コマンドプロンプトコマンドを実行する


605

C#アプリケーション内からコマンドプロンプトコマンドを実行する方法はありますか?もしそうなら、私はどのように次のことをしますか:

copy /b Image1.jpg + Archive.rar Image2.jpg

これは基本的に、JPG画像内にRARファイルを埋め込みます。これをC#で自動的に行う方法があるかどうか疑問に思っていました。


6
stackoverflow.com/questions/181719/…の複製(あなたが望むことをする答えがあります)。
マットハミルトン

stackoverflow.com/a/5367686/492はより良い答えを持っています
CADは

回答:


918

これは、C#からシェルコマンドを実行するために必要なすべてです。

string strCmdText;
strCmdText= "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
System.Diagnostics.Process.Start("CMD.exe",strCmdText);

編集:

これは、cmdウィンドウを非表示にすることです。

System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
process.StartInfo = startInfo;
process.Start();

編集:2

重要なのは、/Cそれ以外では引数が機能しないことです。どのようにスコット・ファーガソンは言った:それは「文字列で指定されたコマンドを実行してから終了します。」


166
/ C文字列で指定されたコマンドを実行して終了します
スコットファーガソン

16
コマンドを実行して終了するように指示するだけです(ウィンドウを閉じるためのユーザー入力を待機しないでください)
RameshVel

3
もう1つ質問をお願いします。この間、コマンドプロンプトを非表示にする方法はありますか?
ユーザー

9
これが恐ろしい考えだと私が思うのは私一人だけではありません。はい、これでうまくいきますが、それは完全かつ完全に間違っています。単純なIO操作を実行するためにCMDプロセスを生成することは、たとえそれが機能しても、間違っています。System.IO名前空間に関するドキュメントを読みます。不要なプロセスを生成せずに必要な処理を実行するのに十分な機能があります。
インスタンスハンター

56
参考:process.WaitForExit()を使用してプロセスが完了するのを待ってから続行し、process.ExitCodeを使用してプロセスの終了コードを取得します。
shindigo 2014

122

@RameshVelソリューションを試しましたが、コンソールアプリケーションで引数を渡すことができませんでした。誰かが同じ問題をここで経験する場合、ここでの解決策です:

using System.Diagnostics;

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();

cmd.StandardInput.WriteLine("echo Oscar");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());

2
まあ、私のマシンには管理者またはウイルス対策の制限があるとは思わなかったが、上記のコードは機能する!オグラスに感謝
ピートコザック

6
この行:cmd.StartInfo.CreateNoWindow = true; 私の日を救った。
Ganesh Kamath-'Code Frenzy'

複数のコマンドを1回で実行する方法はありますかcmd.StandardInput.WriteLine(@"cd C:\Test; pwd")
ザック・スミス

36
var proc1 = new ProcessStartInfo();
string anyCommand; 
proc1.UseShellExecute = true;

proc1.WorkingDirectory = @"C:\Windows\System32";

proc1.FileName = @"C:\Windows\System32\cmd.exe";
proc1.Verb = "runas";
proc1.Arguments = "/c "+anyCommand;
proc1.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(proc1);

2
@C#の記号は何ですか?
Pacerier、2015

6
@Pacerier文字列内で通常エスケープする必要があるすべての文字(この場合は\)をエスケープするようコンパイラーに指示します。したがって、\がない場合、コードは次のようになりますproc1.FileName = "C:\\Windows\\System32\\cmd.exe";
James Ko

1
proc1.Verb = "runas";このプロセスが昇格された特権で実行されることに注意してください...これは常に意図されているわけではありません。
Dinei

1
終了後、このcmdウィンドウが閉じないようにするにはどうすればよいですか?
Hrvoje T 2018

1
「&&」で結合された「cd path」を行の他のコマンドで呼び出すと、最初に実行された場合でも、常に最後に実行されることがわかりました。your: 'proc1.WorkingDirectory = @ "C:\ Windows \ System32";' とても役に立ちました!ありがとう!
Nozim Turakulov

