【问题标题】:Executing custom commands from command prompt in winform C#在winform C#中从命令提示符执行自定义命令
【发布时间】:2013-07-05 18:47:49
【问题描述】:

我有一个第三方可执行命令被捆绑到我的 winform 应用程序中。该命令放置在执行应用程序的目录中名为“tools”的目录中。

比如我的winform mytestapp.exe放在D:\apps\mytestapp目录下,那么第三方命令的路径就是D:\apps\mytestapp\tools\mycommand.exe。我正在使用 Application.StartupPath 来识别 mytestapp.exe 的位置,以便它可以从任何位置运行。

我通过启动一个进程 - System.Diagnostics.Process.Start 并使用命令提示符执行该命令来执行此命令。运行命令需要传递额外的参数。

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

例如, 如果我的应用程序和命令如下所示,它可以工作 D:\apps\mytestapp\mytestapp.exe D:\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
        }

【问题讨论】:

  • 有什么异常?你能在 Process.Start 周围分享你的代码吗
  • 显示您的 processstartinfo 设置代码,您应该会得到快速的答案 :)
  • @retailcoder,我认为 processstartinfo 中没有错误,因为当路径中没有空格时,我得到了所需的输出。
  • 如果您将文件路径作为参数传入,您需要将它们封装在引号中,或者转义空格。

标签: c# winforms command


【解决方案1】:

尝试从您的命令中提取工作目录并为 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:\Users\mytestapp\command.exe C:\somefolder\somefile.txt D:\newfolder\newfolder.txt - works "C:\Users\mytestapp\command.exe C:\somefolder\somefile .txt D:\newfolder\newfolder.txt" - 工作 C:\Users\mytestapp\command.exe "C:\somefolder\somefile.txt" "D:\newfolder\newfolder.txt" - 工作 "C:\Users \mytestapp\command.exe" C:\somefolder\somefile.txt D:\newfolder\newfolder.txt - 有效 command.exe 路径或 file1 路径或 file2 路径中的任何空格 - 失败。我尝试了引号的组合。 :(
  • 你能传递与其参数分开的command.exe吗?就像我更新的答案一样?
【解决方案2】:

我相信以下工作: "C:\Documents and settings\mytestapp\tools\mycommand.exe" "parameter1" "parameter2"

您可能还有其他问题。尝试调试一下,看看引号是不是用了两次,或者中间有没有引号。

【讨论】:

    【解决方案3】:

    我认为这可能是因为在引用包含空格的路径的 args(和命令)字符串中需要引号;当在代码中定义 non-verbatim(即在字符串之前没有 @)时,它们也需要被转义,因此 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);
    

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

    【讨论】:

      猜你喜欢
      • 2011-10-26
      • 1970-01-01
      • 2011-07-08
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 2013-08-01
      • 2017-02-28
      • 2012-11-23
      相关资源
      最近更新 更多