一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C# - C#如何使用SHBrowseForFolder導(dǎo)出中文文件夾詳解

C#如何使用SHBrowseForFolder導(dǎo)出中文文件夾詳解

2022-03-05 17:04RECT C#

這篇文章主要給大家介紹了關(guān)于C#如何使用SHBrowseForFolder導(dǎo)出中文文件夾的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)合作工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

從業(yè)以來,數(shù)次踩中編碼的坑, 這次又馬失前蹄 , 真是事不過三此非彼白.

本來這個小問題不打算拿出來說 , 但是翻看谷歌發(fā)現(xiàn)若干年前也有寥寥數(shù)人遇到碰到這個問題 ,而且都并沒有給出一個可行的解決方案 ,現(xiàn)在問題依然掛在CSDN等地方 , 似乎不會再有人去回答了, 或者其實題主們后面解決了但并沒有回頭來提供解決方案. 現(xiàn)在由我來”終結(jié)此貼”

SHBrowseForFolder是一個可以用于獲取文件夾路徑的Windows API。使用起來可以方便很多,文中將詳細介紹關(guān)于C#使用SHBrowseForFolder導(dǎo)出中文文件夾的相關(guān)內(nèi)容 ,下面話不多說了,來一起看看詳細的介紹吧

0x00.使用SHBrowseForFolder選擇文件夾

(大段代碼來襲 , 不想看可直接拉到底看關(guān)鍵的幾行)

底層接口 – 選擇文件夾相關(guān)

