Launching exe from an application - c++

I have to launch an exe from other application.There is code in the internet to do it.
I wanted to discuss how the Application get the path of the other exe to launch, Since path of the exe can be any.
Is Storing in the registry or config is the option??
What an application should do if the exe already running.
Please add possible problem one may face whiling a launching an exe from other application
I am using c++ on VS 2008.

You have two choices for launching EXE files: ShellExecuteEx(), and CreateProcess().
Each behaves a bit different, check them out on MSDN.
As for the varying path, the registry may be a good alternative.

Related

How to execute code after application closure?

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.

Run .exe with DLLs in Azure Function

I want to execute a C++ .exe which depends on DLLs by means of Azure Functions. It works on my local machine as well as when starting the exe with kudo console.
Like in post Run .exe executable file in Azure Function suggested I prepared the run.csx and loaded up the .exe and DLLs in the same Folder "D:\home\site\wwwroot\QueueTriggerCSharp1\".
It works when no DLLs in the C++ Code is required. Otherwise C++ doesn't find the DLLs (which are in the same Folder as the .exe) and the exit code is -1073741701.
I get the same exit code, if I don't upload the DLLs.
Where should I load the DLLs or could there be another reason for it?
The run.csx-Code:
using System;
using System.Threading;
using System.Diagnostics;
public static void Run(TimerInfo myTimer, TraceWriter log)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
string WorkingDirectoryInfo =#"D:\home\site\wwwroot\QueueTriggerCSharp1\";
string ExeLocation = #"D:\home\site\wwwroot\QueueTriggerCSharp1\WriteDatebase2.exe";
Process proc = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.WorkingDirectory = WorkingDirectoryInfo;
log.Info($"WorkingDirectory: {info.WorkingDirectory}");
info.FileName = ExeLocation;
info.Arguments = "";
info.UseShellExecute = false;
info.CreateNoWindow = true;
proc.StartInfo = info;
proc.Start();
proc.WaitForExit();
int exitcode=proc.ExitCode;
log.Info($"ExitCode: {exitcode}");
}
The same error occurs when I start the exe with a python azure function. Starting the python script in kudo console works.
Does anyone have similar issues?
Can anyone help me?
Thanks!
Based on a meeting I just had with Microsoft Support, there is no way to do this.
Azure Functions is a very controlled (sandboxed) environment where access to system32 directory prevents EXE operation, despite the necessary DLLs being adjacent to the EXE.
I have found that an EXE with DLLs works fine on server/core but will not work on nanoserver. So I suspect Functions might use nanoserver, which could be the problem.
Getting your C++ working on nanoserver might be the gateway to Functions. But even if it doesn't get you to Functions, you can benefit from the drastically lower footprint of nanoserver. However, I'm not that optimistic about DLL-based EXEs running on nanoserver. Maybe statically linked EXEs is an option.
A co-worker actually had some console apps running in Functions some time ago but it has since stopped working.
EDIT: Just learned recently that nanoserver will never support 32-bit apps (not sure about 64-bit)
You need to bring your EXE or DLL with your Azure Function code. THis can be done during the deployment or manually with the KUDU interface. Then refer the EXE or DLL from in your Azure Function.
Here a 2-minute video that explains how to do it: Microsoft Developer - Execute an Exe in Azure
I know it's an old question and maybe back then the situation was different, but I've just encountered the same issue and managed to solve it by delaying a load of a dll. So you have two options:
Don't link your exe with the import library of the dll. Use LoadLibrary and GetProcAddress instead, or
Keep linking your exe with the import library, but mark the dll as delay-loaded. Using Visual Studio you can do that by adding the dll filename to Configuration Properties->Linker->All Options->Delay Loaded Dlls input field.

Launching a stand-alone executable from C++

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.

Load a DLL from another directory at program start

