在winform C#中从命令提示符执行自定义命令

本文关键字:执行 自定义 命令 命令提示符 winform | 更新日期: 2023-09-27 18:21:17

我有一个第三方可执行命令,它被绑定到我的winform应用程序中。该命令位于执行应用程序的目录中一个名为"tools"的目录中。

例如,如果我的winform mytestapp.exe放在D:''apps''mytestapp目录中,那么第三方命令的路径是D:''app''mytestapp''tools''mycommand.exe。我使用Application.StartupPath来标识mytestappexe的位置,这样它就可以从任何位置运行。

我通过启动一个进程System.Diagnostics.process.Start并使用命令提示符执行该进程来执行此命令。要传递其他参数以运行该命令。

我面临的问题是,如果我的应用程序和命令的路径中没有任何空格,那么就可以正常工作

例如,如果我的应用程序和命令像下面这样放置,它就会工作D: ''apps''mytestapp''mytestapp.exeD: ''apps''mytestapp''tools''mycommand.exe"parameter1"parameter2"-这适用于

但是,如果路径中有空白,就会失败

C: ''Documents and settings ''mytestapp''tools''mycommand.exe"parameter1"parameter2"-不起作用C: ''Documents and settings ''mytestapp''tools''mycommand.exe"parameter1 parameter2"-不起作用"C:''Documents and settings''mytestapp''tools''mycommand.exe"parameter1 parameter2"-不起作用"C:''Documents and settings ''mytestapp''tools''mycommand.exe parameter1 parameter2"-无法使用

我尝试使用双引号执行如上所示的命令,但它不起作用。那么,我该如何执行自定义命令呢。对此问题有任何意见或解决方案吗?提前谢谢。

这是启动过程的代码

try
        {
            System.Diagnostics.ProcessStartInfo procStartInfo =
                new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;
            procStartInfo.CreateNoWindow = true;
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();
            proc.WaitForExit();
        }
        catch (Exception objException)
        {
            // Log the exception
        }

在winform C#中从命令提示符执行自定义命令

尝试从命令中提取Working目录,并为ProcessStartInfo对象设置WorkingDirectory属性。然后在命令中只传递文件名。

本例假定该命令只包含完整的文件名
需要根据您的实际命令文本进行调整

string command = "C:'Documents and settings'mytestapp'tools'mycommand.exe";
string parameters = "parameter1 parameter2";
try
{
    string workDir = Path.GetDirectoryName(command);
    string fileCmd = Path.GetFileName(command);
    System.Diagnostics.ProcessStartInfo procStartInfo =
        new System.Diagnostics.ProcessStartInfo("cmd", "/c " + fileCmd + " " + parameters);
    procStartInfo.WorkingDirectory = workDir;
    procStartInfo.RedirectStandardOutput = true;
    procStartInfo.UseShellExecute = false;
    procStartInfo.CreateNoWindow = true;
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = procStartInfo;
    proc.Start();
    proc.WaitForExit();
}
catch (Exception objException)
{
    // Log the exception
}

我相信以下是有效的:"C:''Documents and settings''mytestapp''tools''mycommand.exe"参数1"参数2"

你可能有其他问题。试着调试并检查引号是否使用了两次,或者是否有引号在中间。

我认为这可能是因为在引用包含空格的路径的args(和命令)字符串中需要引号;此外,当在代码中定义非逐字(即字符串前面没有@)时,它们也需要转义,因此command字符串的定义如下:

var command = "'"C:''Documents and settings''mytestapp''tools''mycommand.exe'"";
             // ^ escaped quote                                              ^ escaped quote

特别是对于启动进程,我不久前写了这个方法,对于这个特定的情况来说,它可能有点过于专业化了,但人们可以很容易地按原样使用它和/或为设置进程的不同风格编写具有不同参数的重载:

private ProcessStartInfo CreateStartInfo(string command, string args, string workingDirectory, bool useShellExecute)
{
    var defaultWorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty;
    var result = new ProcessStartInfo
    {
        WorkingDirectory = string.IsNullOrEmpty(workingDirectory) 
                                 ? defaultWorkingDirectory 
                                 : workingDirectory,
        FileName = command,
        Arguments = args,
        UseShellExecute = useShellExecute,
        CreateNoWindow = true,
        ErrorDialog = false,
        WindowStyle = ProcessWindowStyle.Hidden,
        RedirectStandardOutput = !useShellExecute,
        RedirectStandardError = !useShellExecute,
        RedirectStandardInput = !useShellExecute
    };
    return result;
}

我像下面这样使用它;这里的_process对象可以是任何Process——将其作为实例变量可能对您的用例无效;此外,OutputDataReceivedErrorDataReceived事件处理程序(未显示)只记录输出字符串,但您可以对其进行解析并在此基础上执行某些操作:

public bool StartProcessAndWaitForExit(string command, string args, 
                     string workingDirectory, bool useShellExecute)
{
    var info = CreateStartInfo(command, args, workingDirectory, useShellExecute);            
    if (info.RedirectStandardOutput) _process.OutputDataReceived += _process_OutputDataReceived;
    if (info.RedirectStandardError) _process.ErrorDataReceived += _process_ErrorDataReceived;
    var logger = _logProvider.GetLogger(GetType().Name);
    try
    {
        _process.Start(info, TimeoutSeconds);
    }
    catch (Exception exception)
    {
        logger.WarnException(log.LogProcessError, exception);
        return false;
    }
    logger.Debug(log.LogProcessCompleted);
    return _process.ExitCode == 0;
}

您传递的args字符串正是您在命令行中输入它的方式,因此在您的情况下,它可能看起来像:

CreateStartInfo("'"C:''Documents and settings''mytestapp''tools''mycommand.exe'"", 
                "-switch1 -param1:'"SomeString'" -param2:'"Some''Path''foo.bar'"",
                string.Empty, true);

如果将路径/命令字符串放在设置文件中,则可以存储它们,而无需转义引号和反斜杠。