4

(編集)プロットが厚くなります:同じコード(なりすましの必要はありません!)はWindows 7クライアントからは正常に実行されますが、Windows 2008 R2クライアントからは実行されません!これが問題のコードです。(元のメッセージは以下のコードに従います。)

var entry = new DirectoryEntry("IIS://" + tbHost.Text + "/W3SVC", tbUsername.Text, tbPassword.Password);
foreach (DirectoryEntry site in entry.Children)
{
    Console.Write("Site {0}\n", site.Name);
    foreach (PropertyValueCollection prop in site.Properties)
        Console.Write("{0}={1}\n", prop.PropertyName, prop.Value);
}

ここで、IISプロバイダーの場合、DirectoryEntryオブジェクトの作成時にクレデンシャルを渡すことはできないことを読みました。なりすましをする必要があります。そのため、次のコードを試しましたが、以前にコンストラクターのユーザー名とパスワードを渡そうとしたときと同じように、プロパティを読み取ろうとすると、「不明なエラー(0x80005000)」というテキストのCOMExceptionが発生しますDirectoryEntry。要約は次のとおりです。

  • LogonUser()成功すれば、クレデンシャルはOKです。LOGON32_LOGON_NEW_CREDENTIALSの代わりに使用する必要があることに気付く前に、少し頭を叩いていたLOGON32_LOGON_INTERACTIVE
  • リモートマシンは同じドメインにありません。実際には、ドメインにはまったく含まれていません。実際、私はその名前をクライアントのhostsファイルに入れて、名前でアクセスできるようにしました。
  • ターゲットマシンでMetabaseExplorerを実行すると、読み取りたいキーが存在することがわかります。(投稿の最後にある写真を参照してください。)

const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int LogonUser(String lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

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

[DllImport("kernel32.dll")]
extern static int GetLastError();

(...)

IntPtr myToken = IntPtr.Zero;
if (LogonUser(tbUsername.Text, tbHost.Text, tbPassword.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref myToken) == 0)
{
    int causingError = GetLastError();
    throw new System.ComponentModel.Win32Exception(causingError);
}

WindowsImpersonationContext myMission = WindowsIdentity.Impersonate(myToken);

string mbUri = "IIS://" + tbHost.Text + "/MimeMap";
DirectoryEntry myDirEntry = new DirectoryEntry(mbUri);
Console.Write("{0}\n", myDirEntry.Properties["KeyType"]);

myDirEntry.Close();
myMission.Undo();
if (myToken != IntPtr.Zero)
    CloseHandle(myToken);

ここに画像の説明を入力してください

4

2 に答える 2

5

とった。サーバー管理→役割→Webサーバー(IIS)に移動し、サービス管理ツール→IIS6管理の互換性→IIS6メタベースの互換性を有効にするだけで済みました。下の写真を参照してください。

これはクライアントマシンにあるため、IISから他に何もインストールする必要はありません。

サーバー以外のWindows(XP、Vista、7)ではどのように機能するのでしょうか。

ここに画像の説明を入力してください

于 2011-04-14T18:15:57.470 に答える
0

管理者としてPowershellを開き、以下を使用してIIS6管理の互換性を有効にすることもできます。

Import-Module Servermanager
Add-WindowsFeature Web-Mgmt-Compat -IncludeAllSubFeature
Get-WindowsFeature #Show list of all installed features
于 2013-10-22T18:21:09.843 に答える