簡體   English   中英

Process.Start() 和 PATH 環境變量

[英]Process.Start() and PATH environment variable

我有以下簡單的 C# 應用程序,它只是嘗試啟動“jconsole.exe”,它在我的機器上位於 C:\\Programs\\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:”和“programs”之間的兩個反斜杠),它失敗並出現 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”,程序就會啟動。 Windows 在 PATH 中找到帶有雙反斜杠的可執行文件似乎沒有問題,但 Process.Start() 確實如此。

為什么 PATH 中額外的反斜杠會導致問題,我該如何解決這個問題? 我不知道我要調用的可執行文件在運行時將位於何處,所以我寧願依賴 PATH 變量。

不太清楚為什么會出現問題。 不過,我可以想到一種適用於我的機器的解決方案:

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%;"c:\\mypath",則您必須在啟動時完全限定 c:\\mypath 中的任何進程。

我閱讀它的方式,即使PATH變量包含 Windows 能夠使用的有效路徑, Process.Start也無法使用它並且需要完全限定的 path

如果您首先創建ProcessStartInfo ,則可以解決它。

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

// Manipulate dictionary...

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

您必須自己了解如何操作 PATH 以使其為您工作。 但這應該可以解決您的 PATH 變量可能遇到的任何問題。

接受的答案是不正確的。

cmd.exe 將首先查找具有可執行擴展名的應用程序。
因此,當您在C:\\Ruby\\bin\\pumapuma.bat文件時, puma.bat將優先於puma

如果您從c:\\redmine啟動c:\\ruby\\bin\\puma.bat ,它將使用當前工作目錄c:\\ruby\\bin啟動 puma,並且您的 Web 應用程序將正常工作。
但是,如果您直接啟動c:\\ruby\\bin\\puma ,它將以c:\\redmine的當前工作目錄啟動 puma,隨后會失敗。

所以修正后的版本或多或少是這樣的:

// 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM