11

WMI を使用して実行し、ネットワーク共有にアクセスする必要がある C# exe があります。ただし、共有にアクセスすると、UnauthorizedAccessException が発生します。exeを直接実行すると、共有にアクセスできます。どちらの場合も同じユーザー アカウントを使用しています。

私のアプリケーションには、ローカル PC で実行される GUI クライアントと、リモート PC で実行されるバックエンド プロセスの 2 つの部分があります。クライアントがバックエンドに接続する必要がある場合、最初に WMI を使用してリモート プロセスを起動します (以下にコードを再現)。リモート プロセスは、Directory.GetDirectories() を使用してネットワーク共有にアクセスし、クライアントに報告するなど、多くのことを行います。

クライアントが WMI を使用してリモート プロセスを自動的に起動すると、ネットワーク共有にアクセスできなくなります。ただし、リモート デスクトップを使用してリモート マシンに接続し、バックエンド プロセスを手動で起動すると、ネットワーク共有へのアクセスは成功します。

WMI 呼び出しで指定されたユーザーと、リモート デスクトップ セッションにログインしているユーザーは同じなので、権限は同じである必要がありますね。

Directory.Exists()の MSDN エントリには、「Exists メソッドはネットワーク認証を実行しません。事前認証なしで既存のネットワーク共有を照会すると、Exists メソッドは false を返します。」と記載されています。これが関係していると思いますか?ユーザーが WMI セッションで正しく認証されるようにするにはどうすればよいですか?

ConnectionOptions opts = new ConnectionOptions();

opts.Username = username;
opts.Password = password;

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost));

ManagementScope scope = new ManagementScope(path, opts);

scope.Connect();

ObjectGetOptions getOpts = new ObjectGetOptions();
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts))
{
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create");
    inParams["CommandLine"] = commandLine;
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null);
}
4

4 に答える 4

2

WMI はリモート プロセスの実行時に偽装を使用するだけで、ネットワーク アクセスは許可されません。マネージ コードの外に出ても問題ない場合は、必要な資格情報を使用して開始されたリモート プロセス WMI に UNC パスをマップするだけです。これで、必要なネットワーク アクセスが得られます。netapi32.dll の NetUseAdd と NetUseDel を使用して、UNC パスをマップします。API の使用の詳細については、http://pinvoke.net/を参照してください。

于 2010-10-15T16:35:07.980 に答える
2

上記の Isalamon によって提案されたリンクをたどった (感謝) 私は Jestro のアドバイスに従い、代わりにpsexec.exe ( http://technet.microsoft.com/en-us/sysinternals/bb897553.aspxからダウンロードできます) を使用して書き直しました。 WMI。このようにするのは少し面倒に感じますが、うまくいくようです。

同様の問題が発生しているすべての人のための新しいコード:

Process proc = new Process();
proc.StartInfo.FileName = "PsExec.exe";
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}",
                                         remoteHost,
                                         domain,
                                         username,
                                         password,
                                         commandLine);
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
于 2010-03-16T09:38:25.627 に答える
1

素晴らしいプログラムである PSEXEC を使用して並べ替えたことは知っていますが、WMI に戻りたい場合は、ConnectionOptions で次のことを有効にしてみましたか。

  • フラグ EnablePrivileges
  • 偽装を ImpersonationLevel.Impersonate に設定する

次のことを行います。

接続操作のためにユーザー特権を有効にする必要があるかどうかを示す値を取得または設定します。このプロパティは、実行する操作で特定のユーザー権限を有効にする必要がある場合 (マシンの再起動など) にのみ使用してください。

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx


この接続での操作に使用される COM 偽装レベルを取得または設定します。

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx

プログラムが正しい資格情報を持っていることを実際に許可し、ネットワーク共有にアクセスするようにWMIに指示する必要があると思います

于 2012-05-23T13:58:06.803 に答える
0

認証を行うための net use (ドライブ文字を使用する必要はありません) を含むリモート マシンのバッチ ファイルにすべてのコマンドを書き込むことができます。そのようにうまく動作します。私はまだ代替案に取り組んでいます。

于 2011-05-10T16:12:49.147 に答える