Well, i have a QProcess that works as my program updater, but on Windows you CAN'T modify exe files when they're running, but if you close the program that created the Updater process i suppose that the Updater closes too. It's possible to make the Updater process independent?
Then, on Windows Vista (and later) it's impossible to run my updater because it returns that i need to elevate my level to administrator, It is possible to elevate the permissions for the process?
First of all, in opposite to Linux, Windows processes are independent from their parents by default and would not be closed after parent process closes.
Right way to solve your problem would be making your updater a Windows service. Then, it wouldn't be launched by application and it will have privileges to write to system folders etc. (see here)
Here is library for services support in Qt (and it actually works).
If you want simpler solution, you can use ShellExecute to escalate privileges to launch your updater.
Related
If I run a Qt application directly from the Windows command-line (cmd), it immediately returns back to the shell even as the GUI continues running; I assume it creates a second process before the parent exits.
If I run the Qt application indirectly though, from a batch file or Python script, it doesn't behave the same way; it blocks until the application actually exits:
Is this standard Qt behavior? I can't find any mention of it in the documentation or anywhere else. Can it be customized? I would prefer that the application always block when run from the command-line.
This is NORMAL Windows behavior.
In a console console programs are waited on. GUI programs are not. The rules are specified in start /?(mention of new behavior is NT4 to Windows 2000).
So Start /w c:\windows\notepad.
I have a simple application using
QT += core gui network webkitwidgets
I've used windeployqt.exe to generate the 32 bits release on my win-10 64 bit computer. When I put the folder on a win-7 64 Bit desktop and double-click the app.exe, it never starts.
I can see it in the task manager, but I can't kill it, and if I try I cannot close the explorer folder in which I double clicked anymore.
I've checked the usual platform, ICU, qwindows.dll, and so on.
http://doc.qt.io/qt-5/windows-deployment.html
EDIT Precisions:
I've compiled with default 32 Bit kit: "build-Test-Desktop_Qt_5_5_1_MinGW_32bit-Release" with "mingw492_32"
I have a package "release" generated by windeployqt.exe using the --webkit switch. I start a command prompt:
> set path=
> set mingw=
Then I make sure that no Qt/Mingw things exists anymore in my environment variables.
I also rename "c:\Qt" into "c:\ __Qt".
I move my release folder on my desktop.
I start release\test.exe ( from the clean path shell )
Everything runs fine! So The release/test.exe has everything it needs without the path/mingw variable.
But as soon as I put the folder on another windows machine ( 7 instead of 10 ) it never starts.
I tried dependency walker. It shows a lot of "API-MS-WIN*.dll" missing...
It even shows much more missing dlls on the "good" machine than on the bad one !!!
Every single "missing dll" on the "bad" target machine is actually in system32 on this machine.
Thanks for advice, every advice is welcome, I'm a bit desperate... :)
Edit
It seems to be related to the machine itself. I have successfully deployed this (very small) app to 2 non developer machine on win7 and win8 respectively. But the above "bad machine" still resits running it...
Edit
The problem seems not to be general but related to this one particular machine. Hence, feel free to close or move to the appropriate forum as it is not related to Qt/windeplyqt. If I figure out a solution, and question is closed, I'll simply add a last edit. Safe Boot and malwarebyte are my next actions.
After a long investigation.
Do not believe dependency walker, it used to be a top notch tool but it is now outdated.
If there is a missing dll, the system will prompt you with "cannot load dll xxx.dll" anyway.
Your best shot in case a soft runs on machine X but not on Machine Y is:
start in safe mode ( run: msconfig --> diagnostic startup )
turn off any antivirus or non microsoft/driver software,
"run as administrator".
If you can run with step 3. Then proceed by elimination:
run without admin rights,
Start anti spyware, etc...
Add appropriate exception to your antivirus if it is the root cause.
If the antivirus is not the root cause, run process monitor on both machines. Then compare, what Failed on one machine and not the other ? Read the windows event log and compare any error messages on both machines.
run sfc /scannow to check disk
run a complete anti spyware scan/ pc-repair tool ( malwarebytes, combofix, ... )
Make sure you really have the very same package on both machines, make sure you are not trying to run an exe on mac OS, make sure your computer is on.
Call the oracle, you are in the matrix...
In my case the problem was Avast and it was solved by adding appropriate exception.
I'm looking for a way to develop some Unix scripts that will connect to a DOS box (Windows server 2012) and interactively execute DOS commands.
I'm comfortable with the Unix side (I'll almost certainly use Expect), but I'm "Windows illiterate" and am unable to find anything about connecting to Windows's DOS command line in this fashion. Is this even possible to do?
(FWIW, this is to enable us to control Tableau Server using its 'tabcmd' DOS command suite from our existing Linux environment.)
UPDATE 1:
I think another way of asking the question is: does Windows provide anything that is the equivalent of the Unix "remote shell", accessible from Unix?
There are no built-in tools to do this, although PsExec is a utility that can almost do what you want. PsTools are not a built-in, but are hosted on Technet. Some things to keep in mind:
PsExec works by actually remotely copying a file over to the Windows System32 folder (copying is one thing that is builtin ;)
Windows uses Kerberos for authentication. This depends on the computer you are running the command from being on the same Active Directory as the computer you want to control, with access set up from that side. Linux can use kerberos through third-party AD integration tools (like Quest Authentication Services, a commercial product), or also Centrify but there are no built-in tools that do it.
Psexec is not encrypted, meaning if you send commands containing sensitive data, they can be seen (though not the authentication part of it).
PsExec is obviously still a Windows utility. I have been able to get it to work using Wine, but only for a local account and after some tweaking with matching hostnames and stuff. It's possible that if you have authenticated using QAS or Centrify that your wine command will somehow pick it up, but I haven't tested it; I don't work where we use AD anymore.
Maybe the biggest problem is the difference of philosophy between the two communities. Windows doesn't use command line execution very often for remote administration. There is more focus on using your local utilities on a remote system (i.e., you can load a remote registry hive from RegEdit or browse the file system of a remote system using your local Windows Explorer program).
Overall, I think Keith's solution is actually the best, and the most straightforward.
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.
You can also use
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
Might be surprising and counterintuitive, but it works and is more cross-platform
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...
This seems to be a Qt bug, see QTBUG-9761 , the correct workaround is to use ShellExecute with lpOperation set to runas.
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.
I have an NSIS installer that installs my Qt application. At the end of the install process, the installer gives the user the option to launch the application immediately.
My application uses QLocalSocket/QLocalServer to talk to other local instances of the application. (They talk to each other basically just to ensure that there's only one instance of the app running at a time.) However, on Vista, if one of the instances was started up by the installer, then other instances cannot talk to that instance unless they were also started by the installer (or uninstaller, interestingly).
The NSIS installer launches the app with the Exec command. The client tries to connect to the server through QLocalSocket::connectToServer, which fails with the error "QLocalSocket::connectToServer: Unknown error 5".
Can anyone explain this? What's the best way to work around it?
If 5 is a windows error code, it would mean access denied. Is there a way for you to change the security on this server (You would need to access the native pipe handle)?
The finish page run option has more issues than just this, the new process gets the wrong HKCU and user profile etc.
I would recommend just disabling the run checkbox on the finish page. (This issue goes all the way back to win2000 when RunAs was added)
If you really really want this run checkbox, you can use the UAC plugin, it will allow you to start a child process as the "correct" user.
Finally figured this out. The installer was running as admin (the install script said "RequestExecutionLevel admin"), and apparently it launched my app with those elevated permissions, which meant that other instances of my app running with user-level permissions couldn't connect to it. QLocalSocket/Server uses named pipes on windows, so I figure this is a windows security feature. I'm planning to work around this by using the UAC NSIS plugin, which I believe lets you run a process with user-level permissions.