3

In my application, I generate a HTML file that I want to open by clicking on a button. So my file is named, for example:

QString file = "F:/the_path/to_the_/generated_html_file.html";

On Windows I change it to:

file = "file:///F:/the_path/to_the_/generated_html_file.html";

so that I can open it with :

QDesktopServices::openUrl(QUrl(file));

and it opens in the default browser.

But when the character # is present in the path or file name, it doesn't work any more and it seems that the URL is truncated just after the #.

For example, if I name the file generated#_html_file.html, I get this error message:

ShellExecute 'F:/the_path/to_the_/generated' failed (error 2).

Why does that happen, and how can I avoid it?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
SteveTJS
  • 635
  • 17
  • 32

2 Answers2

12

In a URL, # is a character that delimits the 'fragment identifier' from the resource location. To reference a file: URL with a literal #, it needs to be escaped (as %23).

Reference: RFC 1738:

The character "#" is unsafe and should always be encoded because it is used in World Wide Web and in other systems to delimit a URL from a fragment/anchor identifier that might follow it.

As noted by SteveTJS, the static method QUrl::fromLocalFile() is provided for this purpose, so you can write

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

instead of

QDesktopServices::openUrl(QUrl(file));

This will

  1. Prepend the file: protocol identifier and // empty hostname
  2. Convert native path separator to / (if different)
  3. Encode any non-safe characters for URL.
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • Indeed, I posted my answer at the same time. The function QUrl::fromLocalFile(...) does the work. – SteveTJS Jul 22 '15 at 13:05
  • @Steve - quite right, I don't use `QUrl` very much, so I'd forgotten that. I've upvoted your answer, and will add a note to mine. – Toby Speight Jul 22 '15 at 14:14
6

I just found the solution:

QString file = "F:/the_path/to_the_/generated#_html_file.html";
QUrl url = QUrl::fromLocalFile(file);
// gives url="file:///F:/the_path/to_the_/generated%23_html_file.html";
QDesktopServices::openUrl(url); //works
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
SteveTJS
  • 635
  • 17
  • 32