2011-02-28 3 views
6

나는 특정 디렉토리의 모든 파일/폴더 이름을 나열해야하는 C#에서 기능을 작성하고 있습니다. 이 기능은 EN OS에서 제대로 실행되지만 현지화 된 OS (예 : 독일어)에서 응용 프로그램을 실행하면 특수 폴더 (프로그램 대신 프로그램 파일, Favoriten 대신 즐겨 찾기 등)의 영어 이름이 계속 표시됩니다. Environment.GetFolderPath with Environment.SpecialFolder는 내가 원하는 것의 정반대로 모든 도움이 될 수 있다고 생각합니다. 즉, 지정된 폴더의 전체 경로를 제공합니다. 반면에 주어진 지역화 된 이름을 원합니다. 통로. File, SHFileInfo를 사용해 보았지만 사용하지는 않았습니다. 어떤 생각, OS에서 표시되는 폴더 이름을 어떻게 얻을 수 있습니까?실제 (현지화 된) 폴더 이름을 얻는 방법은 무엇입니까?

+0

내가 u는 내가 영어 이름은 말할 것 ... 코드에서 –

+0

를 로케일을 설정할 필요가 있다고 생각 실제 이름 (필요하다. 파일에 액세스 할 수 있습니다.) 그리고 독일어 이름은 표시 이름입니다. – CodesInChaos

답변

10

당신은 SHGetFileInfo API와 지역화 된 표시 이름을 얻을 수 있습니다 :이 작동하도록하는 방법을 알아낼했다

public static string GetDisplayName(Environment.SpecialFolder specialFolder) 
    { 
     IntPtr pidl = IntPtr.Zero; 
     try 
     { 
      HResult hr = SHGetFolderLocation(IntPtr.Zero, (int) specialFolder, IntPtr.Zero, 0, out pidl); 
      if (hr.IsFailure) 
       return null; 

      SHFILEINFO shfi; 
      if (0 != SHGetFileInfo(
         pidl, 
         FILE_ATTRIBUTE_NORMAL, 
         out shfi, 
         (uint)Marshal.SizeOf(typeof(SHFILEINFO)), 
         SHGFI_PIDL | SHGFI_DISPLAYNAME)) 
      { 
       return shfi.szDisplayName; 
      } 
      return null; 
     } 
     finally 
     { 
      if (pidl != IntPtr.Zero) 
       ILFree(pidl); 
     } 
    } 

    public static string GetDisplayName(string path) 
    { 
     SHFILEINFO shfi; 
     if (0 != SHGetFileInfo(
        path, 
        FILE_ATTRIBUTE_NORMAL, 
        out shfi, 
        (uint)Marshal.SizeOf(typeof(SHFILEINFO)), 
        SHGFI_DISPLAYNAME)) 
     { 
      return shfi.szDisplayName; 
     } 
     return null; 
    } 

    private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; 
    private const uint SHGFI_DISPLAYNAME = 0x000000200;  // get display name 
    private const uint SHGFI_PIDL = 0x000000008;  // pszPath is a pidl 

    [DllImport("shell32")] 
    private static extern int SHGetFileInfo(IntPtr pidl, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags); 
    [DllImport("shell32")] 
    private static extern HResult SHGetFolderLocation(IntPtr hwnd, int nFolder, IntPtr token, int dwReserved, out IntPtr pidl); 
    [DllImport("shell32")] 
    private static extern void ILFree(IntPtr pidl); 

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] 
    private struct SHFILEINFO 
    { 
     public IntPtr hIcon; 
     public int iIcon; 
     public uint dwAttributes; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
     public string szDisplayName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
     public string szTypeName; 
    } 

[StructLayout(LayoutKind.Sequential)] 
public struct HResult 
{ 
    private int _value; 

    public int Value 
    { 
     get { return _value; } 
    } 

    public Exception Exception 
    { 
     get { return Marshal.GetExceptionForHR(_value); } 
    } 

    public bool IsSuccess 
    { 
     get { return _value >= 0; } 
    } 

    public bool IsFailure 
    { 
     get { return _value < 0; } 
    } 
} 
+0

정확히 내가 무엇을 찾고 있었습니까. 감사. 그러나 나는 한 가지 더 많은 문제 (이 코드의 회귀가 아니라 선재)를 가지고있다. 파일을 나열하는 동안, 이제 독일어로 된 두 개의 파일이 나옵니다. 하나는 폴더이고 다른 하나는 실제로 OS에서 볼 수있는 링크로 보여줍니다. 변경 제안을하기 전에이 폴더에 대한 지역화되지 않은 이름과 바로 가기에 대한 지역화 된 이름을 얻었습니다. 목록을 반복적으로 만들 때 바로 가기를 표시하고 싶지 않습니다. – Scotti

+0

그냥 .lnk 파일을 필터링합니다. –

+0

culture'de-DE' (germany)를 사용하여'Environment.SpecialFolder.Desktop'에''敄潴潴敄敄潴潴潴潴潴''''''......습니다. 왜? –

2

. 위의 코드가 무엇인지 잘 모르겠다. (중국어 유니 코드 문자도있다.) 그러나 이것은 안정적으로 작동하는 것처럼 보인다.

GetDisplayName(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); 

을하며,이 예에서 ("내 문서"폴더의 표시 이름을 반환하거나)로 이름을 변경 한 어떤

: 그냥 예를 들어, 호출하여 (경로에 전달합니다.
using System.Runtime.InteropServices; 
... 
public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; 
public const uint SHGFI_DISPLAYNAME = 0x000000200;  // get display name 

[DllImport("shell32")] 
public static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, 
    out SHFILEINFO psfi, uint cbFileInfo, uint flags); 

[StructLayout(LayoutKind.Sequential)] 
public struct SHFILEINFO 
{ 
    public IntPtr hIcon; 
    public IntPtr iIcon; 
    public uint dwAttributes; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public string szDisplayName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
    public string szTypeName; 
}; 


public static string GetDisplayName(string path) 
{ 
    SHFILEINFO shfi = new SHFILEINFO(); 
    if (0 != SHGetFileInfo(path,FILE_ATTRIBUTE_NORMAL,out shfi, 
     (uint)Marshal.SizeOf(typeof(SHFILEINFO)),SHGFI_DISPLAYNAME)) 
    { 
     return shfi.szDisplayName; 
    } 
    return null; 
} 
+0

일부 중국어 문자를 제공하는 다른 솔루션과 비교하여 작동합니다. – whywhywhy

0

당신은 캐릭터 셋 같이 DllImport과 StructLayout 유니 코드로 설정되어 있는지 확인해야합니다.

[DllImport("shell32", CharSet = CharSet.Unicode)] 
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 
관련 문제