6

I have an update function in my app - it downloads and verifies the installer (a setup.exe, created with NSIS). To actually kick off the update, I have simply been doing:

QString path = .. absolute path to the downloaded file ...
QProcess::startDetached(path, QStringList());

This works fine on XP - but on Vista and Win7, nothing happens once the download completes. If I browse to the downloaded update and run it manually, it works fine. I assume what's happening is that UAC is blocking the installer at CreateProcess time, but this is where my knowledge runs out.

Additional complication - when I'm running a debug build from the command line, the steps above work - I get the UAC prompt and can run the installer. It's the release builds, started form the start menu/shortcut, which have the issue - I assume there's a difference in the auth token when running from a command shell.

James Turner
  • 2,425
  • 2
  • 19
  • 24

4 Answers4

7

You can also use

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

Might be surprising and counterintuitive, but it works and is more cross-platform

Andro Selva
  • 53,910
  • 52
  • 193
  • 240
sierdzio
  • 71
  • 1
  • 2
  • Awesome solution. This actually call ShellExecute in the background. The only problem I see is that it does not bring the UAC window to the top – Daniel Georgiev Oct 07 '15 at 11:23
3

If you are not admin and you call CreateProcess() on a .exe with a "Vista" manifest (or no manifest, but a .exe that windows detects as an installer (This includes NSIS)) the call fails, you need to use ShellExecute[Ex](). ShellExecute will trigger UAC prompt if required...

Anders
  • 97,548
  • 12
  • 110
  • 164
2

This seems to be a Qt bug, see QTBUG-9761 , the correct workaround is to use ShellExecute with lpOperation set to runas.

ismail
  • 46,010
  • 9
  • 86
  • 95
  • Using the runas verb will _force_ UAC elevation, if you don't specify a verb, ShellExecute will figure it out on its own... – Anders Dec 26 '10 at 20:18
1

Another alternative is to prepend your execution with cmd.exe /C. This effectively routes your execution through the shell, so you do get the UAC prompt. The downside is that if your process fails you probably won't get as much information had you gone through ShellExecute[Ex], but on the plus side you will get all the facilities of QProcess that you miss if you use QDesktopServices::openUrl, where you have no idea if things worked or not.

Tim Angus
  • 983
  • 11
  • 26