異なるクライアント コンピューター上のローカル ドメイン ネットワークを介して .exe ファイルを実行するサーバー C# アプリケーションを開発しています。私は WMI 経由で実行することを選択しましたが、.exe パスがリモート マシンに対してローカルである場合は正常に動作します。ここの他のスレッドや他のフォーラムを検索すると、WMI が UNC パスをサポートしていないことに気付きました (これが私の問題です)。
以下のメソッドを呼び出して、リモート PC デスクトップに配置された .exe を実行すると、正常に動作します。
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\Documents and Settings\user1\Desktop\My_Setup.exe", @"domain\user", "mypass");
ここで、UNC パスを使用しようとすると、終了コード 2が表示されます。
var execResult = WmiExecuteRemoteProcess("XPSP3", @"\\server\shared\My_Setup.exe", @"domain\user", "mypass");
メソッドは次のWmiExecuteRemoteProcess
ようになります。
public bool WmiExecuteRemoteProcess(string remoteComputerName, string arguments, string pUser, string pPassword)
{
try
{
ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Username = pUser;
connOptions.Password = pPassword;
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
ManagementScope manScope = new ManagementScope(string.Format(@"\\{0}\ROOT\CIMV2", remoteComputerName), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
using (ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions))
{
using (ManagementBaseObject inParams = processClass.GetMethodParameters("Create"))
{
inParams["CommandLine"] = arguments;
using (ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null))
{
return (uint)outParams["returnValue"] == 0;
}
}
}
}
catch (Exception ex)
{
Log.Error(ex.Message);
return false;
}
}
arguments
この状況を考えると、次のようにパラメーターを解析することで、一種の「チート」を決定しました。
var args = "cmd.exe /c \"pushd \"\"\\\\server\\shared\"\" && My_Setup.exe && popd\"";
var execResult = WmiExecuteRemoteProcess("XPSP3",args,@"domain\user", "mypass");
ここでやろうとしているのは、コマンドpushd
でcmd.exe を使用しpopd
、UNC パスを "Z:\shared" のようなネットワーク ドライブ ベースのパスにマップすることです。この方法では、WMI と cmd.exe の両方が UNC パスを処理する必要がありません。
結果: .exe がリモート マシンに対してローカルである場合は、非常にうまく機能しますが、UNC パスを使用すると、cmd.exe プロセスのみが表示されます。内部で終了コード 2 が再度スローされている可能性がありますが、cmd 実行の出力をログ ファイルにリダイレクトしても、それをキャッチできません。
おそらく、この種のメカニックの経験がある人なら、これに光を当てることができるでしょう。このためだけにサービス全体を開発したり、PsExec を使用したりすることは避けたいと思います (これは最後の手段かもしれません)。
情報が不足している場合はお知らせください。どんなコメントでも大歓迎です。
よろしく。
編集:確認しましたが、共有フォルダーまたはファイルへのアクセス許可の問題ではありません。