This is very specific, and I have very little to go on, but I am at my wits end.
Here's the scenario:
My c++ application runs an executable using CreateProcess. The Process Attributes, Thread Attributes and Environment are all inherited from the application.
The executable loads a DLL.
When I run my application normally, all is fine.
When I launch my application from Outlook ("Open" my applications data file, as an email attachment, from Outlook, which launches my application) the CreateProcess succeeds, but the executable that is run returns immediately with a return code of 1, and there is nothing in std out or std err.
Investigation shows that the Path environment variable in my application is the same when it is run normally, and when it is run from Outlook except that Outlook adds its directory to the path. All other paths are the same.
The executable I am running is g++ cross compiler.
I know this is a tiny amount to go on, but I'm hoping someone has had a similar experience.
Related
for a self-built installer I need a way to execute code after closing of an application itself.
Application structure
Main application: The installer is started from it when needed, it closes itself in the process.
Installer: This is also located in the folder of the main application and therefore also accesses all dll files. When an update is available, a zip file is first downloaded and then unpacked into the temp folder. Afterwards, all files are moved from there to the shared application directory.
The problem
The problem is that the updater can only update a few dll files at runtime that are not used by itself, because some are write-protected due to the installer's access.
A solution
Moving the files from the temp folder to the shared application folder must happen after closing the installer. But I don't know how to realize that.
Thanks a lot!
If your problem are the DLLs shared by the installer and main application, then you can do this: Before you run the installer, your main application can copy all the needed DLLs and the installer EXE from your main application folder to a temporary folder and run it from there. Your installer must then only wait until the main application gets closed and then replace all its files in the main folder. And once your update is finished, delete this temporary copy of the installer with its DLLs.
Note that if you want to overwrite files in Program Files folder, your installer will have to be run with elevated privileges. Google for "runas" command... you will need it when starting your installer with QProcess.
But there may be also other problems. If your first installation was with normal installer, it typically creates some entries in registry and also generates list of files for later uninstall. And if your new versions will contain different files than originally installed version, then your subsequent uninstall may malfunction or may leave some files existing on users' computers. And you certainly do not want this.
And yet another potential problem. You may have running several instances of your application. In that case quitting one instance will still leave the other instances running and hence their files will not be replacable by the installer - it will fail.
So as you can see, these are quire serious aspects to take into account.
How I do it in my software and I suggest you try it too? I prepare one installer file (.exe) with InnoSetup (freeware!). This can be used for first installation as well as for automatic updates. Then if I create a new version and put it on the server, the running main application detects it, downloads the new installer and runs this installer (of course it asks the user if it should proceed). The installer then asks for elevated privileges, asks to close the running application (it usually is closed automatically when starting the installer) and overwrites the existing installation. All this is standard functionality built in the installer created by InnoSetup. And correctly updates the uninstall instructions... It took me several days to set up everything to my needs but it works well. The only "drawback" is that it is not completely silent, it shows some dialogs. But this is no real issue for me. Maybe it is better for the users to see what is happening on their computer...
Your question implies Windows. I'll make a suggestion from a Win32 perspective.
In our application, we have a similar issue. Periodically, our application downloads an update executable into a temp folder and then launches it. When the update EXE runs, it makes sure the main application has exited, unpacks the files into the application's installation folder, and then starts the application back up again. It's actually more complicated than that, as it really copies the new files into a different install folder, but I'll save those details unless you really need it.
The problem is that the updater can only update a few dll files at runtime that are not used by itself, because some are write-protected due to the installer's access.
This is the core of your issue. My advice is to have the Installer EXE statically linked to both the VC runtime and the other code its sharing with the application. That is, no DLL dependencies all. If you really need to share code between the installer and the application, but still want the application to use a DLL, you can do this. Have the shared code built as both a DLL (with a stub lib) and also built as a full LIB. May require some minor refactoring to your build or redundantly build the same source files. The Installer code links with the full LIB. The application code links with the stub LIB for the DLL like it does now.
If you are just looking for a way to launch the process, the API you want is CreateProcess.
Also, have you looked at the open source options like Omaha - which is what Google Chrome has used for silent updates?
Moving the files from the temp folder to the shared application folder must happen after closing the installer. But I don't know how to realize that.
The "Windows way" would be to use PendingFileRenameOperations as described in this blog-post and have Windows do the move during the next startup. Of course that implies one more of the annoying "Please reboot to finish the installation" messages.
I have a Windows exe file, which I want to make hardware-locked. I want it to run only on computers, which have a valid license key. For this I use Winlicense.
I created a project in Winlicense and all is OK, but when I click "Protect" the protection finishes successfully, but the exe is running without any problems on any Windows computer. I expect to see a message that this program requires a valid key in order to run.
I can send the XML of my Winlicense project together with the exe file (the exe file is absolutely empty).
What is the right way to protect the exe, so that it asks for a valid key when it is run?
I have a programmable signal generator. It came with a .inf file and a .exe file. Double clicking the .exe file runs the signal generator systems application.
I would like to invoke this executable from a piece of VC++ code. I am using Shell Execute as follows.
std::string app = "C:\gen.exe";
ShellExecute(NULL,"open",NULL,app.c_str(),NULL,SW_SHOWNORMAL);
However, instead of launching the executable, the command pops open a file dialog.
Upon further experimenting with ShellExecute, I noticed that ShellExecute works for executable files in the Program Files directory, but fails when I have stand alone executables such as in the case I mentioned above. Can someone please explain how to launch using VC++ a standalone executable located in a random directory on the disk?
By Standalone executable, I mean that the binary distribution for the application was simply an executable file, and a couple of other files. I can launch the executable by simply double clicking it, however, I cannot launch it using ShellExecute.
If you take a look at the documentation for ShellExecute (link), it seems like you might have the reference to app in the wrong parameter. The fourth parameter is the parameters parameter - not the parameter specifying which file to open/run. So basically, this should work:
std::string app = "C:\\gen.exe";
ShellExecute(NULL,"open",app.c_str(),NULL,NULL,SW_SHOWNORMAL);
Alternatively, you could use CreateProcess or system("C:\\gen.exe");. I should point out that none of these options are portable to other OSs, but running a program probably won't be, however you end up doing it, since most OSs differ on how they run programs - or even what programs are.
I have an application that runs as a WCF webservice on IIS7. It calls a COM control and this control then loads another dll with data. This application has been in use for quite a while and normally works fine, but recently I ran into a problem on one machine where the LoadLibrary call to load the data dll fails. However, the call doesn't always fail, it will work for the first call after the IIS service is restarted, and then fails after that.
The data dll exists in the same directory as the COM control, and the current directory is set to this directory. I've checked and the current directory does not get set to another directory, it stays the same for both calls. The separate calls are separate calls to the webservice and in between them the com control gets unloaded, as does the data dll.
The data dll loads fine if I place it in the system directory or use the full path to the dll in the com directory, so I can work around this, but I'm just wondering why it would happen. When I call GetLastError after it fails to load the module, as I mentioned it just gives me 'The specified module could not be found' error.
The MSDN description for LoadLIbrary says that the current directory should be searched and all the other installations where this has worked seems to suggest that it normally does. The machine that it's failing on is a Windows Server 2008 R2 machine, although the application has been run on this type of machine many times before.
Any ideas are welcome. Is there a way to get LoadLibrary to enumerate where it's looking?
Thanks,
Jordan
I haven't found a function that will enumerate all the DLL search paths, and it looks rather complicated: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx
The Windows behavior of searching the current working directory for libraries (in addition to the location of the .exe) is considered a potential security flaw. That article describes some ways to exclude the current directory within a process, including the SetDllDirectory function. I don't know how IIS works, but if you don't control the process, maybe someone else is tampering with the search settings? I think GetDllDirectory will tell you if that changed.
There is also a global registry setting that disables searching the working directory, but since your load isn't always failing I have to guess that's not the cause.
I am trying to build a Windows service with MingW. It need thread safe exceptions, so I added the linker flag -mthreads. The application works fine from the command-line, but when I try to start it from services.msc, the 1054 error ("The service did not respond to the start or control request in a timely fashion") is raised. The service starts if I re-build it without the -mthreads flag. How can I get this working with -mthreads?
I suspect -mthreads is bringing in a dependency on a DLL, and that DLL is not on the path when it's running as a service. In my cygwin environment, if I compile a trivial program with "-mno-cygwin -mthreads", I get a dependency on MINGWM10.DLL, which certainly wouldn't be on the path when running as a service. If I try running it with no PATH set, it crashes as it starts to load (and leaves a turd in the Application event log).
I'd be bringing up your exe in Dependency Walker (http://www.dependencywalker.com) to see what you're loading at load-time, and check your Windows Event Log to see if there are any hints there. You're probably going to need to put a copy of the DLLs it needs alongside the executable.
You need mingwm10.dll in the working directory or in [edit: system, not per user] PATH, because C++ programs compiled with -mthread option have that dependency. If you're pretty sure exception will never be thrown by your code nor propogate through your stack, use -fno-exception instead of -mthread to resolve the dependency.
I wonder if you can debug it when it runs as a service. There must be something spooking your program when service host runs it. Perhaps try to attach a debugger to svchost.exe, at least you can see what modules are loaded and maybe which exception causes the crash.
Is your application even starting up at all? Put a call to OutputDebugString (or equivalent) at the start of your main function to see if it even gets that far. (Grab DbgView from SysInternals if you don't have it already.)
If it doesn't get that far, we start checking for the obvious: is it a matter of the application not finding the runtime DLL? It could be that you have the regular runtime in its PATH, but it can't find the MT version. That could explain the behaviour you describe. You may need to copy the MT runtime or update the PATH accordingly.