?

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      //-------------------------------------------------------------------------
      class Win32API
      {
       // C# representation of the IMalloc interface.
       [InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
       Guid("00000002-0000-0000-C000-000000000046")]
       public interface IMalloc
       {
       [PreserveSig]
       IntPtr Alloc([In] int cb);
       [PreserveSig]
       IntPtr Realloc([In] IntPtr pv, [In] int cb);
       [PreserveSig]
       void Free([In] IntPtr pv);
       [PreserveSig]
       int GetSize([In] IntPtr pv);
       [PreserveSig]
       int DidAlloc(IntPtr pv);
       [PreserveSig]
       void HeapMinimize();
       }
       
       [StructLayout(LayoutKind.Sequential, Pack = 8)]
       public struct BROWSEINFO
       {
       public IntPtr hwndOwner;
       public IntPtr pidlRoot;
       public IntPtr pszDisplayName;
       [MarshalAs(UnmanagedType.LPTStr)]
       public string lpszTitle;
       public int ulFlags;
       [MarshalAs(UnmanagedType.FunctionPtr)]
       public Shell32.BFFCALLBACK lpfn;
       public IntPtr lParam;
       public int iImage;
       }
       
       [Flags]
       public enum BffStyles
       {
       RestrictToFilesystem = 0x0001, // BIF_RETURNONLYFSDIRS
       RestrictToDomain = 0x0002, // BIF_DONTGOBELOWDOMAIN
       RestrictToSubfolders = 0x0008, // BIF_RETURNFSANCESTORS
       ShowTextBox = 0x0010, // BIF_EDITBOX
       ValidateSelection = 0x0020, // BIF_VALIDATE
       NewDialogStyle = 0x0040, // BIF_NEWDIALOGSTYLE
       BrowseForComputer = 0x1000, // BIF_BROWSEFORCOMPUTER
       BrowseForPrinter = 0x2000, // BIF_BROWSEFORPRINTER
       BrowseForEverything = 0x4000, // BIF_BROWSEINCLUDEFILES
       }
       
       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
       public class OpenFileName
       {
       public int structSize = 0;
       public IntPtr dlgOwner = IntPtr.Zero;
       public IntPtr instance = IntPtr.Zero;
       public String filter = null;
       public String customFilter = null;
       public int maxCustFilter = 0;
       public int filterIndex = 0;
       public String file = null;
       public int maxFile = 0;
       public String fileTitle = null;
       public int maxFileTitle = 0;
       public String initialDir = null;
       public String id="codetool">

      簡單介紹一下 Win32API 所有接口的結(jié)構(gòu)體 都是參照SHBrowseForFolder函數(shù)而寫 , Win32Instance 主要是精確的獲取當(dāng)前進程的ID

      接下來是 獲取文件夾路徑的簡單例子

      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      //-------------------------------------------------------------------------
      private void __SelectFolder(out string directoryPath)
      {
       directoryPath = "null";
       try
       {
       IntPtr pidlRet = IntPtr.Zero;
       int publicOptions = (int)Win32API.BffStyles.RestrictToFilesystem |
       (int)Win32API.BffStyles.RestrictToDomain;
       int privateOptions = (int)Win32API.BffStyles.NewDialogStyle;
       
       // Construct a BROWSEINFO.
       Win32API.BROWSEINFO bi = new Win32API.BROWSEINFO();
       IntPtr buffer = Marshal.AllocHGlobal(1024);
       int mergedOptions = (int)publicOptions | (int)privateOptions;
       bi.pidlRoot = IntPtr.Zero;
       bi.pszDisplayName = buffer;
       bi.lpszTitle = "文件夾";
       bi.ulFlags = mergedOptions;
       
       Win32Instance w = new Win32Instance();
       bool bSuccess = false;
       IntPtr P = w.GetHandle(ref bSuccess);
       if (true == bSuccess)
       {
        bi.hwndOwner = P;
       }
       
       pidlRet = Win32API.Shell32.SHBrowseForFolder(ref bi);
       Marshal.FreeHGlobal(buffer);
       
       if (pidlRet == IntPtr.Zero)
       {
        // User clicked Cancel.
        return;
       }
       
       byte[] pp = new byte[2048];
       if (0 == Win32API.Shell32.SHGetPathFromIDList(pidlRet, pp))
       {
        return;
       }
       
       int nSize = 0;
       for (int i = 0; i < 2048; i++)
       {
        if (0 != pp[i])
        {
        nSize++;
        }
        else
        {
        break;
        }
       
       }
       
       if (0 == nSize)
       {
        return;
       }
       
       byte[] pReal = new byte[nSize];
       Array.Copy(pp, pReal, nSize);
       // 關(guān)鍵轉(zhuǎn)碼部分
       Gb2312Encoding gbk = new Gb2312Encoding();
       Encoding utf8 = Encoding.UTF8;
       byte[] utf8Bytes = Encoding.Convert(gbk, utf8, pReal);
       string utf8String = utf8.GetString(utf8Bytes);
       utf8String = utf8String.Replace("\0", "");
       directoryPath = utf8String.Replace("\\", "/") + "/";
       
       }
       catch (Exception e)
       {
       Console.WriteLine("獲取文件夾目錄出錯:" + e.Message);
       }
      }

      以上用到的一個GBK轉(zhuǎn)碼庫 位置查看 - github傳送門

      0x01.GBK轉(zhuǎn)碼

      以下是關(guān)鍵的一段代碼:

      ?
      1
      2
      3
      4
      5
      Gb2312Encoding gbk = new Gb2312Encoding();
      Encoding utf8 = Encoding.UTF8;
      byte[] utf8Bytes = Encoding.Convert(gbk, utf8, pReal);
      string utf8String = utf8.GetString(utf8Bytes);
      utf8String = utf8String.Replace("\0", "");

      谷歌上找到的一個方案是把項目編碼全部改為unicode , 但是C#項目里貌似沒這個設(shè)定 , 所以使用SHGetPathFromIDList拿出的數(shù)據(jù)直接轉(zhuǎn)碼即可支持中文.(全部為英文的路徑也不會有影響)

      總結(jié)

      以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

      原文鏈接:http://shadowkong.com/archives/2409

      延伸 · 閱讀

      精彩推薦
      主站蜘蛛池模板: 俄罗斯毛片免费大全 | 201天天爱天天做 | 亚洲26uuuu最新地址 | 9久re热视频这里只有精品 | 99ri在线视频网 | 6个老师的尿奴 | 亚洲 激情| www.毛片在线观看 | 日本乱人伦中文在线播放 | 视频在线91 | 456在线观看 | 亚洲国产在线99视频 | 久久精品一卡二卡三卡四卡视频版 | 91动漫在线观看 | 无遮18禁在线永久免费观看挡 | 麻豆网站在线免费观看 | 牛牛色婷婷在线视频播放 | 日本无卡码一区二区三区 | 欧美巨吊| 俺去也亚洲色图 | 精久久 | 999国产高清在线精品 | 日本视频在线观看 | 女教师被女同学调教成脚奴 | 成人尤物 | 欧美亚洲天堂 | 糖心在线观看 | 金发美女与黑人做爰 | 女人和男人搞鸡 | 婷婷久久综合九色综合九七 | 把女的下面扒开添视频 | 国产一区二区三区四区波多野结衣 | 国产美女亚洲精品久久久久久 | gogort99人体专业网站 | 美女1819xxxx | 色悠久久久久综合欧美99 | 四虎成人免费大片在线 | 污丝瓜视频| 乌克兰黄色录像 | 国产精品手机视频一区二区 | 欠操h|