2

我有一个 .NET 3.5 Web 应用程序,为此我实现了一个名为 CalculationsCounterManager 的类(代码如下)。此类具有一些共享/静态成员,它们管理两个自定义性能计数器的创建和递增,这些计数器监视对 SQL Server 数据库的数据调用。如果计数器不存在,则执行这些数据调用会驱动计数器的创建。当然,通过通过 nUnit GUI 为此类执行的单元测试,一切正常。计数器被创建并递增。

但是,当通过 ASPNET 辅助进程执行相同的代码时,会出现以下错误消息:“请求的注册表访问是不允许的。”。当执行读取以检查计数器类别是否已存在时,此错误发生在 CalculationsCounterManager 类的第 44 行。

有谁知道一种方法可以为工作进程帐户提供足够的特权,以便允许它在生产环境中创建计数器,而不会使服务器面临安全问题?

Namespace eA.Analytics.DataLayer.PerformanceMetrics
    ''' <summary>
    ''' Manages performance counters for the calculatioins data layer assembly
    ''' </summary>
    ''' <remarks>GAJ 09/10/08 - Initial coding and testing</remarks>
    Public Class CalculationCounterManager

        Private Shared _AvgRetrieval As PerformanceCounter
        Private Shared _TotalRequests As PerformanceCounter
        Private Shared _ManagerInitialized As Boolean
        Private Shared _SW As Stopwatch

        ''' <summary>
        ''' Creates/recreates the perf. counters if they don't exist
        ''' </summary>
        ''' <param name="recreate"></param>
        ''' <remarks></remarks>
        Public Shared Sub SetupCalculationsCounters(ByVal recreate As Boolean)

            If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = False Or recreate = True Then

                Dim AvgCalcsProductRetrieval As New CounterCreationData(CounterSettings.AvgProductRetrievalTimeCounterName, _
                                                                        CounterSettings.AvgProductRetrievalTimeCounterHelp, _
                                                                        CounterSettings.AvgProductRetrievalTimeCounterType)

                Dim TotalCalcsProductRetrievalRequests As New CounterCreationData(CounterSettings.TotalRequestsCounterName, _
                                                                                  CounterSettings.AvgProductRetrievalTimeCounterHelp, _
                                                                                  CounterSettings.TotalRequestsCounterType)

                Dim CounterData As New CounterCreationDataCollection()

                ' Add counters to the collection.
                CounterData.Add(AvgCalcsProductRetrieval)
                CounterData.Add(TotalCalcsProductRetrievalRequests)

                If recreate = True Then
                    If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = True Then
                        PerformanceCounterCategory.Delete(CollectionSettings.CalculationMetricsCollectionName)
                    End If
                End If

                If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = False Then
                    PerformanceCounterCategory.Create(CollectionSettings.CalculationMetricsCollectionName, CollectionSettings.CalculationMetricsDescription, _
                                                  PerformanceCounterCategoryType.SingleInstance, CounterData)
                End If

            End If

            _AvgRetrieval = New PerformanceCounter(CollectionSettings.CalculationMetricsCollectionName, CounterSettings.AvgProductRetrievalTimeCounterName, False)
            _TotalRequests = New PerformanceCounter(CollectionSettings.CalculationMetricsCollectionName, CounterSettings.TotalRequestsCounterName, False)
            _ManagerInitialized = True

        End Sub

        Public Shared ReadOnly Property CategoryName() As String
            Get
                Return CollectionSettings.CalculationMetricsCollectionName
            End Get
        End Property

        ''' <summary>
        ''' Determines if the performance counters have been initialized
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared ReadOnly Property ManagerInitializaed() As Boolean
            Get
                Return _ManagerInitialized
            End Get
        End Property

        Public Shared ReadOnly Property AvgRetrieval() As PerformanceCounter
            Get
                Return _AvgRetrieval
            End Get
        End Property

        Public Shared ReadOnly Property TotalRequests() As PerformanceCounter
            Get
                Return _TotalRequests
            End Get
        End Property

        ''' <summary>
        ''' Initializes the Average Retrieval Time counter by starting a stopwatch
        ''' </summary>
        ''' <remarks></remarks>
        Public Shared Sub BeginIncrementAvgRetrieval()

            If _SW Is Nothing Then
                _SW = New Stopwatch
            End If

            _SW.Start()

        End Sub

        ''' <summary>
        ''' Increments the Average Retrieval Time counter by stopping the stopwatch and changing the
        ''' raw value of the perf counter.
        ''' </summary>
        ''' <remarks></remarks>
        Public Shared Sub EndIncrementAvgRetrieval(ByVal resetStopwatch As Boolean, ByVal outputToTrace As Boolean)
            _SW.Stop()
            _AvgRetrieval.RawValue = CLng(_SW.ElapsedMilliseconds)
            If outPutToTrace = True Then
                Trace.WriteLine(_AvgRetrieval.NextValue.ToString)
            End If
            If resetStopwatch = True Then
                _SW.Reset()
            End If
        End Sub

        ''' <summary>
        ''' Increments the total requests counter
        ''' </summary>
        ''' <remarks></remarks>
        Public Shared Sub IncrementTotalRequests()
            _TotalRequests.IncrementBy(1)
        End Sub

        Public Shared Sub DeleteAll()
            If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = True Then
                PerformanceCounterCategory.Delete(CollectionSettings.CalculationMetricsCollectionName)
            End If
        End Sub

    End Class
End Namespace
4

1 回答 1

3

是的,这是不可能的。如果不对生产环境中的潜在安全/DOS 问题开放服务器,就无法向工作进程添加权限。安装程序(如 MSI)通常以提升的权限运行,并安装/卸载性能计数器类别和计数器以及其他锁定对象。

例如,Windows Installer XML (WiX) 支持性能计数器...

于 2008-09-11T15:03:51.093 回答