Click here to Skip to main content
15,918,108 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This has bugged me for DAYS, but I think I found the cause of the issue.

I am creating a windows service, that can load different projects and execute them. These smaller services can do various tasks. This works very well. However, I started a couple of days ago building a new module that will take measurement of the computers hardware and send that statistics to another server. For the measurement, I am using System.Diagnostic.PerformanceCounter. This does the trick, however (and this is important), it came with the warning that this is only for Windows platform. Now this is fine as I only work with Windows platforms.

So I build the module and started doing some unittest on it, which works great. But when I then started it up in debug with the underlying windows service that will discover it and then load it, I suddenly get:

System.AggregateException: One or more errors occurred. (Could not load file or assembly 'System.Diagnostics.PerformanceCounter, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.)
 ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Diagnostics.PerformanceCounter, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
File name: 'System.Diagnostics.PerformanceCounter, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'


What I have tried:

I found this odd as I could run the module in my unittest without problems. At this point, I thought that the Activator could not load the file for some reason, or not see it, so I added some code so it would load it explicitly. When I run the service again, I now get:

2023-10-30 11:24:10.523 +01:00 [ERR] Exception description has not been implemented. No details available other than stacktrace
System.AggregateException: One or more errors occurred. (Performance Counters are not supported on this platform.)
 ---> System.PlatformNotSupportedException: Performance Counters are not supported on this platform.

All of my projects in this solution are set to net6.0-windows, so I could not understand it. I then tried creating a completely new service to check if I have done something weird and used the performance counter to get a CPU reading:
C#
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
	logger.Information("Service running");
	var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
	Console.WriteLine("CPU: " + cpuCounter.NextValue());
	Console.WriteLine("CPU: " + cpuCounter.NextValue());

	//Other code
}

I expected that the code would fail, but it ran the little service without issues. I then transferred the small code snippet into the real service that loads my failing module. Now, not only the real service builds and runs without issue, but the module also loads without any exception.

So from what I can gather, the System.Diagnogstics.PerformanceCounter does not like being loaded with the Activator. For some reason, the platform information is not transfered over and it breaks. However... if the diagnostics is already loaded from the get go, the Activator is happy, because it uses the already loaded instance. However, this is not exactly how I wanted it to be, so my question now is:

How can I tell the module assembly that actually needs to use the System.Diagnogstics.PerformanceCounter or Activator, that the platform is actually a Windows platform so it will load without issue. And without having the main service preload DLLs, that it might not needed?

For reference, here is my activator loading code:
C#
private KafkaBroker? LoadBrokerFromPath(string brokerFilePath)
{
	Assembly assembly = Assembly.LoadFile(brokerFilePath);
	Type[] types = assembly.GetTypes();
	foreach (Type type in types)
	{
		if (typeof(MyBroker).IsAssignableFrom(type))
		{
			// Create an instance of the type that implements the interface.
			MyBroker? broker = (MyBroker?) Activator.CreateInstance(type);
			
			if (broker != null)
			{
				return broker;
			}
		}
	}
	logger.Error("Failed to load broker from file '{Path}'. 
                  MyBroker was not available", brokerFilePath);
	return null;
}
Posted
Updated 5-Nov-23 0:01am
v3
Comments
Maxim Kartavenkov 30-Oct-23 14:07pm    
What happening if you setup explicitly platform while you building your application? Try x64 or x86 instead of "Any CPU" in the configuration.
Evilfish2000 23-Nov-23 5:32am    
Maxim thank you for your suggestion. I will test this at some point. However, work suddenly took a turn so this project is on hold. Sorry for not informing of this until now.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900