11

上記の回答のいずれも何らかの理由で役に立たなかったため、敷居の下でエラーを一掃し、コマンドのトラブルシューティングを困難にしているようです。だから私はこのようなもので行くことになりました、多分それは他の誰かを助けるでしょう:

var proc = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = @"C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\tf.exe",
        Arguments = "checkout AndroidManifest.xml",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        WorkingDirectory = @"C:\MyAndroidApp\"
    }
};

proc.Start();

これをスタンドアロンのコンソールアプリケーションにコンパイルする場合、それを機能させるために他にどのようなコードを追加する必要がありますか?(私はこのすべてのプログラミングに初心者ですが、スクリプトをいくつか作成しただけです)。私はcsc.exeを使用しています。
script'n'code

@copyitright名前空間とクラス。新しいプロジェクトを作成するだけの場合は、それらが生成されます。
coinbird 2017

ああ。気にしないで。cmd.exeアプリを使用する場合、コマンドを引数として渡すことができます。
ザック・スミス

後世のために:私はプロセスが実行さecho Hello World!れ、ポップアップするcmdウィンドウにコマンド出力を表示することを望みました。だから私は試してみました:Filename = @"echo"Arguments = "Hello World!"UseShellExecute = falseRedirectStandardOuput = falseCreateNoWindow = false。これにより、親アプリケーションのコマンドウィンドウに「Hello World!」が表示されました。(stdoutが子プロセスにリダイレクトされなかったため、これは理にかなっています)。
Minh Tran

10

技術的にこれは提起された質問に直接答えるものではありませんが、元の投稿者が何をしたかったか、つまりファイルを結合する方法についての質問には答えます。どちらかと言えば、これは初心者がInstance HunterとKonstantinが話していることを理解するのに役立つ投稿です。

これは、ファイル(この場合はjpgとzip)を結合するために使用する方法です。zipファイルのコンテンツで満たされるバッファーを(1回の大きな読み取り操作ではなく小さなチャンクで)作成し、その後、zipファイルの最後までjpgファイルの後ろにバッファーが書き込まれることに注意してください。到達:

private void CombineFiles(string jpgFileName, string zipFileName)
{
    using (Stream original = new FileStream(jpgFileName, FileMode.Append))
    {
        using (Stream extra = new FileStream(zipFileName, FileMode.Open, FileAccess.Read))
        {
            var buffer = new byte[32 * 1024];

            int blockSize;
            while ((blockSize = extra.Read(buffer, 0, buffer.Length)) > 0)
            {
                original.Write(buffer, 0, blockSize);
            }
        }
    }
}

9

コマンドウィンドウを開いたままにする場合、またはwinform / wpfで使用する場合は、次のように使用します。

    string strCmdText;
//For Testing
    strCmdText= "/K ipconfig";

 System.Diagnostics.Process.Start("CMD.exe",strCmdText);

/ K

コマンドウィンドウを開いたままにします


いいね。コマンドとそのパラメーターに関するこのドキュメントを見つけましたcmd
ピウス

8

はい、あります(Matt Hamiltonのコメントのリンクを参照)。ただし、.NETのIOクラスを使用する方が簡単で優れています。File.ReadAllBytesを使用してファイルを読み取り、次にFile.WriteAllBytesを使用して「埋め込み」バージョンを書き込むことができます。


11
特にファイルが十分に大きい場合は、ファイルを別のファイルに追加するためだけにファイル全体をメモリにロードすることは、あまり効率的ではありません。
Konstantin Spirin

7
答えの精神を見てみてください。重要なのは、.NETには、OSシェルを呼び出さなくてもこれを実行するのに十分なIOクラスと関数があることです。私が述べた特定の機能は最高ではないかもしれませんが、それらは単に最も単純でした。これを行うためにシェルを呼び出すことはまったく意味がありません。
インスタンスハンター