My basic issue is this: my program (MyProgram.exe) has a dependency on a DLL from another program (OtherProgram), and I'm trying to avoid repackaging a new DLL every time OtherProgram updates. I'd like to have MyProgram.exe link in OtherProgram's DLL when it launches, but I'm not completely sure that Windows allows for this. So if there is some kind of workaround that would also be acceptable.
And just for some background, the platform is Windows 7 x64, and MyProgram.exe runs fine when I create a symlink in the MyProgram.exe project directory to the DLL in OtherProgram's install directory. When I try to run it without the symlink, I get the "program can't start because OtherProgramDLL.dll is missing from your computer" error.
Any advice or links to relevant info is greatly appreciated!
EDIT: Clarification: the DLL is not linked at compile-time, this issue crops up at runtime
There are two types of dynamic linking in the Windows world:
Load-Time linking is when a DLL is loaded automatically when your program starts up. Windows finds this DLL using a specific algorithm I'll discuss below.
Run-Time linking is when you specifically load a DLL by calling LoadLibrary in your code. Similar rules apply as to how the library is found, but you can specify a fully-qualified or relatively-qualified path to control the search.
In the case of Load-Time linking, MS recommends that your program's DLLs are stored in and loaded from the same directory where your application is loaded from. If this is at all workable, this is probably your best option.
If that doesn't work, there are several other options, outlined here. One is to leverage the search order by putting the DLL in either the working directory or the directory where the application was loaded from.
You can change the working directory of an application by:
Create a shortcut to your application.
Bring up the shortcut's properties
Edit the "Start in" property with the directory where the DLL is located.
When you launch your application using the shortcut, it will load the right DLL.
Other options for load-time linking include:
Adding a manifest to your application which specifies where your dependent assemblies are, or,
Setting the PATH.
You could use LoadLibrary, but you would need a way to guarantee the DLL's location. This Wikipedia article provides good example on how to use the DLL after it has been loaded.
You can add the directory where the dll is located to the PATH environment variable.
I have struggled with the same problem and also found a dead end with the suggested methods like LoadLibrary, SetDllDirectory, Qt's addLibraryPath and others. Regardless of what I tried, the problem still remained that the application checked the libraries (and didn't find them) before actually running the code, so any code solution was bound to fail.
I almost got desperate, but then discovered an extremely easy approach which might also be helpful in cases like yours: Use a batch file! (or a similar loader before the actual application)
A Windows batch file for such a purpose could look like this:
#echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>
/edit: Just saw #SirDarius comment in Luchian's answer which describes that way, so just take my batch code bit as a reference and all credits go to him.
I have the same problem with one application I am working on.
I do not want to use runtime loading because there are tens of functions I would need to manually create function pointer for.
Mr Dibling's mention of manifest file opened a new door for me but I sadly found out that the oldest version of windows that supports the feature is Windows 7. It won't even work on Vista.
Long story short, a friend familiar with Windows Application development told me to look up Delay-Loaded DLL, which turns out to solve the problem perfectly with minimal effort. It delays the loading of DLL library to either the point you manually do, or the first time its function is called. So you just need to add your DLL path to the search path before that happens, where SetDllDirectory helps.
Here is the steps to make it work:
1) Specify the DLL to be delay-loaded to linker, either through your makefile, cmake or VS property page (Linker->Input of VS2015)
2) Call SetDllDirectory at the beginning of your program, before any call to the DLL is made.
Delay-loaded DLL is supported all the way back to VC6.
SetDllDirectory is supported after XP SP1.
Use Symbolic Links to the 3rd Party Executables
I found the approach advocated by Aaron Margosis useful. See:
Using NTFS Junctions to Fix Application Compatibility Issues on 64-bit Editions of Windows
Essentially, create symbolic links to each of the dependent 3rd Party executables. Place these symbolic link files in and amongst your own dependent executable files. Except for filename changes to the targets, the 'soft' symbolic links will resolve the load-time dependencies even as the target of the links are changed by future updates.

Why would a call to LoadLibrary fail with 'The specified module could not be found' after working the first time

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.