Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to launch the associated application for a file / directory / URL?

Linux seems to be easy: xdg-open <file/directory/URL>.

Apparently, Mac is similar: open should be used instead of xdg-open. I don't have access to a Mac so I couldn't test it.

For Windows, I found 4 different suggestions and those that I have tried failed.

  • Is there a non-java, cross platform way to launch the associated application for a certain file type? suggests
    start

  • How to give focus to default program of shell-opened file, from Java? suggests
    cmd /c start ...

  • How to open user system preferred editor for given file?
    How to Find Out Default File Opener with Java? suggest
    RUNDLL32.exe

  • What is the correct way to use ShellExecute() in C to open a .txt
    Open file with Windows' native program within C++ code
    How to use ShellExecute to open html files in Windows using C++? suggest
    ShellExecute

I have tried the first 3 with system() and QProcess::startDetached() and "http://www.stackoverflow.com" as argument but they all failed; start works just fine from the command line though. I haven't tried ShellExecute yet.

What is the Windows equivalent of xdg-open? It seem to me, it is start but why did my attempts with start fail?

Is ShellExecute my only option?


EDIT I thought QDesktopServices::openUrl() was for web pages only because it did not work for files or directories.

After some debugging I figured out that if I replace \\ with / in the path on Windows, it works for files but the directories are still not opened. Any ideas what I am doing wrong?

QDir dir("C:/Documents and Settings/ali");

qDebug() << "Exists? " << dir.exists();

qDebug() << dir.absolutePath();

QDesktopServices::openUrl(QUrl(dir.absolutePath()));

qDebug() << "External app called";

Application Output:

Exists?  true 
"C:/Documents and Settings/ali" 
External app called 

But nothing happens, the directory is not opened. On Linux, directories are opened with the default file manager as expected.


SOLUTION: Due to the Qt bug and Windows quirks (malformed application window), I ended up using ShellExecute. That gives me enough flexibility to achieve exactly what I want at some expense...

like image 302
Ali Avatar asked Dec 07 '12 16:12

Ali


People also ask

How do I launch a Windows application from the launch file?

Call the Windows.System.Launcher.LaunchFileAsync (IStorageFile, LauncherOptions) method with LauncherOptions.DisplayApplicationPicker set to true to launch the app that the user selects from the Open With dialog box.

How do I associate a file with a program in Windows?

In Control Panel, search for Default Programs and open the icon. Click the Associate a file type or protocol with a program option. Locate the file extension you want to modify and highlight it. Click the Change program button. Select the program you want to associate and open the file extension and click OK.

What is launchfileasync and how does it work?

Source apps that call LaunchFileAsync can request that they remain on screen after a file launch. By default, Windows attempts to share all available space equally between the source app and the target app that handles the file.

How do I set default apps by file type in Windows?

In Control Panel, search for Default Programs and click the icon. Click the Associate a file type or protocol with a program option. In the Default apps window, scroll to the bottom and click the Choose default apps by file type option.


1 Answers

Why don't you just use Qt's support for this? For example:

QDesktopServices::openUrl(QUrl("/home/realnc/test.pdf"));

This opens the document in Acrobat Reader. In general, it obeys the preferred application settings in my OS for all file types that have one or more applications associated with them. Best of all, it's platform-independent.

Edit: The fact that it opens directories on Linux but not on Windows smells like a bug. It might be best to report this on Qt's bug tracker. In the meantime, you could have a workaround for Windows for when the file is a directory:

#ifdef Q_WS_WIN
    if (QFileInfo(path).isDir())
        QProcess::startDetached("explorer", QStringList(path));
    else
#endif
        QDesktopServices::openUrl(QUrl(path));

You can also do it with cmd.exe's start command, but you'll get an ugly terminal pop up for a few fractions of a second:

QProcess::startDetached("cmd", QStringList() << "/C" << "start"
                               << QDir::toNativeSeparators(path));
like image 157
Nikos C. Avatar answered Oct 12 '22 14:10

Nikos C.