激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(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 主要是精確的獲取當前進程的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

    延伸 · 閱讀

    精彩推薦
    主站蜘蛛池模板: 国产精品一二三区在线观看 | 日韩精品99久久久久久 | 欧美色淫 | 久在线播放 | 一区小视频 | 国产青青| a视频在线看 | 一级做a爱片久久毛片a高清 | 高清av免费 | 免费看成年人网站 | xx53xx| 亚洲爱爱网站 | 国产精品欧美日韩一区二区 | 7m视频成人精品分类 | 国产精品18久久久久久久久 | 久久久久久久免费精品 | 欧美成人激情在线 | 亚洲精品7777xxxx青睐 | 国产69精品久久久久久 | 青草伊人网 | 91精品国产777在线观看 | 精品亚洲二区 | 一级免费| 黄色大片在线免费看 | 成人做爰高潮片免费视频美国 | 九草在线视频 | 国产精品成人一区二区三区电影毛片 | 欧美精品一区二区三区四区 | 大学生一级毛片在线视频 | 得得啪在线视频 | 中国a级黄色片 | 日韩精品久久久久久久九岛 | 国产亚洲小视频 | 欧美精品免费一区二区三区 | 久久网一区二区 | 欧美日本亚洲视频 | 黄色毛片视频在线观看 | 亚洲日本高清 | 久久在线观看 | 香蕉久久久久久 | 国产色91|