2009-11-05 7 views

답변

2
static void Main(string[] args) 
    { 

     string lpPath = null; 
     string lpFileName = "notepad"; 
     string lpExtension = ".exe"; 
     int nBufferLength = 255; 
     string lpBuffer = ""; 
     string lpFilePart = ""; 

     int bufferSize = SearchPath(lpPath, lpFileName, lpExtension, nBufferLength, out lpBuffer, out lpFilePart); 

    } 

    private static int SearchPath(string lpPath, string lpFileName, string lpExtension, int nBufferLength, out string lpBuffer, out string lpFilePart) 
    { 
     // lpPath [in, optional] 
     // The path to be searched for the file. 
     // If this parameter is NULL, the function searches for a matching file using a registry-dependent system search path. 

     //lpFileName [in] 
     //The name of the file for which to search. 

     //lpExtension [in, optional] 
     //The extension to be added to the file name when searching for the file. The first character of the file name extension must be a period (.). The extension is added only if the specified file name does not end with an extension. 

     //If a file name extension is not required or if the file name contains an extension, this parameter can be NULL. 

     //nBufferLength [in] 
     //The size of the buffer that receives the valid path and file name, in TCHARs. 

     //lpBuffer [out] 
     //A pointer to the buffer to receive the path and file name of the file found. The string is a null-terminated string. 

     //lpFilePart [out, optional] 
     //A pointer to the variable to receive the address (within lpBuffer) of the last component of the valid path and file name, which is the address of the character immediately following the final backslash (\) in the path. 

     //Return Value 
     //If the function succeeds, the value returned is the length, in TCHARs, of the string that is copied to the buffer, not including the terminating null character. If the return value is greater than nBufferLength, the value returned is the size of the buffer that is required to hold the path. 

     //If the function fails, the return value is zero. 

     List<string> pathsToSearch = new List<string>(); 
     string currentWorkingFolder = Environment.CurrentDirectory; 
     string path = System.Environment.GetEnvironmentVariable("path"); 
     lpBuffer = ""; 
     lpFilePart = ""; 

     if (lpPath == null) 
     { 
      RegistryKey key = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager"); 
      object safeProcessSearchModeObject = key.GetValue("SafeProcessSearchMode"); 
      if (safeProcessSearchModeObject != null) 
      { 
       int safeProcessSearchMode = (int)safeProcessSearchModeObject; 
       if (safeProcessSearchMode == 1) 
       { 
        // When the value of this registry key is set to "1", 
        // SearchPath first searches the folders that are specified in the system path, 
        // and then searches the current working folder. 
        pathsToSearch.AddRange(Environment.GetEnvironmentVariable("PATH").Split(new char[] { Path.PathSeparator }, StringSplitOptions.None)); 
        pathsToSearch.Add(currentWorkingFolder); 
       } 
       else 
       { 
        // When the value of this registry entry is set to "0", 
        // the computer first searches the current working folder, 
        // and then searches the folders that are specified in the system path. 
        // The system default value for this registry key is "0". 
        pathsToSearch.Add(currentWorkingFolder); 
        pathsToSearch.AddRange(Environment.GetEnvironmentVariable("PATH").Split(new char[] { Path.PathSeparator }, StringSplitOptions.None)); 
       } 
      } 
      else 
      { 
       // Default 0 case 
       pathsToSearch.Add(currentWorkingFolder); 
       pathsToSearch.AddRange(Environment.GetEnvironmentVariable("PATH").Split(new char[] { Path.PathSeparator }, StringSplitOptions.None)); 
      } 
     } 
     else 
     { 
      // Path was provided, use it 
      pathsToSearch.Add(lpPath); 
     } 

     FileInfo foundFile = SearchPath(pathsToSearch, lpExtension, lpFileName); 
     if (foundFile!= null) 
     { 
      lpBuffer = Path.Combine(foundFile.DirectoryName, foundFile.Name); 
      lpFilePart = foundFile.Name; 

     } 

     return lpBuffer.Length; 
    } 

    private static FileInfo SearchPath(List<string> paths, string extension, string fileNamePart) 
    { 
     foreach (string path in paths) 
     { 
      DirectoryInfo dir = new DirectoryInfo(path); 
      var fileInfo = dir.GetFiles().Where(file => file.Extension == extension && file.Name.Contains(fileNamePart)); 
      if (fileInfo.Any()) 
       return fileInfo.First(); 
     } 
     return null; 
    } 
0

당신은 DirectoryInfo.GetFiles을 사용할 수 있습니다 (문자열의 searchPattern, SearchOption searchOption). 하위 디렉토리를 포함하여 디렉토리에 * .exe 파일을 모두 얻으려면, 당신은 사용할 수 있습니다 : 당신이 전체를 다시 구현 계산하지 않는

DirectoryInfo di = new DirectoryInfo("c:\temp"); 
var files = di.GetFiles("*.exe", SearchOption.AllDirectories); 

이별로 http://msdn.microsoft.com/en-us/library/ms143327.aspx

+0

이것은 실제로 최적의 솔루션이 아닙니다. 분이 걸릴 수 있으며 잘못된 결과가 반환 될 수 있습니다. – Simon

+0

@ 시몬 : 왜 결과가 틀릴 것이라고 생각합니까? – Kamarey

+0

받아 들인 대답을보세요 – Simon

2

에서 MSDN 설명서를 살펴 보자 논리의 C#에서 시간 낭비, IMO, 두 줄의 P/Invoke 때뿐만 아니라 그것을 할 것이라고 스스로.

+0

@codeka - P/Invoke는 모노로 작동하지 않습니다 (관리 솔루션을 원한다면 드라이버가 필요합니다). 분명히, 어떤 이유로 든 P/Invoke는 Simon에게도 마찬가지로 도움이되지 않습니다. 매우 도움이되는 대답은 아닙니다. –

+2

@Michael : SearchPath를 구현하는 것이 모노에서는 의미가 없기 때문에 (적어도 리눅스에서는 P/Invoke가 잘 동작 할 것이다). –