1

異なるクライアント コンピューター上のローカル ドメイン ネットワークを介して .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 を使用したりすることは避けたいと思います (これは最後の手段かもしれません)。

情報が不足している場合はお知らせください。どんなコメントでも大歓迎です。

よろしく。

編集:確認しましたが、共有フォルダーまたはファイルへのアクセス許可の問題ではありません。

4

1 に答える 1

1

誰かがこの問題またはその他の関連する問題に直面した場合、これが私が解決した方法です。

問題は、WMI が UNC パスを処理できないことではありませんが、Windows のセキュリティ制限により、WMI 操作はネットワーク リソースにアクセスできません。パスをマッピングしても問題ありません。許可されていないだけです。この特定のケースで最終的に得た回避策は、setup.exe をリモート マシンの一時フォルダーにコピーし、以前と同じようにローカル パスにアクセスして WMI を介して最終的に実行することでした。

var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\temp_folder\My_Setup.exe", @"domain\user", "mypass");
于 2016-06-22T11:08:42.267 に答える