1

I've already tried:

  GError *pError = NULL;
  string uri = g_filename_to_uri(file.c_str(), NULL, &pError);
  if (!g_app_info_launch_default_for_uri(uri.c_str(), NULL, &pError)) {
      cout << "Failed to open uri: " << pError->message;
  }

Here I get the error "URIs not supported". Is the uri I create here wrong?

My second approach was to spawn the file with an asynchronous command line:

  file = quoteStr(file);
  try {
    Glib::spawn_command_line_async(file);
  } catch (Glib::SpawnError error) {
    cout << error.what();
  } catch (Glib::ShellError error) {
    cout << error.what();
  }

Here the Glib::SpawnError exception is thrown with the error: "Failed to execute helper program (Invalid argument)". I mean, when I execute the quoted absolute file path in the Windows cmd, it opens the file (in this case a pdf file). Does this function work different?

1
  • Is the uri I create here wrong? Impossible to say without you showing us that URI... But for your 2nd problem, see my answer; I suspect you need to have the gspawn helper executable in your path or in the same directory as your own executable. Certainly, that fixed the same problem for me. Commented Jul 28, 2017 at 11:45

2 Answers 2

1

Hopefully this is related and can provide a real answer rather than just a (clever!) workaround.

I ran into a strange situation: Launching a file (specifically an HTML document) by g_app_info_launch_default_for_uri() or gtk_show_uri_on_window() worked when the executable was run from my build directory. However, it did not work if I copied the exe to another directory (for distribution) and ran it from there.

In the latter case, I got the same error as your 2nd quote:

Failed to execute helper program (Invalid argument)

The build directory is not in my path, and nor is it special for any other reason (it's in a temp RAM drive). So I was completely baffled.

I then thought about that error... What helper program could it possibly be talking about?

And why might that program be found when running from the build directory? Well, my build uses a libtool wrapper, and that puts a bunch of things in the path, so that we don't need to copy all the DLLs etc in just to test builds.

So, I went to investigate whether there was anything relevant-looking in paths that might be searched by the MSYS2 shell and its libtool wrapper. The prime suspect, of course, is C:\msys64\mingw64\bin. And look what I found there:

gspawn-win64-helper-console.exe

After copying this executable to the directory from which my application is launched, my program now successfully launches the URI, regardless of which folder its executable currently resides in.

Edit

After updating my packages in MSYS2, it was back to the same error - as it seems now this is the helper that is required:

gspawn-win64-helper.exe

That actually makes more sense, since my application is graphical, not console. I guess maybe something changed here recently. You could distribute both to be extra safe.

Sign up to request clarification or add additional context in comments.

Comments

-2

I had a similar problem and I had to give up using glib to do that and ended up implementing a simple crossplatform (win, mac and linux) compatible way to do it:

// open an URI, different for each operating system
void
openuri(const char *url)
{
#ifdef WIN32
    ShellExecute(GetActiveWindow(),
         "open", url, NULL, NULL, SW_SHOWNORMAL);
#elif defined(__APPLE__)
    char buffer[512];
    ::snprintf(buffer, sizeof(buffer), "open %s", url);
    ::system(buffer);
#else
    char buffer[512];
    ::snprintf(buffer, sizeof(buffer), "xdg-open %s", url);
    ::system(buffer);
#endif
}

... it's not very nice but it's small and it works :)

2 Comments

Yes that works too ofc, but I did want to use that only as the last way. Still thanks for the sample!
This will introduce arbitrary shell code execution vulnerabilities into your application (from the url, which is not escaped) and should not be used. In general, the system() syscall should be avoided at all costs; there are few generally applicable situations where it can easily be used safely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.