1

偽装を使用して MVC Web サイトから 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 コマンドを実行しようとすると、エラーがスローされます。

更新
デイビッドの答えに応えて、私は次のことを試しました:

  1. PerfMonUser という名前の新しいローカル ユーザーを作成しました
  2. このユーザーを「Performance Monitor Users」グループに追加しました

コードを変更して、次のようになりました。

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);
4

1 に答える 1