<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WPF 打開(kāi)資源管理器且選中某個(gè)文件

      命令行方法

      打開(kāi)資源管理器且選中某個(gè)文件可以使用 cmd 調(diào)用 explorer 帶上 select 參數(shù),如下面命令行所示

      explorer.exe /select,"C:\Folder\file.txt"
      

      但有很多情況下,用戶可能使用其他資源管理器,此時(shí)將會(huì)導(dǎo)致應(yīng)用軟件打開(kāi)的是 explorer 而不是用戶默認(rèn)的資源管理器

      SHOpenFolderAndSelectItems 單文件

      通過(guò) shell32.dll 提供的 SHOpenFolderAndSelectItems 方法,可以直接使用函數(shù)調(diào)用的方式打開(kāi)資源管理器且選中某個(gè)文件,且使用的是用戶設(shè)置的默認(rèn)的資源管理器

      以下是我創(chuàng)建的簡(jiǎn)單的 WPF 例子程序的界面,可以看到界面非常簡(jiǎn)單,就是輸入一個(gè)文件,然后點(diǎn)擊按鈕就可以打開(kāi)資源管理器選中輸入的文件

          <Grid>
              <Grid VerticalAlignment="Center">
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="Auto"></ColumnDefinition>
                      <ColumnDefinition Width="*"></ColumnDefinition>
                      <ColumnDefinition Width="Auto"></ColumnDefinition>
                  </Grid.ColumnDefinitions>
                  <TextBlock Text="文件路徑:" Margin="50,0,0,0" VerticalAlignment="Center"/>
                  <TextBox x:Name="InputTextBox"  Grid.Column="1" Margin="10,0,10,0" VerticalAlignment="Center"/>
                  <Button Grid.Column="2" Content="打開(kāi)" Margin="10,0,50,0" VerticalAlignment="Center" Click="Button_OnClick"/>
              </Grid>
          </Grid>
      

      按鈕的后臺(tái)代碼將需要使用 PInvoke 調(diào)用 Win32 函數(shù)。對(duì)于 dotnet 7 以前的程序,可使用如下方式定義

          [DllImport("shell32.dll", ExactSpelling = true)]
          private static extern void ILFree(IntPtr pidlList);
      
          [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
          private static extern IntPtr ILCreateFromPathW(string pszPath);
      
          [DllImport("shell32.dll", ExactSpelling = true)]
          private static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
      

      對(duì)于 dotnet 7 以及更高版本的項(xiàng)目,可使用 LibraryImportAttribute 特性輔助定義。如以下 C# 代碼所示

          [LibraryImport("shell32.dll")]
          private static partial void ILFree(IntPtr pidlList);
      
          [LibraryImport("shell32.dll", StringMarshalling = StringMarshalling.Utf16)]
          private static partial IntPtr ILCreateFromPathW(string pszPath);
      
          [LibraryImport("shell32.dll")]
          private static partial int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
      

      過(guò)程中別忘了在 csproj 項(xiàng)目文件里面開(kāi)啟不安全代碼,開(kāi)啟之后的項(xiàng)目文件代碼大概如下

      <Project Sdk="Microsoft.NET.Sdk">
      
        <PropertyGroup>
          <OutputType>WinExe</OutputType>
          <TargetFramework>net9.0-windows</TargetFramework>
          <Nullable>enable</Nullable>
          <ImplicitUsings>enable</ImplicitUsings>
          <UseWPF>true</UseWPF>
          <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
        </PropertyGroup>
      
      </Project>
      

      后臺(tái) C# 代碼的按鈕點(diǎn)擊事件里面將調(diào)用 SHOpenFolderAndSelectItems 方法打開(kāi)資源管理器選中輸入的文件

          private void Button_OnClick(object sender, RoutedEventArgs e)
          {
              var filePath = InputTextBox.Text;
              filePath = System.IO.Path.GetFullPath(filePath);
      
              IntPtr pidlList = ILCreateFromPathW(filePath);
              if (pidlList != IntPtr.Zero)
              {
                  try
                  {
                      Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0));
                  }
                  finally
                  {
                      ILFree(pidlList);
                  }
              }
          }
      
      

      以上代碼里面的 ILCreateFromPathW 要求傳入絕對(duì)路徑,需要調(diào)用 System.IO.Path.GetFullPath 方法轉(zhuǎn)換傳入路徑為絕對(duì)路徑

      如果不知道代碼如何寫的話,可以拉取我的例子項(xiàng)目代碼跑跑看

      本文代碼放在 githubgitee 上,可以使用如下命令行拉取代碼。我整個(gè)代碼倉(cāng)庫(kù)比較龐大,使用以下命令行可以進(jìn)行部分拉取,拉取速度比較快

      先創(chuàng)建一個(gè)空文件夾,接著使用命令行 cd 命令進(jìn)入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼

      git init
      git remote add origin https://gitee.com/lindexi/lindexi_gd.git
      git pull origin 6988631e41226832c3b83cf62529eb7d7892e0b2
      

      以上使用的是國(guó)內(nèi)的 gitee 的源,如果 gitee 不能訪問(wèn),請(qǐng)?zhí)鎿Q為 github 的源。請(qǐng)?jiān)诿钚欣^續(xù)輸入以下代碼,將 gitee 源換成 github 源進(jìn)行拉取代碼。如果依然拉取不到代碼,可以發(fā)郵件向我要代碼

      git remote remove origin
      git remote add origin https://github.com/lindexi/lindexi_gd.git
      git pull origin 6988631e41226832c3b83cf62529eb7d7892e0b2
      

      獲取代碼之后,進(jìn)入 WPFDemo/WilinojearcheWheyecearhire 文件夾,即可獲取到源代碼

      更多一些細(xì)節(jié)信息是調(diào)用 SHOpenFolderAndSelectItems 之前請(qǐng)確保已經(jīng)初始化 COM 組件,即調(diào)用過(guò) CoInitialize 方法。在 WPF 里面為了和 DirectX 等交互,在按鈕點(diǎn)擊之前就已經(jīng)調(diào)研過(guò)了 COM 初始化了,因此在 WPF 里面可以省略此邏輯。但是在控制臺(tái)應(yīng)用里面,需要手動(dòng)調(diào)用一下,代碼如下

      CoInitialize(0, 0);
      
          [LibraryImport("Ole32.dll")]
          private static partial int CoInitialize(IntPtr pvReserved, uint dwCoInit);
      

      我再次更新 WPF 例子項(xiàng)目的代碼,在按鈕點(diǎn)擊的方法里面調(diào)用。不過(guò)在按鈕點(diǎn)擊方法里面調(diào)用是必然返回失敗的,如上文所述,這是因?yàn)?WPF 早已初始化過(guò)了。好在這個(gè)方法失敗了也沒(méi)有什么問(wèn)題,可以放心調(diào)用

          private void Button_OnClick(object sender, RoutedEventArgs e)
          {
              // 必定返回失敗,因?yàn)?WPF 已經(jīng)調(diào)用過(guò)了
              var result = CoInitialize(0, 0);
      
              ... // 忽略其他代碼
          }
      

      根據(jù) SHOpenFolderAndSelectItems 文檔如下描述,如果沒(méi)有先調(diào)用 CoInitialize 則會(huì)失敗

      CoInitialize or CoInitializeEx must be called before using SHOpenFolderAndSelectItems. Not doing so causes SHOpenFolderAndSelectItems to fail.

      SHOpenFolderAndSelectItems 選中多個(gè)文件

      有時(shí)候咱的需求是打開(kāi)文件夾,選中里面多個(gè)文件,此時(shí)依然可以使用 SHOpenFolderAndSelectItems 方法,只是咱需要修改一下剛才的函數(shù)簽名。修改之后的代碼如下

      // 修改前:
          [LibraryImport("shell32.dll")]
          private static partial int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
      
      // 修改后:
          [LibraryImport("shell32.dll")]
          private static partial int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] children, uint dwFlags);
      

      可以看到修改后的差別只是將 children 參數(shù)的類型修改為 IntPtr[] 指針數(shù)組類型,且標(biāo)記了作為 LPArray 方式傳入而已。如果不想改的話,那也可以自己使用 System.Runtime.InteropServices.Marshalling.ArrayMarshaller<nint, nint>.ManagedToUnmanagedIn 的 GetPinnableReference 方法將指針數(shù)組轉(zhuǎn)換為指針傳入。只不過(guò)此時(shí)的指針對(duì)應(yīng)在 C 的定義是指針的指針而已

      選中多個(gè)文件的使用方法就是在 pidlList 參數(shù)傳入多個(gè)文件所在的文件夾,在 children 參數(shù)里面?zhèn)魅胄枰x中的文件

      傳入的這些路徑都需要經(jīng)過(guò) ILCreateFromPathW 處理,以下是我修改之后的按鈕點(diǎn)擊事件代碼,可以全選文件夾里面的所有文件

          private void Button_OnClick(object sender, RoutedEventArgs e)
          {
              // 必定返回失敗,因?yàn)?WPF 已經(jīng)調(diào)用過(guò)了
              var result = CoInitialize(0, 0);
      
              var folderPath = InputTextBox.Text;
      
              folderPath = System.IO.Path.GetFullPath(folderPath);
      
              IntPtr pidlList = ILCreateFromPathW(folderPath);
      
      
              if (pidlList != IntPtr.Zero)
              {
                  var fileList = Directory.GetFiles(folderPath);
      
                  var selectedFileList = new IntPtr[fileList.Length];
      
                  for (var i = 0; i < fileList.Length; i++)
                  {
                      var file = fileList[i];
                      selectedFileList[i] = ILCreateFromPathW(file);
                  }
      
                  try
                  {
                      // Open parent folder and select item
                      Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, (uint) fileList.Length, selectedFileList, 0));
                  }
                  finally
                  {
                      ILFree(pidlList);
      
                      foreach (var nint in selectedFileList)
                      {
                          ILFree(nint);
                      }
                  }
              }
          }
      
          [LibraryImport("Ole32.dll")]
          private static partial int CoInitialize(IntPtr pvReserved, uint dwCoInit);
      
          [LibraryImport("shell32.dll")]
          private static partial void ILFree(IntPtr pidlList);
      
          [LibraryImport("shell32.dll", StringMarshalling = StringMarshalling.Utf16)]
          private static partial IntPtr ILCreateFromPathW(string pszPath);
      
          [LibraryImport("shell32.dll")]
          private static partial int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] children, uint dwFlags);
      

      嘗試替換以上代碼到項(xiàng)目里,運(yùn)行項(xiàng)目即可進(jìn)行測(cè)試打開(kāi)資源管理器選中輸入的文件夾的所有文件

      那如果需要選中多個(gè)文件夾呢?自然只需將以上代碼的 fileList 替換為文件夾列表就可以了。在 SHOpenFolderAndSelectItems 的 children 參數(shù)里面可以的內(nèi)容是傳入文件或文件夾。可以混合多選多個(gè)文件和文件夾同時(shí)

      參考文檔

      c# - How to open Explorer with a specific file selected? - Stack Overflow

      file - C#: How to use SHOpenFolderAndSelectItems - Stack Overflow

      c#: 打開(kāi)文件夾并選中文件 - 楚人無(wú)衣 - 博客園

      SHOpenFolderAndSelectItems 函數(shù) (shlobj_core.h) - Win32 apps - Microsoft Learn

      【C#】在Windows資源管理器打開(kāi)文件夾,并選中指定的文件或文件夾 - Tod's - 博客園

      CoInitializeEx 函數(shù) (combaseapi.h) - Win32 apps Microsoft Learn

      SHOpenFolderAndSelectItems function (shlobj_core.h) - Win32 apps Microsoft Learn

      更多 WPF 博客,請(qǐng)參閱 博客導(dǎo)航

      posted @ 2024-11-16 07:31  lindexi  閱讀(383)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 蜜桃AV抽搐高潮一区二区| 深夜精品免费在线观看| 国产黄色一区二区三区四区| 亚洲护士一区二区三区| 国产精品一区二区小视频| 亚洲国产精品久久久久秋霞 | 久久亚洲中文字幕伊人久久大| 久久这里有精品国产电影网| 亚洲欧美在线一区中文字幕| 国产欧美日韩亚洲一区二区三区| 内射少妇一区27p| 国产精品爽爽va在线观看网站 | 国产熟女一区二区五月婷| 奇米777四色成人影视| 湾仔区| 成人爽a毛片免费| 四虎永久免费高清视频| 成人亚洲综合av天堂| 国产最新精品系列第三页| 亚洲午夜无码久久久久蜜臀AV| 精品国产迷系列在线观看| 国内少妇人妻偷人精品视频| 国产在线观看码高清视频| 久久人与动人物a级毛片| 日韩区中文字幕在线观看| 精品中文人妻在线不卡| 精品偷拍被偷拍在线观看| 国产精品一区二区色综合| 中文字幕在线日韩一区| 日本精品极品视频在线| 久久精品久久精品久久精品| 国产午夜成人久久无码一区二区| 99www久久综合久久爱com| 亚洲二区中文字幕在线| 亚洲人成色77777在线观看| 国产一二三五区不在卡| 99在线精品国自产拍中文字幕| 湖口县| 国产精品亚洲综合色区丝瓜| 亚洲AV无码久久精品成人| 久久青青草原精品国产app|