2011-02-28 17 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

私が探していたもの。ありがとう。私はもう一つ問題があります(このコードの回帰ではなく、既存のものです)。私はファイルをリストしている間、今私はドイツ語でプログラムの2つのファイルを取得しています。 1つはフォルダで、もう1つはOSで実際に表示されるリンクとして表示されます。変更を提案する前に、これらのフォルダのローカライズされていない名前とショートカットのローカライズされた名前を取得していました。ショートカットを繰り返し表示すると、そのショートカットを表示したくありません。 – Scotti

+0

は.lnkファイルをフィルタリングするだけです。 –

+0

culture 'de-DE'(germany)を持つ' Environment.SpecialFolder.Desktop'に対して '' '' '' '' '' '' '' '' '' 'を取得します。どうして? –

2

。上記のコードに何が問題なのかよく分かりませんが(中国語のUnicode文字もあります)、これは確実に動作するようです。ただ、(例えば、呼び出すことによって、パスを渡す:

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のUnicodeに設定されていることを確認する必要があります。

[DllImport("shell32", CharSet = CharSet.Unicode)] 
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 
関連する問題