web-dev-qa-db-ja.com

コマンドと一緒に管理者としてcmdを実行するには?

これが私のコードです:

try
{
    ProcessStartInfo procStartInfo = new ProcessStartInfo(
                                            "cmd.exe", 
                                            "/c " + command);
    procStartInfo.UseShellExecute = true;
    procStartInfo.CreateNoWindow = true;
    procStartInfo.Verb = "runas";
    procStartInfo.Arguments = "/env /user:" + "Administrator" + " cmd" + command;

    ///command contains the command to be executed in cmd
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = procStartInfo;
    proc.Start();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

残しておきたい

procStartInfo.UseShellExecute = true 
procStartInfo.RedirectStandardInput = false;

process.standardinputを使わずにコマンドを実行することはできますか?引数で渡したコマンドを実行しようとしましたが、実行されません。

8
purvang

@mtijnが言ったように、あなたは多くのことが起こっているので、後でオーバーライドすることもあります。また、物事を正しくエスケープしていることを確認する必要があります。

次のコマンドを昇格して実行するとします。

_dir c:\
_

まず、このコマンドをProcess.Start()で実行した場合、ウィンドウを開いたままにするものがないため、ウィンドウが開いてすぐに閉じます。コマンドを処理して終了します。ウィンドウを開いたままにするには、コマンドを別のコマンドウィンドウでラップし、_/K_スイッチを使用して実行を続けます。

_cmd /K "dir c:\"
_

そのコマンドを昇格して実行するには、もう少しエスケープする必要があることを除いて、あなたと同じように_runas.exe_を使用できます。ヘルプドキュメント(_runas /?_)によると、runasに渡すコマンド内の引用符は、バックスラッシュでエスケープする必要があります。残念ながら、上記のコマンドでこれを行うと、ダブルバックスラッシュが発生し、cmdパーサーが混乱するため、エスケープする必要があります。したがって、上記のコマンドは次のようになります。

_cmd /K \"dir c:\\\"
_

最後に、指定した構文を使用して、すべてをrunasコマンドにまとめ、上記のコマンドをさらに引用符で囲むことができます。

_runas /env /user:Administrator "cmd /K \"dir c:\\\""
_

コマンドプロンプトから上記のコマンドを実行して、期待どおりに機能することを確認します。

これらすべてを考えると、最終的なコードは組み立てが簡単になります。

_        //Assuming that we want to run the following command:
        //dir c:\

        //The command that we want to run
        string subCommand = @"dir";

        //The arguments to the command that we want to run
        string subCommandArgs = @"c:\";

        //I am wrapping everything in a CMD /K command so that I can see the output and so that it stays up after executing
        //Note: arguments in the sub command need to have their backslashes escaped which is taken care of below
        string subCommandFinal = @"cmd /K \""" + subCommand.Replace(@"\", @"\\") + " " + subCommandArgs.Replace(@"\", @"\\") + @"\""";

        //Run the runas command directly
        ProcessStartInfo procStartInfo = new ProcessStartInfo("runas.exe");
        procStartInfo.UseShellExecute = true;
        procStartInfo.CreateNoWindow = true;

        //Create our arguments
        string finalArgs = @"/env /user:Administrator """ + subCommandFinal + @"""";
        procStartInfo.Arguments = finalArgs;

        //command contains the command to be executed in cmd
        using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
        {
            proc.StartInfo = procStartInfo;
            proc.Start();
        }
_
5
Chris Haas

なぜプロセスオブジェクトを引数で初期化し、後でそれらの引数をオーバーライドするのですか?ところで:「command」を「cmd」まで連結する引数を設定する最後のビット。これはあまり意味がなく、失敗する可能性があります(スペースが不足しているように見えます)。

また、現在標準のコマンドラインを使用しているので、代わりに runasツール を使用することを検討することをお勧めします。コマンドラインからrunasを呼び出すこともできます。

また、なぜコマンドラインから「コマンド」を実行しているのですか? Process.Startから直接開始して、その場で提供される管理者権限を使用してみませんか?ここに少しの擬似コードがあります:

Process p = Process.Start(new ProcessStartInfo()
{
    FileName = <your executable>,
    Arguments = <any arguments>,
    UserName = "Administrator",
    Password = <password>,
    UseShellExecute = false,
    WorkingDirectory = <directory of your executable>
});
1
mtijn