【问题标题】:Unable to set Process.StartInfo.WorkingDirectory to call exe from c#无法将 Process.StartInfo.WorkingDirectory 设置为从 c# 调用 exe
【发布时间】:2019-04-18 11:08:13
【问题描述】:

我正在尝试使用 System.Diagnostics.Process 命名空间在 C# 程序中调用 chrome.exe

我的 chrome.exe 位于路径 C:\Program Files (x86)\Google\Chrome\Application

如果我通过传递以下参数调用 RunProc 函数 - (保持 exe 的绝对路径并保持 WorkingDirectory 为空)

("C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe" , "https://www.google.com", "") 它工作得很好。

但是,有参数 -

("Chrome.exe , "https://www.google.com", "C:\Program Files (x86)\Google\Chrome\Application") 它在步骤 proc.Start 处给出异常(); 说明 - 系统找不到指定的文件。

我还尝试在初始化 StartInfo 时编写 WorkingDirectory = workingDir,但仍在寻找解决方案。

class Program
{
    static void Main(string[] args)
    {
        RunProc(@"chrome.exe", @"https://www.google.com", @"C:\Program Files (x86)\Google\Chrome\Application");
    }

    static bool RunProc(string exe, string args, string workingDir)
    {
        Process proc = new Process
        {
            StartInfo =
            {
                FileName =  exe,
                CreateNoWindow = true,
                RedirectStandardInput = true,
                WindowStyle = ProcessWindowStyle.Hidden,
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                Arguments = args,
                //WorkingDirectory = workingDir
            }
        };

        if (!string.IsNullOrEmpty(workingDir))
        {
            proc.StartInfo.WorkingDirectory = workingDir;
        }

        proc.Start();
        proc.StandardInput.WriteLine(args);
        proc.StandardInput.Flush();
        proc.StandardInput.Close();

        return true;
    }

}

【问题讨论】:

  • 如果您能提供minimal reproducible example,那就太好了,这样我们就可以在代码中看到您是如何调用该方法的(以及使用哪些参数)。
  • 使用这一行:FileName = exeexe 是否包含您要启动的文件的完整路径,或者只是文件名?工作目录不用于执行文件
  • 变量 exe 仅包含文件名。我想设置文件所在的工作目录。如果该文件在您的工作中直接可用,那么您应该只能使用名称运行 exe。
  • @mjwills - 我已经更新了这个问题,给出了完整的工作代码和一个例子。希望这会有所帮助。

标签: c# process system.diagnostics


【解决方案1】:

唯一的方法是让你在尝试启动其他进程之前将你的工作目录更改为传入的工作目录。 WorkingDirectory 属性就是这样,并且不会以任何方式参与查找要运行的可执行文件。如果您未能提供完全限定的名称,那仅取决于您的工作目录和 PATH 环境变量。

static bool RunProc(string exe, string args, string workingDir)
{
    var prevWorking = Environment.CurrentDirectory;
    try
    {
        Environment.CurrentDirectory = workingDir;
        Process proc = new Process
        {
            StartInfo =
            {
               FileName =  exe,
               CreateNoWindow = true,
               RedirectStandardInput = true,
               WindowStyle = ProcessWindowStyle.Hidden,
               UseShellExecute = false,
               RedirectStandardError = true,
               RedirectStandardOutput = true,
               Arguments = args,
            }
        };

        proc.Start();
        proc.StandardInput.WriteLine(args);
        proc.StandardInput.Flush();
        proc.StandardInput.Close();

        return true;
    }
    finally
    {
        Environment.CurrentDirectory = prevWorking;
    }
}

【讨论】:

  • 效果很好。我解释了workingDirectory 属性错误,非常感谢您澄清这一点。这解决了我的问题。
  • 如果您可以编辑第 6 行,例如 Environment.CurrentDirectory = workingDir;对其他观众来说会更好。
  • @ArkilShaikh - 完成。很高兴即使有错字你也能得到它。
【解决方案2】:

为什么不直接从它所在的路径调用 .exe 呢?

Process.Start(@"C:\new\folder\abcd.exe");

或者直接放

proc.StartInfo.WorkingDirectory = @"c:\new\folder";

在 proc.start() 之前;

【讨论】:

  • 感谢您的回复。我可以遵循您的第一个建议,但我使用这段代码的地方将有复杂的 exe 名称、文件夹路径和参数,因此最好将所有这些分开。我已经尝试了您的第二个建议,但没有奏效。
【解决方案3】:

您如何看待在您的静态方法中结合 .exe 的绝对路径并在调用 Process start 之前检查该路径是否存在:

using System.Diagnostics;
using System.IO;

namespace RunProc
{
    class Program
    {
        static void Main(string[] args)
        {
            RunProc(@"chrome.exe", @"https://www.google.com", @"C:\Program Files (x86)\Google\Chrome\Application");
        }

        static bool RunProc(string exe, string args, string workingDir)
        {
            string filePath = workingDir + "\"" + exe;

            if (!File.Exists(filePath))
                return false;

            Process proc = new Process
            {
                StartInfo =
                {
                    FileName =  filePath,
                    CreateNoWindow = true,
                    RedirectStandardInput = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    Arguments = args,
                }
            };

            proc.Start();
            proc.StandardInput.WriteLine(args);
            proc.StandardInput.Flush();
            proc.StandardInput.Close();

            return true;
        }
    }
}

也许,RunProc 方法使用DirectoryInfoFileInfo 会更清晰一些

using System.Diagnostics;
using System.IO;

namespace RunProc
{
    class Program
    {
        static void Main(string[] args)
        {
            FileInfo myRelativeFileExe = new FileInfo(@"chrome.exe");
            DirectoryInfo myAbsoluteFileDir = new DirectoryInfo(@"C:\Program Files (x86)\Google\Chrome\Application");
            
            RunProc(myRelativeFileExe, myAbsoluteFileDir, @"https://www.google.com");
        }

        static bool RunProc(FileInfo exe, DirectoryInfo workingDir, string args)
        {
            FileInfo myAbsoluteFilePath = new FileInfo(Path.Combine(workingDir.ToString(), exe.ToString()));

            if (!myAbsoluteFilePath.Exists)
                return false;

            Process proc = new Process
            {
                StartInfo =
                {
                    FileName =  myAbsoluteFilePath.FullName,
                    CreateNoWindow = true,
                    RedirectStandardInput = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    Arguments = args,
                }
            };

            proc.Start();
            proc.StandardInput.WriteLine(args);
            proc.StandardInput.Flush();
            proc.StandardInput.Close();

            return true;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 2020-06-02
    相关资源
    最近更新 更多