我无法使用模拟从MVC网站删除PerformanceCounterCategory。我有一个静态类,当应用程序启动时,它会检查PerformanceCounterCategory是否存在,以及它是否包含正确的计数器。如果没有,它将删除该类别并使用所需的计数器再次创建它。
在内置的Web服务器Cassini下运行时工作正常,但是当我尝试通过IIS7(Vista)运行时,我收到以下错误:
访问被拒绝 说明:
在执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中的起源位置的更多信息 例外细节:
System.ComponentModel.Win32Exception:访问被拒绝
我对代码的使用:
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);
处理尝试执行PerformanceCounterCategory.Delete命令时抛出错误。
更新
为了回应大卫的回答,我尝试了以下内容:
修改了代码,现在读取:
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);
...但我仍然收到错误:
异常详细信息:System.ComponentModel.Win32Exception:拒绝访问
......在线:
PerformanceCounterCategory.Delete(PerfCategory);
答案 0 :(得分:2)
这是因为PerformanceCounterCategory.Delete要求您具有管理员权限或者是Performance Monitor Users组的成员。有关详细信息,请参阅MSDN。
默认情况下,Cassini在NT AUTHORITY \ SYSTEM用户帐户下运行,显然是Admin。然而,IIS在有限的用户帐户下运行,因此它无法访问PerformanceCounter调用。您需要使“用户”用户成为性能监视器用户或管理员的成员。