的Process.Start()和环境变量PATH(Process.Start() and PATH

2019-06-28 06:34发布

我有一个简单的尝试启动“jconsole.exe”,这在我的机器上位于C以下琐碎的C#应用​​程序:\程序\ jdk16 \ bin中。

using System;
using System.Diagnostics;

namespace dnet {
  public class dnet {
    static void Main( string[] args ) {
      try {
        Process.Start("jconsole.exe");
        Console.WriteLine("Success!");
      } catch (Exception e) {
        Console.WriteLine("{0} Exception caught.", e);
      }
    }
  }
}

如果我的PATH环境变量设置为

c:\windows;c:\windows\sytem32;c:\programs\jdk16\bin

它完美的作品。 但是,如果PATH环境变量设置为

c:\windows;c:\windows\sytem32;c:\\programs\jdk16\bin

(注意两者之间的反斜杠“C:”和“方案”),它没有用win32异常。

System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at dnet.dnet.Main(String[] args)

有趣的是,当我运行.NET程序,并得到异常同一命令提示符下,我可以简单地输入“jconsole.exe”,程序将启动。 窗户似乎不难找到与该路径中的双反斜线的可执行文件,但的Process.Start()一样。

为什么在PATH额外的反斜杠导致的问题,我怎样才能解决这个问题呢? 我不知道在哪里可执行我想打电话将设在运行时,所以我宁愿依靠PATH变量。

Answer 1:

不明白为什么会出现这个问题。 虽然,我能想到的一个解决方案,我的机器上工作的:

var enviromentPath = System.Environment.GetEnvironmentVariable("PATH");

Console.WriteLine(enviromentPath);
var paths = enviromentPath.Split(';');
var exePath = paths.Select(x => Path.Combine(x, "mongo.exe"))
                   .Where(x => File.Exists(x))
                   .FirstOrDefault();

Console.WriteLine(exePath);

if (string.IsNullOrWhiteSpace(exePath) == false)
{
    Process.Start(exePath);
}

我发现它给了我这个解决方案的想法一个段。 从对的Process.Start文档

如果您在使用引号在您的系统路径变量声明,必须在开始在该位置找到的任何进程时完全限定该路径。 否则,系统将无法找到路径。 例如,如果c:\ mypath中是不是在你的路径,你用引号将其添加:PATH =%PATH%;启动时,它\ mypath中:“C:\ mypath中”,则必须完全限定在C的任何进程。

我读的方式,即使PATH变量包含一个有效的路径,Windows是能够使用, Process.Start无法使用它,需要完全合格的路径



Answer 2:

你可以解决它,如果你第一次创建ProcessStartInfo

ProcessStartInfo psi = new ProcessStartInfo("jconsole.exe");
StringDictionary dictionary = psi.EnvironmentVariables;

// Manipulate dictionary...

psi.EnvironmentVariables["PATH"] = dictionary.Replace(@"\\", @"\");
Process.Start(psi);

你必须找出自己如何操作的路径,让它为你工作。 但是,这应该解决您可能有您的PATH变量的任何问题。



Answer 3:

接受的答案是不正确。

CMD.EXE会发现第一个可执行扩展的应用程序。
所以,当你有文件pumapuma.batC:\Ruby\bin\ ,然后puma.bat将优先于puma

如果你开始c:\ruby\bin\puma.bat ,从c:\redmine ,它将开始与PUMA当前工作目录c:\ruby\bin ,和你的web应用程序将工作。
但是,如果你开始c:\ruby\bin\puma直接,它将开始与PUMA在当前工作目录c:\redmine ,并随后将失败。

所以,正确的版本看起来或多或少是这样的:

// FindAppInPathDirectories("ruby.exe");
public string FindAppInPathDirectories(string app)
{
    string enviromentPath = System.Environment.GetEnvironmentVariable("PATH");
    string[] paths = enviromentPath.Split(';');

    foreach (string thisPath in paths)
    {
        string thisFile = System.IO.Path.Combine(thisPath, app);
        string[] executableExtensions = new string[] { ".exe", ".com", ".bat", ".sh", ".vbs", ".vbscript", ".vbe", ".js", ".rb", ".cmd", ".cpl", ".ws", ".wsf", ".msc", ".gadget" };

        foreach (string extension in executableExtensions)
        {
            string fullFile = thisFile + extension;

            try
            {
                if (System.IO.File.Exists(fullFile))
                    return fullFile;
            }
            catch (System.Exception ex)
            {
                Log("{0}:\r\n{1}",
                     System.DateTime.Now.ToString(m_Configuration.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)
                    , "Error trying to check existence of file \"" + fullFile + "\""
                );

                Log("Exception details:");
                Log(" - Exception type: {0}", ex.GetType().FullName);
                Log(" - Exception Message:");
                Log(ex.Message);
                Log(" - Exception Stacktrace:");
                Log(ex.StackTrace);
            } // End Catch

        } // Next extension

    } // Next thisPath


    foreach (string thisPath in paths)
    {
        string thisFile = System.IO.Path.Combine(thisPath, app);

        try
        {
            if (System.IO.File.Exists(thisFile))
                return thisFile;
        }
        catch (System.Exception ex)
        {
            Log("{0}:\r\n{1}",
                 System.DateTime.Now.ToString(m_Configuration.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)
                , "Error trying to check existence of file \"" + thisFile + "\""
            );

            Log("Exception details:");
            Log(" - Exception type: {0}", ex.GetType().FullName);
            Log(" - Exception Message:");
            Log(ex.Message);
            Log(" - Exception Stacktrace:");
            Log(ex.StackTrace);
        } // End Catch

    } // Next thisPath

    return app;
} // End Function FindAppInPathDirectories


文章来源: Process.Start() and PATH environment variable