Re: PerformanceCounterCategory.Delete removes entire registry key

Tech-Archive recommends: Speed Up your PC by fixing your registry



That's good news, thanks.

I worked around this by using a different name for the category and the
service. This is fine for now.

Now I'm hitting another problem. After I Delete the category and re-Create
it, I then add the new counters using code as follows:

// Remove any hanging or previously-created category information
if (PerformanceCounterCategory.Exists( _perfMonCategoryName ))
{
PerformanceCounterCategory.Delete( _perfMonCategoryName );
}

if (_perfMonCategory != null)
{
ApplicationLog.Log( LogType.INFO, 0,
"PerfMon Statistics are being replaced for " +
_perfMonCategoryName);

foreach (PerformanceCounter pc in _perfMonData)
{
pc.Close();
}
PerformanceCounter.CloseSharedResources();

_perfMonData.Clear();
}

// Register the current process with PerfMon as a new category of
counters, with
// one entry in a list of counters per Statistic for the process
CounterCreationDataCollection newCounters = new
CounterCreationDataCollection();

foreach (Statistic st in _statistics)
{
CounterCreationData newCounter = new CounterCreationData(st.PerfMonName,
st.PerfMonName,
PerformanceCounterType.NumberOfItems32 );
newCounters.Add(newCounter);
}

_perfMonCategory = PerformanceCounterCategory.Create(
_perfMonCategoryName,
ColorPaletteHelpString,
newCounters);

// Export the initial values for each counter
foreach (Statistic st in _statistics)
{
PerformanceCounter newData = new PerformanceCounter(
_perfMonCategoryName,
st.Name,
false ); // writable
ApplicationLog.Log( LogType.INFO, 0,
"PerfMon counter:" +
newData.CounterType + " " + newData.CounterHelp);

newData.RawValue = st.iValue;
st.Counter = newData;

_perfMonData.Add( newData );
}
}


In the debugger, the categoryHelp on _perfMonCategory shows up as null
although I am passing in a string ColorPaletteHelpString. In addition, the
Log call to dump newData.CounterType and newData.CounterHelp fails with
exception "Category does not exist", although I can see it in the debugger
after the .Create call just above.

I am beginning to suspect that this area of .Net 1.1 is what is sometimes
referred to as a "bug farm". Is this one also expected to be fixed in .Net
2.0? Are there any other known bugs I need to look out for?

Another comment - it looks to me like the PerformanceCounterCategory class
may use a single named mutex "netfxperf.1.0" to control access to all .Net
custom counters. The SWI team would probably be interested in this, since
these are trivial to squat on and deny access to legitimate users, without
proper security controls.

--
Steve Townsend
Lava Trading


"David Browne" wrote:

>
> "Steve Townsend" <SteveTownsend@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
> news:092F5C32-ACF1-4B93-BDAE-E779F625EF47@xxxxxxxxxxxxxxxx
> >I am attempting to instrument several existing Windows service applications
> > (written in C#) using the PerformanceCounter* classes in .Net FW 1.1 SP1.
> > Each service must dynamically add its required counters based on
> > configuration metadata from SQL Server using the service name as the
> > Category, and to this end I have the following code snippet:
> >
> > /// <summary>
> > /// This method exports the statistics for this process to PerfMon. This
> > must be called
> > /// at the end or process initialization so that all statistics for the
> > process are
> > /// registered.
> > /// If this is called multiple times the existing data structure is
> > replaced by an
> > /// updated version. This allows, if rather clumsily, counters to be
> > added after
> > /// AppManager has completed process initialization.
> > /// </summary>
> > /// <returns></returns>
> > public void ExportStatistics()
> > {
> > lock (this)
> > {
> > // Remove any hanging or previously-created category information
> > if (PerformanceCounterCategory.Exists( _perfMonCategoryName ))
> > {
> > PerformanceCounterCategory.Delete( _perfMonCategoryName );
> > }
> >
> > ... boring details of actual counter setup omitted.
> >
> > The first call to this method works OK - registry keys named "Linkage" and
> > "Performance" are added to
> > HKLM\System\CurrentControlSet\Services\<category-name>, which already
> > exists
> > because that's the service which is going to publish the counters.
> >
> > Now, when a revised list of counters needs to be published, the entire
> > category has to be discarded and recreated, per the following text in
> > MSDN's
> > description of PerformanceCounterCategory.Delete:
> >
> > "Remarks
> > You can delete only custom performance counter categories from the system.
> > You cannot delete a counter from a category. To do so, delete the category
> > and recreate the category with the counters you want to retain."
> >
> > At this point the code snippet above finds .Exists=True and calls .Delete.
> > I walked through this in the debugger and the entire registry key at
> > HKLM\System\CurrentControlSet\Services\<category-name/service-name> is
> > deleted by this method call. This seems like a bug, because it's
> > impossible
> > under this behaviour to instrument a .Net service with revised Performance
> > Counters without requiring a full reinstall. This is since my service
> > (and
> > any other I have ever known) stores its configuration bootstrap data under
> > a
> > "Parameters" subkey of this now-deleted service Registry placeholder.
> >
> > Is there a fix for this available or planned? I am sure there are hacks I
> > could use to get around this (e.g. use a name mapping to put the Category
> > info in a different place in the Registry from the rest of the service
> > configuration), but the current behaviour seems clearly incorrect.
> >
>
> I believe this behavior is changed in .NET 2.0 to delete only the Linkage
> and Performance subkeys when the service key has other information in it
> too.
>
> David
>
>
>
.



Relevant Pages