QProcess::startDetached sometimes it seems that detached and main process uses the same dlls
-
Greetings,
I have a weird problem that want to understand. I have some application that needs to be updated at some point. That main app launches another process and closes itself. Another process tries to download files to the main applications' folder and SOMETIMES it's ok, sometimes not - and by time stamp I can see that some dlls are not overwritten. So I make a conclusion that detached process uses dlls of the starter.
I start a process like this:
QProcess::startDetached(processPath, args, workingDirPath, &processId);
Here
workingDirPath
is individual for each process and contains all necessary dlls. -
The workingDir is the directory where you start your process. This is the directory where all dataset could be found (e.g. ./test.dat).
startDetached does not state anything about dlls.
They have to be accessible by other means.[edit: koahnig] I could not find it right away, but the environment setting would be for dlls.
This is as with the command prompt. -
Thank you, but can you help me to understand in general? Can a process started as detached use the parents' dll and not it's own?
-
Thank you, but can you help me to understand in general? Can a process started as detached use the parents' dll and not it's own?
@nikitablack
Unfortunately, No.
I have used QProcess in both forms, but never experimented with different environments. The documentation is inconsistent as far as I can see. That is also the reason why I could not find a reference to the environment right away.
I would expect that you can use the "setEnvironment" only when you use "start". "startDetached" is a static method, but should know nothing of whatever you have set to a QProcess object. -
I don't think environment has anything to do here. It's a question of what the dlls are and are they shared between the two apps (main app and updater). Can you tell us more what these are and does the updater use them in any way?
So I make a conclusion that detached process uses dlls of the starter.
This is a possibility. Different apps can share dlls. That's perfectly normal. For example if two Qt apps are started from the same working directory that contains Qt dlls they will share them.
If the updater has its own copy in its working dir and you still think it uses the ones from the main app you can check what is actually loaded by running a profile with Dependency walker.Another possibility is that the main process doesn't have enough time to unload before you try to overwrite its dlls.
-
If SafeDllSearchMode is disabled, the search order is as follows:
- The directory from which the application loaded.
- The current directory.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
The PATH variable of the environment has something to do with finding dlls.
However, as ChrisKawa is lining out, 2 apps may share the same dlls.
The only reason which could make sense is when you have to use for your application completely different dlls (e.g. Qt 4). However, I would recommend in such a case that the first possisbilities provide the resolution.
-
Thank you guys.
@Chris-Kawa said:
Can you tell us more what these are and does the updater use them in any way?
The problem I have is very strange and difficult to describe. I'll try. The main app uses lots of dlls (mostly qt's dlls). But I can tell that I have a problems only with my dlls. The updater uses all the same dlls (actually copy of them in different folder). The main app starts an updater with
QProcess::startDetached
in separate working directory. With ProcessExplorer or ProcessHacker I can see that all dlls are from different paths - there's no common dll. Next I'm closing main app withQApplication::quit()
. I haveWaitForSingleObjectEx
in updater and I even added a timeout so I'm 100% sure that the main process exited. I start to download files to main app's folder (the same dlls). And it CAN happen that some of the dlls can't be overwritten. Every launch there's a different dll or even worse - some launches works ok! One more strange thing is that I CAN delete ALL the files manually in explorer. -
Hm, nothing obvious comes to mind.
I see you're mixing WinAPI with Qt. How do you download and save the files? Which APIs do you use? What error codes do you get with them?
Do you overwrite the files in-place or do download to temp -> delete original -> rename temp to original? -
Thank you. The reason of this behavior was that some files was "read-only". Shame on me, I spend 3 days debugging, but didn't check such obvious thing (. A "facepalm" smile for me.
-
Hah, such is the life of a programmer :)
Glad you could solve the issue.