2011-02-28 20 views
6

Belirli bir dizindeki tüm dosya/klasör adlarını listelemem gereken C# işlevinde bir işlev yazıyorum. İşlevsellik, EN OS'de iyi çalışır, ancak uygulamayı yerelleştirilmiş işletim sistemi (ör.) Almanca'da çalıştırdığımda, Özel Klasörler'in İngilizce isimlerini (Program Dosyaları yerine Program Dosyaları, Favoriten yerine Sık Kullanılanlar vb.) Alıyorum. Ben Environment.GetFolderPath Environment.SpecialFolder ile istediğimin tam tersi gibi herhangi bir yardım olabileceğini sanmıyorum, yani, belirtilen özel klasör tam yol verir, oysa, verilen yerelleştirilmiş adını istiyorum yolu. File, SHFileInfo kullanmayı denedim, fakat kullanmam. Herhangi bir fikir, işletim sistemindeki gibi klasör adlarını nasıl alabilirim?Gerçek (yerelleştirilmiş) klasör adları nasıl alınır?

+0

i u ben İngilizce adı olduğunu söyleyebilirim ... kodunda –

+0

mevkiinizi ayarlamak gerektiğini düşünüyorum gerçek isim (buna ihtiyacın var Dosyaya erişmek için) ve Alman adı sadece görünen addır. – CodesInChaos

cevap

10

Sen SHGetFileInfo API ile yerelleştirilmiş ismini alabilirsiniz: Ben bu işe nasıl anlamaya did

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

tam olarak aradığım şey. Teşekkürler. Ancak bir sorunum daha var (bu kodun gerilemesi değil, önceden var). Dosyaları listelerken, Şimdi Almanca Program için iki dosya alıyorum. Biri bir Klasör ve diğeri OS'de gerçekten görülebilen bir bağlantı olarak gösterilir. Değişikliği önermeden önce, bu klasörler için yerelleştirilmemiş adı ve kısayollar için yerelleştirilmiş adı alıyordum. Listeyi tekrarlı hale getirirken kısayolları göstermek istemiyorum. – Scotti

+0

sadece .lnk dosyaları süzün –

+0

Ben .S 敄 歳 潴 p 敄 歳 潴 p' için "de-DE" (germany) kültürü ile Environment.SpecialFolder.Desktop 'almak. Niye ya? –

2

. Yukarıdaki kodda neyin yanlış olduğundan emin değilim (ayrıca Çince Unicode karakterleri de var), ancak bu güvenilir bir şekilde çalışıyor gibi görünüyor.

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

ve bu örnekte ("Belgelerim" klasöründe görünen adını verir ya siz) onu yeniden adlandırdık neyse

: Sadece örneğin arayarak (yolu geçirmek.
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

Bu, bazı Çin chars veren diğer çözüm ile karşılaştırıldığında çalışır. – whywhywhy

0

Sen CharSet Dllımport ve StructLayout için Unicode olarak ayarlanmış olduğundan emin olmak gerekir.

[DllImport("shell32", CharSet = CharSet.Unicode)] 
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 
İlgili konular