使用C ++代码中的Windows本机程序打开文件

时间:2011-02-26 13:47:48

标签: c++ windows explorer graphviz windows-explorer

我的C ++程序创建.png文件,我需要在创建后立即打开(查看)此文件 - 有没有办法打开它,因为它是在 Windows资源管理器中打开的 - 所以文件wiil使用用户的首选程序打开,如果没有与文件格式相关的程序 - Windows将显示对话窗口,用户可以在其中选择任何程序打开该文件。

Crossplatform(+ Linux,+ MacOS,+ BSD)解决方案将是完美的。

感谢。

3 个答案:

答案 0 :(得分:7)

在Windows上,您可以使用ShellExecute function

答案 1 :(得分:4)

如果您使用Qt开发跨平台应用程序,那么QDesktopServices::openUrl() method将完成这项工作。它当然是跨平台的,就像Qt中的所有内容一样。

由于您已经在使用wxWidgets,因此使用Qt打开文件显然是一种过度杀伤力。由于wxWidgets主要是GUI的东西,它可能没有这样的东西,虽然我不能确定,因为我自己从未使用它。

但是,如果你想以跨平台的方式做到这一点,这就是Qt为Windows做的:

quintptr returnValue = (quintptr)ShellExecute(0, 0,
  (wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL);
// ShellExecute returns a value greater than 32 if successful
return (returnValue > 32);

这里,filePath.utf16()是Unicode以null结尾的文件路径。

以下是X11 / Unix的相关部分:

if (launch(url, QLatin1String("xdg-open")))
    return true;
if (X11->desktopEnvironment == DE_GNOME 
    && launch(url, QLatin1String("gnome-open"))) {
    return true;
} else {
    if (X11->desktopEnvironment == DE_KDE 
        && launch(url, QLatin1String("kfmclient exec")))
        return true;
}
if (launch(url, QLatin1String("firefox")))
    return true;
if (launch(url, QLatin1String("mozilla")))
    return true;
if (launch(url, QLatin1String("netscape")))
    return true;
if (launch(url, QLatin1String("opera")))
    return true;
return false;

这里,launch()函数基本上启动指定的应用程序,并将URL传递给它。不仅仅是文件路径,比如Windows,还有像file:///home/user/tmp/file.doc这样的完整网址。但不确定这是否重要。它还会在将URL传递给程序之前对URL中的所有非ASCII字符进行百分比编码。不确定openDocument()尝试的所有程序是否重要。我已使用xdg-open对其进行了测试,并不关心它是否为百分比编码。

以下是检测桌面环境并相应设置X11->desktopEnvironment的部分:

    X11->desktopEnvironment = DE_UNKNOWN;
    Atom type;
    int format;
    unsigned long length, after;
    uchar *data = 0;
    int rc;
    do {
        if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
            X11->desktopEnvironment = DE_KDE;
            break;
        }
        if (qgetenv("DESKTOP_SESSION") == "gnome") {
            X11->desktopEnvironment = DE_GNOME;
            break;
        }
        // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
        if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
            X11->desktopEnvironment = DE_GNOME;
            break;
        }
        rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
                                0, 2, False, XA_STRING, &type, &format, &length,
                                &after, &data);
        if (rc == Success && length) {
            if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
                // Pretend that xfce4 is gnome, as it uses the same libraries.
                // The detection above is stolen from xdg-open.
                X11->desktopEnvironment = DE_GNOME;
                break;
            }
            // We got the property but it wasn't xfce4. Free data before it gets overwritten.
            XFree(data);
            data = 0;
        }
    } while(0);
哇,那是件好事。我删除了检测其他环境的部分,因为它们未在openDocument()中使用。

最后,这是openDocument()的光荣Mac版本:

// LSOpen does not work in this case, use QProcess open instead.
return QProcess::startDetached(QLatin1String("open"), QStringList() << file.toLocalFile());

真的?而已?哇,毕竟Mac平台一定有东西。这里,QProcess :: startDetached()只是启动一个新进程,将文件路径作为参数传递。它在很大程度上等同于system()调用,但不等待进程终止。不确定这是否重要,我不知道如何在不使用QProcess的情况下在Mac上进行操作,因为我从未见过Mac。

答案 2 :(得分:1)

以下是从应用程序打开位图的示例:

ShellExecute(   GetSafeHwnd(),
                      _T("open"),
                      "Test.bmp",
                      NULL,
                      NULL,
                      SW_SHOW);

对于跨平台版本,如果您谷歌查询您的请求,您将找到大量信息。

再见