Technical details:
If you attempt to load a performance counter with this code (existing Performance Object, non-existant counter):
PerformanceCounter newCounter = new PerformanceCounter("RealCategory","BogusName","Foo",true);You'll get the very helpful error message: "Counter 'BogusName' does not exist in the specified Category."
If you use this code (non-existant Performance Object):
PerformanceCounter newCounter = new PerformanceCounter("BogusCategory","BogusName","Foo",true);You'll get a slightly less helpful error message: "Category does not exist." . . . hmm . . would have been nice to know which category.
Now if you use that same call, but flip the readonly flag to false
PerformanceCounter newCounter = new PerformanceCounter("BogusCategory","BogusName","Foo",false);You get this very unhelpful message: "The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly."
The trick at this point is figuring out who's trying to load a counter, and which one they're trying to load. The following code will locate a PerformanceCounterInstaller within an assembly, given a filename. Easy enough to list all the DLLs in a given space with DIR /S /B *.DLL, then run InstallUtil on the ones that turn up positive.
System.Reflection.Assembly assy = System.Reflection.Assembly.LoadFile(fileName);
Type[] publicTypes = assy.GetExportedTypes();
foreach (Type t in publicTypes)
{
if (t.BaseType.Name == "Installer")
{
Installer o = (Installer)t.Assembly.CreateInstance(t.FullName);
foreach(Installer i in o.Installers)
{
if (i.GetType().Name == "PerformanceCounterInstaller")
{
MessageBox.Show("Performance Counter Installer Found in Assembly " + fileName);
}
}
}
}

2 comments:
But I am not getting how to solve this problem........
As I mentioned in the post, this problem occurs because of an attempt (in code) to create a performance counter object that is not properly registered in Windows.
The solutions are to: 1) Register the counters using InstallUtil, or 2) Eliminate the code that uses them (if the install source of counters is not available).
If you didn't write the code, you will have to blindly try to find the counters in question in their DLL. If you can read source code, you can use .Net Reflector to disassemble whatever module is throwing the error (read your stack trace) to find what specific Perfmon object it's attempting to create.
Odds are high that the counters in question are part of whatever you're trying to run that's having this problem. You can always try running InstallUtil on every DLL you've installed recently. If they were smart, whoever developed the system might have named the DLL containing the install source something with Performance or PerfMon or Counters in the name.
Post a Comment