How to open/spawn a file with glib/gtkmm in Windows

£可爱£侵袭症+ 提交于 2020-01-05 05:27:15

问题


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:


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:


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.



来源:https://stackoverflow.com/questions/42442189/how-to-open-spawn-a-file-with-glib-gtkmm-in-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!