运行命令提示符命令

766

有没有办法从C#应用程序内部运行命令提示符命令?如果可以,我该如何执行以下操作:

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

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


7
重复的问题已经在https://dev59.com/LnVC5IYBdhLWcg3wykej上有答案可以实现你想要的功能。 - Matt Hamilton
1
https://dev59.com/om435IYBdhLWcg3whQc5#5367686 有一个更好的答案。 - CAD bloke
17个回答

6

这里是一个简单且代码量较少的版本。它还可以隐藏控制台窗口 -

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();

3

我有以下方法,用于从C#运行命令提示符命令:

在第一个参数中传递您想要运行的命令。

public static string RunCommand(string arguments, bool readOutput)
{
    var output = string.Empty;
    try
    {
        var startInfo = new ProcessStartInfo
        {
            Verb = "runas",
            FileName = "cmd.exe",
            Arguments = "/C "+arguments,
            WindowStyle = ProcessWindowStyle.Hidden,
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = false
        };

        var proc = Process.Start(startInfo);

        if (readOutput)
        {
            output = proc.StandardOutput.ReadToEnd(); 
        }

        proc.WaitForExit(60000);

        return output;
    }
    catch (Exception)
    {
        return output;
    }
}

2

您可以将代码简单地以.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

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
根据我的经验,当文件路径包含空格时,解析器会按照该空格进行分割。 - Preza8

1
你可以使用 RunProcessAsTask 包来异步、轻松地运行进程,如下所示:
var processResults = await ProcessEx.RunAsync("git.exe", "pull");
//get process result
foreach (var output in processResults.StandardOutput)
{
   Console.WriteLine("Output line: " + output);
}

0

这可能需要一些时间来阅读,所以提前道歉。这是我尝试和测试的方法,可能有更简单的方法,但这是我把代码扔到墙上看哪个粘住了的结果。

如果可以使用批处理文件,则可能过于复杂的解决方法是让C#编写一个.bat文件并运行它。如果您想要用户输入,则可以将输入放入变量中,并让C#将其写入文件中。这种方式需要不断尝试和错误,因为这就像用另一个木偶控制木偶。

这里有一个例子,在这种情况下,该函数是用于Windows论坛应用程序中清除打印队列的按钮。

using System.IO;
using System;

   public static void ClearPrintQueue()
    {

        //this is the path the document or in our case batch file will be placed
        string docPath =
         Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        //this is the path process.start usues
        string path1 = docPath + "\\Test.bat";

        // these are the batch commands
        // remember its "", the comma separates the lines
        string[] lines =
        {
            "@echo off",
            "net stop spooler",
            "del %systemroot%\\System32\\spool\\Printers\\* /Q",
            "net start spooler",
            //this deletes the file
            "del \"%~f0\"" //do not put a comma on the last line
        };

        //this writes the string to the file
        using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
        {
            //This writes the file line by line
            foreach (string line in lines)
                outputFile.WriteLine(line);
        }
        System.Diagnostics.Process.Start(path1);

    }

如果你想要用户输入,你可以尝试像这样的方法。
这是为了将计算机IP设置为静态,但询问用户IP、网关和DNS服务器的设置。
你需要this才能使其工作。
public static void SetIPStatic()
    {
//These open pop up boxes which ask for user input
        string STATIC = Microsoft.VisualBasic.Interaction.InputBox("Whats the static IP?", "", "", 100, 100);
        string SUBNET = Microsoft.VisualBasic.Interaction.InputBox("Whats the Subnet?(Press enter for default)", "255.255.255.0", "", 100, 100);
        string DEFAULTGATEWAY = Microsoft.VisualBasic.Interaction.InputBox("Whats the Default gateway?", "", "", 100, 100);
        string DNS = Microsoft.VisualBasic.Interaction.InputBox("Whats the DNS server IP?(Input required, 8.8.4.4 has already been set as secondary)", "", "", 100, 100);



        //this is the path the document or in our case batch file will be placed
        string docPath =
         Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        //this is the path process.start usues
        string path1 = docPath + "\\Test.bat";

        // these are the batch commands
        // remember its "", the comma separates the lines
        string[] lines =
        {
            "SETLOCAL EnableDelayedExpansion",
            "SET adapterName=",
            "FOR /F \"tokens=* delims=:\" %%a IN ('IPCONFIG ^| FIND /I \"ETHERNET ADAPTER\"') DO (",
            "SET adapterName=%%a",
            "REM Removes \"Ethernet adapter\" from the front of the adapter name",
            "SET adapterName=!adapterName:~17!",
            "REM Removes the colon from the end of the adapter name",
            "SET adapterName=!adapterName:~0,-1!",
//the variables that were set before are used here
            "netsh interface ipv4 set address name=\"!adapterName!\" static " + STATIC + " " + STATIC + " " + DEFAULTGATEWAY,
            "netsh interface ipv4 set dns name=\"!adapterName!\" static " + DNS + " primary",
            "netsh interface ipv4 add dns name=\"!adapterName!\" 8.8.4.4 index=2",
            ")",
            "ipconfig /flushdns",
            "ipconfig /registerdns",
            ":EOF",
            "DEL \"%~f0\"",
            ""
        };

        //this writes the string to the file
        using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, "test.bat")))
        {
            //This writes the file line by line
            foreach (string line in lines)
                outputFile.WriteLine(line);
        }
        System.Diagnostics.Process.Start(path1);

    }

就像我说的那样。这可能有点复杂,但只要我没有写错批处理命令,它就永远不会失败。


0
下面的工作程序使用了上面的几个解决方案来返回版本。
internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(getDotnetversion());
        Console.ReadKey();
    }

    private static string getDotnetversion()
    {
        string version =string.Empty;
        try
        {
            Process cmdDotnet = new Process();
            cmdDotnet.StartInfo.FileName = "dotnet.exe";
            cmdDotnet.StartInfo.RedirectStandardInput = true;
            cmdDotnet.StartInfo.RedirectStandardOutput = true;
            cmdDotnet.StartInfo.CreateNoWindow = true;
            cmdDotnet.StartInfo.UseShellExecute = false;
            cmdDotnet.StartInfo.Arguments = "--version";
            cmdDotnet.Start();
            cmdDotnet.StandardInput.WriteLine("cmd started");
            cmdDotnet.StandardInput.Flush();
            cmdDotnet.StandardInput.Close();
            cmdDotnet.WaitForExit();
            version = cmdDotnet.StandardOutput.ReadToEnd();
        }
        catch
        {
            version = "";
        }
        return version;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接