Windows 경로에 실행 파일이 있는지 확인
프로세스를 실행하는 경우 ShellExecute
(또는 .net에서 System.Diagnostics.Process.Start()
) 시작할 파일 이름 프로세스가 전체 경로 일 필요는 없습니다.
메모장을 시작하려면 다음을 사용할 수 있습니다.
Process.Start("notepad.exe");
대신에
Process.Start(@"c:\windows\system32\notepad.exe");
direcotry c:\windows\system32
는 PATH 환경 변수의 일부 이기 때문 입니다.
프로세스를 실행하지 않고 PATH 변수를 구문 분석하지 않고 PATH에 파일이 있는지 어떻게 확인할 수 있습니까?
System.IO.File.Exists("notepad.exe"); // returns false
(new System.IO.FileInfo("notepad.exe")).Exists; // returns false
하지만 다음과 같은 것이 필요합니다.
System.IO.File.ExistsOnPath("notepad.exe"); // should return true
과
System.IO.File.GetFullPath("notepad.exe"); // (like unix which cmd) should return
// c:\windows\system32\notepad.exe
BCL에서이 작업을 수행하기 위해 미리 정의 된 클래스가 있습니까?
내장 된 것이 없다고 생각하지만 System.IO.File.Exists를 사용 하여 이와 같은 작업을 수행 할 수 있습니다 .
public static bool ExistsOnPath(string fileName)
{
return GetFullPath(fileName) != null;
}
public static string GetFullPath(string fileName)
{
if (File.Exists(fileName))
return Path.GetFullPath(fileName);
var values = Environment.GetEnvironmentVariable("PATH");
foreach (var path in values.Split(Path.PathSeparator))
{
var fullPath = Path.Combine(path, fileName);
if (File.Exists(fullPath))
return fullPath;
}
return null;
}
이것은 위험하며 PATH에서 디렉토리를 검색하는 것보다 훨씬 더 많습니다. 이 시도:
Process.Start("wordpad.exe");
실행 파일은 내 컴퓨터의 c : \ Program Files \ Windows NT \ Accessories에 저장되며 해당 디렉터리는 경로에 없습니다 .
HKCR \ Applications 및 HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ App Paths 키도 실행 파일을 찾는 데 역할을합니다. 예를 들어 64 비트 버전의 Windows에서 디렉터리 가상화가 발생하면 이와 같은 추가 지뢰가있을 것이라고 확신합니다.
이것을 더 안정적으로 만들려면 AssocQueryString ()을 pinvoke해야한다고 생각합니다. 확실하지 않고 필요가 없었습니다. 더 나은 접근 방식은 확실히 질문을하지 않는 것입니다.
좋아, 내 생각에 더 나은 방법 ...
이것은 적어도 Windows 7 / Server 2003에서 사용할 수 있는 where 명령을 사용합니다 .
public static bool ExistsOnPath(string exeName)
{
try
{
using (Process p = new Process())
{
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "where";
p.StartInfo.Arguments = exeName;
p.Start();
p.WaitForExit();
return p.ExitCode == 0;
}
}
catch(Win32Exception)
{
throw new Exception("'where' command is not on path");
}
}
public static string GetFullPath(string exeName)
{
try
{
using (Process p = new Process())
{
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "where";
p.StartInfo.Arguments = exeName;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
if (p.ExitCode != 0)
return null;
// just return first match
return output.Substring(0, output.IndexOf(Environment.NewLine));
}
}
catch(Win32Exception)
{
throw new Exception("'where' command is not on path");
}
}
Accepted answer states that there is nothing build-in, but this is not true. There is a standard WinAPI PathFindOnPath for doing this, it is available since Windows 2000.
I tried out Dunc's "where" process and it works, but it's slow and resource-heavy and there's the slight danger of having an orphaned process.
I like Eugene Mala's tip about PathFindOnPath, so I fleshed that out as a complete answer. This is what I'm using for our custom in-house tool.
/// <summary>
/// Gets the full path of the given executable filename as if the user had entered this
/// executable in a shell. So, for example, the Windows PATH environment variable will
/// be examined. If the filename can't be found by Windows, null is returned.</summary>
/// <param name="exeName"></param>
/// <returns>The full path if successful, or null otherwise.</returns>
public static string GetFullPathFromWindows(string exeName)
{
if (exeName.Length >= MAX_PATH)
throw new ArgumentException($"The executable name '{exeName}' must have less than {MAX_PATH} characters.",
nameof(exeName));
StringBuilder sb = new StringBuilder(exeName, MAX_PATH);
return PathFindOnPath(sb, null) ? sb.ToString() : null;
}
// https://docs.microsoft.com/en-us/windows/desktop/api/shlwapi/nf-shlwapi-pathfindonpathw
// https://www.pinvoke.net/default.aspx/shlwapi.PathFindOnPath
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = false)]
static extern bool PathFindOnPath([In, Out] StringBuilder pszFile, [In] string[] ppszOtherDirs);
// from MAPIWIN.h :
private const int MAX_PATH = 260;
I'm after the same thing and I think the best option that I have right now is to use native call to CreateProcess to create a process suspended and watch for success; terminating the process immediately afterward. Terminating a suspended process should not incur any resource bleeding [citation needed :)]
I may not be able to figure out the path that actually got used but for a simple requirement as ExistsOnPath() it should do - till there's a better solution.
ReferenceURL : https://stackoverflow.com/questions/3855956/check-if-an-executable-exists-in-the-windows-path
'Nice programing' 카테고리의 다른 글
Eclipse에서 기본 디버그를 만들고 구성을 실행하는 방법은 무엇입니까? (0) | 2020.12.29 |
---|---|
리프팅 운영자는 무엇입니까? (0) | 2020.12.29 |
PHP에서 "같지 않음"연산자 <>와! =의 차이점 (0) | 2020.12.29 |
스레드 중단 (Thread.Abort 메서드)과 같은 작업을 중단 할 수 있습니까? (0) | 2020.12.29 |
Html.ActionLink를 동적으로 전달할 수 없습니다. (0) | 2020.12.29 |