运行命令提示符命令


604

有什么方法可以在C#应用程序中运行命令提示符命令吗?如果是这样,我将如何执行以下操作:

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

这基本上是将RAR文件嵌入JPG图像中。我只是想知道在C#中是否有一种自动执行此操作的方法。


6
stackoverflow.com/questions/181719/…重复(那里有一个答案可以满足您的要求)。
Matt Hamilton 2009年

Answers:


916

这就是从C#运行shell命令所要做的全部

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否则将不起作用。斯科特·弗格森(Scott Ferguson)怎么说:“执行字符串指定的命令,然后终止。”


166
/ C执行由字符串指定的命令,然后终止
Scott Ferguson

16
它只是告诉cmd运行并终止(不要等待任何用户输入来关闭窗口)
RameshVel

3
谢谢,还有一个问题。有没有办法在此期间隐藏命令提示符?
用户

9
我看不出我是唯一一个认为这是一个可怕想法的人。是的,这是可行的,但这是完全错误的。生成CMD进程以执行简单的IO操作是错误的,即使它可行。通读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
好吧,我没有机会想到我的计算机上存在一些管理员或防病毒限制,但是..以上代码有效!感谢Ogglas
Pete Kozak

6
这行:cmd.StartInfo.CreateNoWindow = true; 拯救了我的一天。
Ganesh Kamath-'Code Frenzy

是否有一个执行多个命令的方式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

6
@Pacerier它告诉编译器转义通常在字符串中必须转义的所有字符,在这种情况下为\。因此,如果没有\,您的代码将如下所示proc1.FileName = "C:\\Windows\\System32\\cmd.exe";
James Ko

1
应该注意的是,proc1.Verb = "runas";使该过程以提升的特权运行...这并非总是如此。
Dinei

1
如何使此cmd窗口在完成后没有关闭?
Hrvoje T

1
我发现,调用“ cd路径”(由“ &&”与其他命令合并)总是执行到最后,即使它先执行也是如此。您的:“ 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 btw。
script'n'code

@copyitright命名空间和类。如果您只是创建一个新项目,则将为您生成它们。
coinbird

啊。没关系。如果您使用该cmd.exe应用程序,则可以将命令作为参数传递。
扎克·史密斯

为了后代:我希望该进程运行echo Hello World!并在弹出的cmd窗口中显示命令输出。所以,我想:Filename = @"echo"Arguments = "Hello World!"UseShellExecute = falseRedirectStandardOuput = falseCreateNoWindow = false。这使父应用程序的cmd窗口显示“ Hello World!”。(这很有意义,因为stdout没有重定向到子进程)。
Minh Tran

10

尽管从技术上讲,这并不能直接回答提出的问题,但确实可以回答如何完成原始海报想要做的事情:合并文件。如果有的话,这是一篇帮助新手了解Instance Hunter和Konstantin在说什么的文章。

这是我用来组合文件的方法(在本例中为jpg和zip)。请注意,我创建了一个缓冲区,该缓冲区被zip文件的内容填充(以小块而不是一个大读取操作),然后该缓冲区被写入jpg文件的背面,直到zip文件的末尾为到达:

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

如果要保持cmd窗口打开或要在winform / wpf中使用它,请像这样使用

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

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

/千

将保持cmd窗口打开


真好 找到了有关命令及其参数的文档cmd
pius

8

是的,有(请参阅Matt Hamilton评论中的链接),但是使用.NET的IO类会更容易,更好。您可以使用File.ReadAllBytes读取文件,然后使用File.WriteAllBytes写入“嵌入式”版本。


11
将整个文件加载到内存中只是为了将一个文件追加到另一个文件并不是很有效,特别是在文件足够大的情况下。
康斯坦丁·斯皮林

7
试着看答案的精神。关键是.NET具有足够多的IO类和函数来执行此操作,而不必调用OS Shell。我提到的特定功能可能不是最好的,但仅仅是最简单的。调用shell来执行此操作根本没有任何意义。
实例猎人

7

您可以在一行中使用CliWrap进行此操作:

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

我对此表示赞同...但是回购协议现在似乎丢失了:Unable to find package 'CliWrap' at source
扎克·史密斯

1
@ZachSmith不确定您的意思,nuget.org / packages / CliWrap似乎工作正常。原始链接也是如此。
Tyrrrz

抱歉,由于某种原因,当我无法通过vpn连接到我的nuget存储库时,无法安装此软件包。nuget对我来说仍然仍然基本上是个谜。必须设置错误
扎克·史密斯


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,则可以使用.vbs格式扩展名中的简单可视基本脚本代码,该代码为:CreateObject("Wscript.Shell").Run "filename.bat",0,True
XMMR12 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.