【问题标题】:How to open Explorer with a specific file selected?如何在选择特定文件的情况下打开资源管理器?
【发布时间】:2012-11-20 18:02:04
【问题描述】:

我想编写一个可以传递文件路径的函数,例如:

C:\FOLDER\SUBFOLDER\FILE.TXT

它会使用包含该文件的文件夹打开 Windows 资源管理器,然后在该文件夹中选择该文件。 (类似于许多程序中使用的“在文件夹中显示”概念。)

我该怎么做?

【问题讨论】:

标签: c# winapi vbscript


【解决方案1】:

跟进@Mahmoud Al-Qudsi 的回答。当他说“启动流程”时,这对我有用:

// assume variable "path" has the full path to the file, but possibly with / delimiters
for ( int i = 0 ; path[ i ] != 0 ; i++ )
{
    if ( path[ i ] == '/' )
    {
        path[ i ] = '\\';
    }
}
std::string s = "explorer.exe /select,\"";
s += path;
s += "\"";
PROCESS_INFORMATION processInformation;
STARTUPINFOA startupInfo;
ZeroMemory( &startupInfo, sizeof(startupInfo) );
startupInfo.cb = sizeof( STARTUPINFOA );
ZeroMemory( &processInformation, sizeof( processInformation ) );
CreateProcessA( NULL, (LPSTR)s.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation );

【讨论】:

    【解决方案2】:

    自 Windows XP(即 Windows 2000 或更早版本不支持)以来,支持方法是SHOpenFolderAndSelectItems

    void OpenFolderAndSelectItem(String filename)
    {
       // Parse the full filename into a pidl
       PIDLIST_ABSOLUTE pidl;
       SFGAO flags;
       SHParseDisplayName(filename, null, out pidl, 0, out flags);
       try 
       {
          // Open Explorer and select the thing
          SHOpenFolderAndSelectItems(pidl, 0, null, 0);
       }
       finally 
       {
          // Use the task allocator to free to returned pidl
          CoTaskMemFree(pidl);
       }
    }
    

    【讨论】:

      【解决方案3】:

      不使用 Win32 shell 函数的最简单方法是使用 /select 参数简单地启动 explorer.exe。比如启动进程

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

      将打开一个新的资源管理器窗口到 C:\Folder\subfolder 并选择 file.txt。

      如果您希望在不启动新进程的情况下以编程方式执行此操作,则需要使用 shell 函数 SHOpenFolderAndSelectItems,这是 explorer.exe 的 /select 命令将在内部使用的。请注意,这需要使用 PIDL,如果您不熟悉 shell API 的工作原理,则可以成为真正的 PITA。

      这是/select 方法的完整的程序化实现,感谢@Bhushan 和@tehDorf 的建议,并进行了路径清理:

      public bool ExploreFile(string filePath) {
          if (!System.IO.File.Exists(filePath)) {
              return false;
          }
          //Clean up file path so it can be navigated OK
          filePath = System.IO.Path.GetFullPath(filePath);
          System.Diagnostics.Process.Start("explorer.exe", string.Format("/select,\"{0}\"", filePath));
          return true;
      }
      

      参考:Explorer.exe Command-line switches

      【讨论】:

      • 选择后需要一个逗号,例如 explorer.exe /select, "c:\folder\subfolder\file.txt
      • 启动一个新进程有什么缺点?
      • @Gusdor 没什么,真的。除非您在文件夹视图选项中的单独进程中启用了已启动的文件夹窗口(默认情况下,它已禁用),否则这实际上不会启动新进程。它通过动作,但将调用现有的 explorer.exe 实例来处理请求,而不是在单独的内存空间中启动新进程。不过,如果您经常调用此代码,那么在打开序列期间使用SHOpenFolderAndSelectItems 肯定会更高效且浪费更少。
      • @MahmoudAl-Qudsi 您可以使用filePath = System.IO.Path.GetFullPath(filePath);,而不是使用Regex 来清理文件路径。它将规范化目录分隔符,它还将解析相对路径,例如如果您传入 @"..\some\relative\file\path.txt"@"C:\Some\relative\..\file\path.txt" 之类的内容。您还可以更新示例以使用新的字符串插值:Process.Start("explorer.exe", $"/select,\"{filePath}\"");
      • 如果文件名本身包含逗号,这似乎不起作用。
      【解决方案4】:

      执行命令时,如果路径包含多个斜杠,则不会打开文件夹并正确选择文件 请确保您的文件路径应该是这样的

      C:\a\b\x.txt

      而不是

      C:\\a\\b\\x.txt

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-24
        • 2012-02-14
        • 2011-05-24
        • 2014-06-25
        • 1970-01-01
        • 2020-05-10
        • 2012-05-05
        相关资源
        最近更新 更多