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

服務(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

      延伸 · 閱讀

      精彩推薦
      主站蜘蛛池模板: 色综合视频一区二区观看 | 97色伦 | 石原莉奈adn093店长未婚妻 | 精品视频日本 | α级毛片| 日本片免费观看一区二区 | 亚洲区一 | 欧美精品久久久久久久免费观看 | 亚洲精品久久7777777 | 二次元美女互摸隐私互扒 | 亚洲欧美一级夜夜爽w | 欧美亚洲一区二区三区在线 | 国产按摩系列 | 99久久精品免费看国产一区二区 | 精品在线播放 | fulao在线观看的 | 免费观看毛片视频 | 国产91一区二区在线播放不卡 | 1314酒色| 香蕉精品高清在线观看视频 | 欧美一级裸片又黄又裸 | 亚洲国产精品综合一区在线 | 青青草国产青春综合久久 | 国产在线观看91 | 日韩精品一区二区三区毛片 | 色综色| www四虎| 国产成人啪精品午夜在线播放 | 亚洲spank男男实践网站 | 美女的隐私视频免费看软件 | kisssis无减删全集在线观看 | 饭冈加奈子乳喷cead144 | 动漫美女被吸乳羞羞小说 | 欧美一级片在线视频 | 国产高清专区 | 大桥未久midd—962在线 | 男女性gif抽搐出入视频 | 成版人快猫永久破解版 | 国产三级精品91三级在专区 | 亚洲 欧美 国产 在线观看 | 色就色欧美综合偷拍区a |