如何“在 Finder 中显示"或“在资源管理器中显示"与 Qt

2021-12-09 00:00:00 qt4 qt c++

是否可以在 Windows 资源管理器/OS X Finder 中打开一个文件夹,然后选择/突出显示该文件夹中的一个文件,并以跨平台方式执行此操作?现在,我做类似的事情

Is it possible to open a folder in Windows Explorer/OS X Finder and then select/highlight one file in that folder, and do it in a cross platform way? Right now, I do something like

QDesktopServices::openUrl( QUrl::fromLocalFile( path ) );

其中 path 是我要打开的文件夹的完整路径.显然,这只会打开文件夹,我必须手动追踪我需要的文件.当该文件夹中有数千个文件时,这有点问题.

where path is a full path to folder I want to open. Obviously, this will just open the folder, and I'll have to track down the file I need manually. This is a bit of a problem when there are thousands of files in that folder.

如果我将其设置为该文件夹中特定文件的路径,则该文件将使用该 MIME 类型的默认应用程序打开,这不是我所需要的.相反,我需要相当于在 Finder 中显示"或在资源管理器中显示"的功能.

If I make it a path to specific file in that folder, then that file is open with default application for that mime type, and that is not what I need. Instead, I need the functionality equivalent to "Reveal in Finder" or "Show in Explorer".

推荐答案

Qt Creator (source)这个功能,简单复制一下:

Qt Creator (source) has this functionality, it's trivial to copy it:

void FileUtils::showInGraphicalShell(QWidget *parent, const QString &pathIn)
{
    const QFileInfo fileInfo(pathIn);
    // Mac, Windows support folder or file.
    if (HostOsInfo::isWindowsHost()) {
        const FileName explorer = Environment::systemEnvironment().searchInPath(QLatin1String("explorer.exe"));
        if (explorer.isEmpty()) {
            QMessageBox::warning(parent,
                                 QApplication::translate("Core::Internal",
                                                         "Launching Windows Explorer Failed"),
                                 QApplication::translate("Core::Internal",
                                                         "Could not find explorer.exe in path to launch Windows Explorer."));
            return;
        }
        QStringList param;
        if (!fileInfo.isDir())
            param += QLatin1String("/select,");
        param += QDir::toNativeSeparators(fileInfo.canonicalFilePath());
        QProcess::startDetached(explorer.toString(), param);
    } else if (HostOsInfo::isMacHost()) {
        QStringList scriptArgs;
        scriptArgs << QLatin1String("-e")
                   << QString::fromLatin1("tell application "Finder" to reveal POSIX file "%1"")
                                         .arg(fileInfo.canonicalFilePath());
        QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
        scriptArgs.clear();
        scriptArgs << QLatin1String("-e")
                   << QLatin1String("tell application "Finder" to activate");
        QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
    } else {
        // we cannot select a file here, because no file browser really supports it...
        const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.filePath();
        const QString app = UnixUtils::fileBrowser(ICore::settings());
        QProcess browserProc;
        const QString browserArgs = UnixUtils::substituteFileBrowserParameters(app, folder);
        bool success = browserProc.startDetached(browserArgs);
        const QString error = QString::fromLocal8Bit(browserProc.readAllStandardError());
        success = success && error.isEmpty();
        if (!success)
            showGraphicalShellError(parent, app, error);
    }
}

另一篇相关的博文(代码比较简单,我没试过所以无法评论),是这个.

Another, related blog post (with simpler code, I haven't tried it so I can't comment), is this.

Windows 上 pathIn 包含空格时,原始代码中存在错误.QProcess::startDetached 会自动引用包含空格的参数.但是,Windows 资源管理器不会识别用引号括起来的参数,而是会打开默认位置.在 Windows 命令行中自行尝试:

There is a bug in the original code when pathIn contains spaces on Windows. QProcess::startDetached will automatically quote a parameter if it contains spaces. However, Windows Explorer will not recognize a parameter wrapped in quotes, and will open the default location instead. Try it yourself in the Windows command line:

echo. > "C:a file with space.txt"
:: The following works
C:Windowsexplorer.exe /select,C:a file with space.txt  
:: The following does not work
C:Windowsexplorer.exe "/select,C:a file with space.txt"

因此,

QProcess::startDetached(explorer, QStringList(param));

改为

QString command = explorer + " " + param;
QProcess::startDetached(command);

相关文章