私のマシンではC:\ Programs\jdk16\binにある「jconsole.exe」を起動しようとする次の簡単なC#アプリケーションがあります。
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」の間の2つのバックスラッシュに注意してください)、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変数に依存したいと思います。
問題が発生する理由がよくわかりません。ただし、自分のマシンで機能する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);
}
私はこの解決策のアイデアを私に与えた1つのパラを見つけました。 Process.Startのドキュメント から
システムで引用符を使用してパス変数を宣言している場合は、その場所で見つかったプロセスを開始するときに、そのパスを完全に修飾する必要があります。そうしないと、システムはパスを見つけられません。たとえば、c:\ mypathがパスになく、引用符を使用して追加する場合:path =%path%; "c:\ mypath"、c:\ mypath内のプロセスを開始するときに完全修飾する必要があります。
PATH
変数に、Windowsが使用できる有効なパスが含まれていても、私が読んだ方法では、Process.Start
はそれを使用できず、完全修飾パスが必要です。
最初に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は、実行可能な拡張子を持つアプリケーションを最初に検索します。
したがって、ファイルpuma
とpuma.bat
がC:\Ruby\bin\
にある場合、puma.bat
はpuma
よりも優先されます。
c:\Ruby\bin\puma.bat
からc:\redmine
を開始すると、現在の作業ディレクトリ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