2013-10-22 2 views
3

C# 응용 프로그램의 시작 메뉴에서 프로그램을 시작하려고하는데 거의 모든 항목 시작 메뉴에는 바로 가기 (lnk) 파일이 있습니다. Process.Start를 사용하여 이러한 파일을 실행할 때 lnk 파일의 전체 경로가 C : \ Program Files 디렉터리를 가리키면 "지정한 경로를 찾을 수 없습니다"라는 오류가 나타났습니다. 나는 Windows의 File System Redirection 몇 가지 조사를했는데, 그래서 그것을 해제 시도,하지만 난 여전히 같은 오류를 받고 있어요 ". 지정한 경로를 찾을 수 없습니다"전체 경로가 64 비트 디렉터리로 해석 될 때 32 비트 C# 응용 프로그램에서 바로 가기 (lnk) 파일을 실행할 수 없습니다.

이 반환
// disable file system redirection: 
IntPtr ptr = new IntPtr(); 
bool isWow64FsRedirectionDisabled = Wow64DisableWow64FsRedirection(ref ptr); 
// run the file: 
System.Diagnostics.Process.Start("c:\\splitter.lnk"); 

그러나 시작> 실행 대화 상자에서 c : \ splitter.lnk를 실행하면 프로그램이 제대로 실행됩니다. 64 비트 응용 프로그램에 대한 바로 가기를 만들어 C 드라이브에 저장하고 위의 코드를 사용하여 실행하려고하면 모든 64 비트 컴퓨터에서이 문제를 재현 할 수 있습니다.

이 문제를 피하기 위해 .lnk 파일을 실행하는 더 좋은 방법이 있습니까? 또는 파일 리디렉션을 제대로 비활성화하지 않았습니까?

편집 : 나는 또한 운영 체제가 파일을 실행하도록 true로 인 UseShellExecute를 설정했지만, 대화 상자를 실행하여 시작에서 동일한 경로>를 실행하면 잘 작동하기 때문에 그것은 여전히 ​​흥미있는 실패

Process process = new Process(); 
process.StartInfo.UseShellExecute = true; 
process.StartInfo.FileName = "c:\\splitter.lnk"; 
process.Start(); 

EDIT 2 : LNK 파일을 직접 실행하려고 시도하지 않고 대상을 얻은 다음 대상을 실행한다고 생각했습니다. How to resolve a .lnk in c#How to follow a .lnk file programmatically을 사용해 보았지만 두 방법 모두 C : \ Program Files \ Splitter.exe의 실제 경로 대신 C : \ Program Files (x86) \ Splitter.exe로 전체 경로를 반환합니다.

아마도 위의 방법 중 하나를 사용하여 LNK 파일의 대상을 가져올 수 있습니다. 그런 다음 대상에 Program Files (x86)가 포함되어 있는지 확인할 수 있습니다. 그렇다면 프로그램 파일로 바꾸고 파일이 존재하는지 확인하십시오. Program Files에 있으면 실행하십시오. 그렇지 않은 경우, Program Files (x86) 위치에서 파일을 실행하십시오. 이것은 지저분한 해결 방법이 될 것이지만, 지금은 무엇을 시도해야할지 모르겠습니다. 모든 제안을 부탁드립니다.

+0

32 비트 프로세스로 실행해야하며 * 64 비트 프로세스에서만 링크가 사용 가능한 프로그램을 시작하려면 문제를 풀 필요가 없습니다. .NET 프로그램에서 Wow64DisableWow64FsRedirection()을 호출하는 것이 매우 번거롭기 때문에 지터로 DLL이로드 될지 알 수 없습니다. AnyCPU에 건물은 항상 당신이 선호하는 솔루션이어야합니다. –

+0

AnyCPU에 구축 중이며 여전히 오류가 발생합니다. – andrewl85

+0

글쎄, 메시지가 참으로 정확하고 실제로 잘못된 경로를 사용하고 있다고 가정하는 것이 가장 좋습니다. 예제 코드가 확실히 도움이되지 않습니다. "c : \\ splitter.lnk"는 "c : \\ program files"에 대한 질문과 전혀 일치하지 않습니다. 시작 메뉴의 바로 가기는 해당 디렉토리에 저장되지 않으며 AppData 하위 디렉토리에 있습니다. –

답변

4

Sam Saffron의 예제 스크립트 How to resolve a .lnk in c#을 사용하여이 문제의 해결 방법을 제공 할 수있었습니다. 나는 다음에 ResolveShortcut 기능을 수정 : 사람이 할 수있는 더 좋은 방법을 알고

public static string ResolveShortcut(string filename) 
{ 
    // this gets the full path from a shortcut (.lnk file). 
    ShellLink link = new ShellLink(); 
    ((IPersistFile)link).Load(filename, STGM_READ); 
    StringBuilder sb = new StringBuilder(MAX_PATH); 
    WIN32_FIND_DATAW data = new WIN32_FIND_DATAW(); 
    ((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0); 
    string final_string = sb.ToString(); 
    if (final_string.Length == 0) 
     final_string = filename; 
    // If the the shortcut's target resolves to the Program Files or System32 directory, and the user is on a 
    // 64-bit machine, the final string may actually point to C:\Program Files (x86) or C:\Windows\SYSWOW64. 
    // This is due to File System Redirection in Windows -- http://msdn.microsoft.com/en-us/library/aa365743%28VS.85%29.aspx. 
    // Unfortunately the solution there doesn't appear to work for 32-bit apps on 64-bit machines. 
    // We will provide a workaround here: 
    string new_path = Validate_Shortcut_Path(final_string, "SysWOW64", "System32"); 
    if (File.Exists(new_path) == true && File.Exists(final_string) == false) 
    { 
     // the file is actually stored in System32 instead of SysWOW64. Let's update it. 
     final_string = new_path; 
    } 
    new_path = Validate_Shortcut_Path(final_string, "Program Files (x86)", "Program Files"); 
    if (File.Exists(new_path) == true && File.Exists(final_string) == false) 
    { 
     // the file is actually stored in Program Files instead of Program Files (x86). Let's update it. 
     final_string = new_path; 
    } 
    // the lnk may incorrectly resolve to the C:\Windows\Installer directory. Check for this. 
    if (final_string.ToLower().IndexOf("windows\\installer") > -1) 
     final_string = filename; 
    if (File.Exists(final_string)) 
     return final_string; 
    else 
     return filename; 
    } 

public static string Validate_Shortcut_Path(string final_string, string find_what, string replace_with) 
{ 
    string final_string_lower = final_string.ToLower(); 
    string find_what_lower = find_what.ToLower(); 
    int find_value = final_string_lower.IndexOf(find_what_lower); 
    if (find_value > -1) 
    { 
     // the shortcut resolved to the find_what directory, which can be SysWOW64 or Program Files (x86), 
     // but this may not be correct. Let's check by replacing it with another value. 
     string new_string = final_string.Substring(0, find_value) + replace_with + final_string.Substring(find_value + find_what.Length); 
     if (File.Exists(new_string) == true && File.Exists(final_string) == false) 
     { 
      // the file is actually stored at a different location. Let's update it. 
      final_string = new_string; 
     } 
    } 
    return final_string; 
} 

경우에, 나는 아이디어에 개방입니다. 그렇지 않으면이 방법을 사용하고이 해결 방법을 대답으로 사용합니다.

관련 문제