2010-03-26 213 views
1

我無法使用模擬從MVC網站中刪除PerformanceCounterCategory。我有一個靜態類,當應用程序啓動時,它會檢查PerformanceCounterCategory是否存在,以及它是否包含正確的計數器。如果不是,則刪除該類別並使用所需的計數器再次創建該類別。模仿 - 訪問被拒絕

它在內置的Web服務器卡西尼運行時工作正常,但是當我試圖通過IIS7(Vista)的運行它,我得到以下錯誤:

Access is denied
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details:
System.ComponentModel.Win32Exception: Access is denied

我使用的代碼:

var username = "user"; 
var password = "password"; 
var domain = "tempuri.org"; 

WindowsImpersonationContext impersonationContext; 

// if impersonation fails - return 
if (!ImpersonateValidUser(username, password, domain, out impersonationContext)) 
{ 
    throw new AuthenticationException("Impersonation failed"); 
} 

PerformanceCounterCategory.Delete(PerfCategory); 
UndoImpersonation(impersonationContext); 

從MS文章模擬代碼...

private static bool ImpersonateValidUser(string username, string password, 
    string domain, out WindowsImpersonationContext impersonationContext) 
{ 
    const int LOGON32_LOGON_INTERACTIVE = 2; 
    const int LOGON32_PROVIDER_DEFAULT = 0; 
    WindowsIdentity tempWindowsIdentity; 
    var token = IntPtr.Zero; 
    var tokenDuplicate = IntPtr.Zero; 

    if (RevertToSelf()) 
    { 
     if (LogonUserA(username, domain, password, 
      LOGON32_LOGON_INTERACTIVE, 
      LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
     { 
      if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
      { 
       tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); 
       impersonationContext = tempWindowsIdentity.Impersonate(); 

       if (impersonationContext != null) 
       { 
        CloseHandle(token); 
        CloseHandle(tokenDuplicate); 
        return true; 
       } 
      } 
     } 
    } 

    if (token != IntPtr.Zero) 
     CloseHandle(token); 
    if (tokenDuplicate != IntPtr.Zero) 
     CloseHandle(tokenDuplicate); 

    impersonationContext = null; 
    return false; 
} 



[DllImport("advapi32.dll")] 
public static extern int LogonUserA(String lpszUserName, String lpszDomain, 
    String lpszPassword, int dwLogonType, int dwLogonProvider, 
    ref IntPtr phToken); 

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, 
    ref IntPtr hNewToken); 

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern bool RevertToSelf(); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
public static extern bool CloseHandle(IntPtr handle); 

該錯誤是當加工塑料拋出ng會嘗試執行PerformanceCounterCategory.Delete命令。

更新
在回答大衛的回答我嘗試了以下內容:

  1. 創建了一個名爲PerfMonUser
  2. 將此用戶添加到「性能監視器用戶」的新本地用戶組

修改了現在讀取的代碼:

var username = "PerfMonUser"; 
var password = "password"; 
var domain = Environment.MachineName; 

WindowsImpersonationContext impersonationContext; 

// if impersonation fails - return 
if (!ImpersonateValidUser(username, password, domain, out impersonationContext)) 
{ 
    throw new AuthenticationException("Impersonation failed"); 
} 

PerformanceCounterCategory.Delete(PerfCategory); 
UndoImpersonation(impersonationContext); 

...但我仍然得到錯誤:

Exception Details: System.ComponentModel.Win32Exception: Access is denied

...就行了:

PerformanceCounterCategory.Delete(PerfCategory); 

回答

2

這是因爲PerformanceCounterCategory.Delete需要你有兩種管理員權限或者成爲性能監視器用戶組的成員。詳情請參閱MSDN

默認情況下,Cassini在NT AUTHORITY \ SYSTEM用戶帳戶下運行,顯然是Admin。但IIS在有限的用戶帳戶下運行,因此它無法訪問PerformanceCounter調用。您需要讓您的「用戶」用戶成爲Performance Monitor Users或Administrator的成員。

+0

你說過你試圖將用戶添加爲性能監視器組的成員。您是否嘗試將該用戶添加爲管理員?這應該是你的下一步。如果這有效,那麼你知道模擬工作正常,你只需要編輯權限。 – sngregory 2012-02-18 08:41:43