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.
Related
My application store some data in data only dll files. Those dll files are loaded with LoadLibrary() when needed at runtime and then discarded with FreeLibrary() after finish using them. The main application access the data stored in the dll files using GetProcAddress(). The program is written in C++ and uses WinAPI calls, no MFC or other libraries. It has two versions x64 and x86. It works fine on most systems. My dll files do not call other libraries or depend on anything else. Each is a stand alone file.
Recently, I discovered the program does not work on one machine. this specific one has Windows 10 x64 installed on it. After investigations I found the following:
LoadLibrary() fails with error message "Could not find module". The dll is in same directory with main program.
I replaced the call to LoadLibrary() with LoadLibraryEx() and tried the following falgs:
LOAD_IGNORE_CODE_AUTHZ_LEVEL did not work. The dll could not be loaded.
DONT_RESOLVE_DLL_REFERENCES ... works?? But, Microsoft strongly recommends not to use it.
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE ... loading the dll succeeds?? But, the call to GetProcessAddress later fails. the program could not access the data in the dll file. So this is not actually working.
I could not find anything wrong with this machine. All other programs are working fine.
I tried the x86 version on this machine and it worked fine using original LoadLibrary().
My installer is dual system and automatically installs x64 version when it finds x64 windows. Normal user can not simply switch to x86 when he gets such error.
My question is how can I eliminate this error and make my program works on any machine:
Should I call LoadLibraryEx() using DONT_RESOLVE_DLL_REFERENCES flag and ignore Microsoft warning?
Is there any way I can get my library loaded with simple call to LoadLibrary()?
If I call LoadLibraryEx() with LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flag, as recommended by Microsoft, how can I access the data without calling GetProcessAddress()?
Thank you in advance.
I am trying to build an application file in release mode in Visual Studio 2015. The issue is that I need to use the Multi-threaded DLL run time library option. When I create the application and try to run it on a different computer I get various missing dll errors like msvcp140.dll and vcsruntime.dll. Is there a way to create an application file such that it has everything it needs and can independently run on any computer.
Under "Libraries" you should select
"Debug Multithreaded (/libs:static /threads /dbglibs)" for all your libraries. All the needed dll's will now be linked to your application. The executable will be somewhat bigger, but the application should work on any windows computer. You can use this option for both the debug and the release version. Keep in mind though that you may still run into problems if you're creating your own dll's that depends on other external dll's (which they often or always do). I.e. in order to be safe; do not create your own dll's.
You have to keep dependencies beside the exe(compiled) file. for this job, you can copy them in the exe directory, or set environment variable. Additionally, I suggest using cross platforms libraries, such as QT.
I’m currently logged onto a machine and my current problem involves a custom build step that has trouble copying a .dll to the Bin directory because Windows says it cannot access the file because it’s currently being used by another process.
I’m able to reproduce this on several other projects. The sequence of events is that I build a release successfully, do some test, checkout another SHA when doing a git bisect, and attempt to build a release from that SHA without doing a git clean -xfd (intentionally, because I’m trying to cache as much reusable data as possible). The weird thing is that I tried to use Process Explorer (procexp) and tasklist /m <locked_dll.dll> to search for whatever is holding onto this dll, and am unable to find anything holding onto the dll. I’m on a non-admin account, and I’m not sure if that is causing Windows to hide certain processes from me. Rebooting the machine helps, but that’s not an acceptable solution since I’m trying to automate things. I’m able to delete the .dll, and when I try to build the project in VS, it’ll complain that it still can’t access the dll when trying to copy it over to the Bin folder. Any ideas? I’m going to keep researching the issue, but as of right now, I’m sort of stumped.
EDIT:
This seems to be a duplicate question (Error: Cannot access file bin/Debug/... because it is being used by another process), but I'll leave this open to see if anyone has found anything new related to the topic.
I've seen this problem in VS 2010 with a large .Net solution with multiple projects in it. Every case I've seen so far pertains to have one project with dependency DLLs that another project also uses, and that other project also uses the first project as a reference, and also uses the same dependency DLLs that happen to be a different version from the first project.
To describe it a different way:
Project A depends on v1 of DLL A
Project B depends on project A and v2 of DLL A
Both project A and B are in the same solution
The solution is to use the same version of DLL A. I usually run into this when upgrading to a new version of SQLite, and I forget to update the dependency in all of my projects.
After talking with a few coworkers, I found the solution to my problem. procexp and tasklist did not see which process was locking the dll because there was no process locking the dll on that particular machine.
I have a hardware configuration where machine A (a host PC) is connected to machine B (acts as a client that retrieves instructions from machine A) using a network switch. machine B runs the same binaries that link to the same dll's. Thus, obviously, running procexp or tasklist on machine A will not see anything locking the dll's because machine B is the culprit.
I am having trouble getting Inno-Setup to load my DLL.
I have looked at similar posts, but none of the solutions offered in those seem to help.In particular, this post came very close, but does not seem to be quite the same issue.
My installer runs just fine on my test system. My DLL is written in C++, using VS 2010. There is a DEF file. I have been successful using the VS debugger to attach to the installer's thread and step through my code. Everything is good. The release version runs just fine on my test system with no debuggers involved. Setup calls my DLL and it works.
Then I take my installer to a different, pristine system to try it out. Every time, when I launch the installer, it starts off with the usual UAC prompt: "Do you want to allow the following program from an unknown publisher to make changes to this computer?" And I say "Yes." Then I get a beep and an alert that says:
Runtime Error (at -1:0):
Cannot import
dll:<utf8>C:\Users\Logicrat\AppData\Local\Temp\is-4E245\MyDLL.dll
In my setup script I have
[Files]
Source: "MyDLL.dll"; DestDir: "{app}"; Flags : dontcopy
and
function MyFunc(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal): Integer;
external 'MyFunc#files:MyDLL.dll stdcall setuponly';
According to the Inno documentation, the dontcopy flag is appropriate if the DLL is not needed for uninstall, which it is not.
I suspect the problem lies in designating exactly where the DLL is supposed to be, as I my script calls for it to be in the {app} directory, yet the error message refers to a temp directory. I've tried a number of variations of the script, all with the same results.
Both my development/test system and my pristine target system are Windows 7 (32-bit). I have been banging on this for weeks with no visible progress. Any suggestions will be most welcome.
Problem solved, thanks to the suggestion by TLama about checking dependencies. When I had initially created the new project for my DLL in MS Visual Studio 2010, I had selected the option to "Use MFC in a shared library." That turned out to be the source of the problem, as the DLL itself was then dependent on mfc100u.dll and msvcr100.dll, which were not present on the target system I used to test my installer. I fixed it by changing the project preference to "Use MFC in a static library." That made the DLL larger, but it also made it work. Then, after I first rebuilt the DLL and then rebuilt the installer that used it, everything was fine.
It might have been nice if the error message I got the first time around named the DLL it was looking for instead of the DLL that tried to call the missing one.
Is it possible to recompile an MFC DLL while its "client" executable is running, and have the executable detect and pick up the new changes? If it's possible, is it foolish? Being able to recompile the DLL without restarting the exe would save some time in my coding workflow. I am using Visual Studio 2008, code is written in native C++/MFC. My code changes are entirely contained in the DLL, not the EXE.
Thanks!
Unfortunately, unless the executable has support for hot-swapping DLLs, you can't do it. The standard DLL loading mechanism in Windows will load it either at the start of the process or at first use of a function exported by the DLL and will not watch the file for changes in order to reload it. Also, depending on how the DLL is loaded, the file might be locked for changes.
You will have to stop your client executable before recompiling.
Yes, it's possible. You'll need to make sure the executable explicitly loads your DLL (via LoadLibrary). If your executable implicitly loads your DLL you'll have the issues that Franci described.
To update the library while the executable is running:
Define some convention for staging the new version of the DLL. It could be in a separate folder, or with a different file name/extension.
Have a means of checking for a new version of the DLL. This could be in response to some specific gesture in the user interface, or you could monitor the directory for changes from a background thread.
When you see a new version, unload the old version (FreeLibrary), then delete it and move the new version to the desired location and reload it (LoadLibrary).
If your DLL implements any COM objects, let me know and I'll give you some additional tips.