如何选择特定文件打开资源管理器?

时间:2012-12-03 09:33:04

标签: c# winapi vbscript

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

C:\FOLDER\SUBFOLDER\FILE.TXT

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

我该怎么做?

4 个答案:

答案 0 :(得分:94)

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

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

将打开一个新的资源管理器窗口到C:\ Folder \子文件夹,并选择了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

答案 1 :(得分:3)

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

<强> C:\ A \ B \ x.txt

而不是

<强> C:\\一个\\ b \\ x.txt

答案 2 :(得分:0)

自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 :(得分:0)

跟进@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 );