7

これは、CliWrapを1行で使用して実行できます。

var stdout = new Cli("cmd")
         .Execute("copy /b Image1.jpg + Archive.rar Image2.jpg")
         .StandardOutput;

私はこれに賛成しました...しかし、リポジトリは今欠けているようです:Unable to find package 'CliWrap' at source
Zach Smith

1
@ZachSmithはあなたが何を意味するのかわからない、nuget.org / packages / CliWrap正常に動作するようです。元のリンクも。
Tyrrrz、2018年

Ah.sorry ..何らかの理由でvpn経由でnugetリポジトリに接続できなかったため、このパッケージをインストールできませんでした。nugetは今でもほとんど謎です。間違って設定したに違いありません
Zach Smith


5

これは少しシンプルでコードの少ないバージョンです。コンソールウィンドウも非表示になります。

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
process.Start();

5

コマンドを非同期モードで実行したい場合-結果を出力します。あなたはあなたにこのクラスをすることができます:

    public static class ExecuteCmd
{
    /// <summary>
    /// Executes a shell command synchronously.
    /// </summary>
    /// <param name="command">string command</param>
    /// <returns>string, as output of the command.</returns>
    public static void ExecuteCommandSync(object command)
    {
        try
        {
            // create the ProcessStartInfo using "cmd" as the program to be run, and "/c " as the parameters.
            // Incidentally, /c tells cmd that we want it to execute the command that follows, and then exit.
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
            // The following commands are needed to redirect the standard output. 
            //This means that it will be redirected to the Process.StandardOutput StreamReader.
            procStartInfo.RedirectStandardOutput =  true;
            procStartInfo.UseShellExecute = false;
            // Do not create the black window.
            procStartInfo.CreateNoWindow = true;
            // Now we create a process, assign its ProcessStartInfo and start it
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();

            // Get the output into a string
            string result = proc.StandardOutput.ReadToEnd();

            // Display the command output.
            Console.WriteLine(result);
        }
        catch (Exception objException)
        {
            // Log the exception
            Console.WriteLine("ExecuteCommandSync failed" + objException.Message);
        }
    }

    /// <summary>
    /// Execute the command Asynchronously.
    /// </summary>
    /// <param name="command">string command.</param>
    public static void ExecuteCommandAsync(string command)
    {
        try
        {
            //Asynchronously start the Thread to process the Execute command request.
            Thread objThread = new Thread(new ParameterizedThreadStart(ExecuteCommandSync));
            //Make the thread as background thread.
            objThread.IsBackground = true;
            //Set the Priority of the thread.
            objThread.Priority = ThreadPriority.AboveNormal;
            //Start the thread.
            objThread.Start(command);
        }
        catch (ThreadStartException )
        {
            // Log the exception
        }
        catch (ThreadAbortException )
        {
            // Log the exception
        }
        catch (Exception )
        {
            // Log the exception
        }
    }

}

2

これは、(他の回答で述べたように)次の方法を使用して実現できます。

strCmdText = "'/C some command";
Process.Start("CMD.exe", strCmdText);

上記の方法を試したところ、上記の回答の一部の構文を使用してもカスタムコマンドが機能しないことがわかりました。

より複雑なコマンドを機能させるには、引用符で囲む必要があることがわかりました。

string strCmdText;
strCmdText = "'/C cd " + path + " && composer update && composer install -o'";
Process.Start("CMD.exe", strCmdText);

1

あなたは単に.batフォーマット拡張でコードを書くことができます、バッチファイルのコード:

c:/ copy /b Image1.jpg + Archive.rar Image2.jpg

このc#コードを使用してください:

Process.Start("file_name.bat")


あなたはCMDを非表示にしたい場合は、単純なVisual Basicのスクリプトコードを使用することができます実行中に.vbsフォーマットの拡張子、コード:CreateObject("Wscript.Shell").Run "filename.bat",0,True
XMMR12
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.