My C++ app was required to communicate with a web application. Since writing in C++ was hard I wrote the web application client in C# (DLL), COM enabled it, and called it from C++ app and it worked.
But the C++ app can be installed on a server PC, its folder shared over a network, mapped to a drive on a client PC, and run from there. When I tried running so, it doesn't run because it is expecting the C# DLL to be registered on the client PC. I would like to avoid it. I would like to keep them both on the server. Is it possible to do it using registration-free COM? If yes, can the C# DLL (and its dependent DLLs) be placed in a folder different to the C++ EXE folder?
I see this is an outdated post. Hope you had found out a solution or a workaround. Anyhow, I shall answer as it may help someone with the same problem.
Is it possible to do it using registration-free COM?
Yes, it is. Follow this MSDN article. You will have to create a manifest for the c# com dll and embed the manifest into it. Which would be with the help of a RT_MANIFEST resource. That article is a little outdated, so you may face problem with .net framework version. If you did, you will need to specify the .net framework version in your machine. You can simply replace the clrclass line with this :
<clrClass
clsid="{16AD5303-E154-44B4-A72B-C129859714AD}"
progid="SideBySide.SideBySide"
threadingModel="Both"
name="SideBySide.SideBySideClass"
runtimeVersion="v4.0.30319" >
can the C# DLL (and its dependent DLLs) be placed in a folder
different to the C++ EXE folder?
Yes, it can be. But I wouldn't recommend it. According to this resource, the assembly loader searches for assembly manifests in the following order :
Side-by-side searches the WinSxS folder.
\\<appdir>\<assemblyname>.DLL
\\<appdir>\<assemblyname>.manifest
\\<appdir>\<assemblyname>\<assemblyname>.DLL
\\<appdir>\<assemblyname>\<assemblyname>.manifest
The above locations are respective to the application (appdir). If you want your dll to be elsewhere, then you can use the file element of the assembly manifest (the name attribute can include a path), see here for more details and other elements.
Hope this helps someone.
Related
I need to make API calls to methods in an EXE provided by a software company. In the past very old .Net version, I was able to make it work by renaming the exe to dll (I guess?). This time around the EXE they have provided seems to have been compiled in 4.6.1. I am not able to make it work and it causes runtime errors:
"Could not load file or assembly... A strongly-named assembly is required"
What are my options? Is it still possible to make API calls to an EXE whether or not I rename it to a DLL? Or Should I ask them to provide me a proper DLL?
Thank you.
Thanks to #vasily.sib and the following link, I was able to resolve this issue.
I can in fact reference any EXE assembly in the project and call methods on it. An EXE (and for that matter a DLL) can be strong named and signed by anyone, and not just by the developer who has the source code for that EXE. See the following link for details.
Thank you.
https://chrisbenard.net/2009/07/16/strong-name-an-assembly-without-source-code/
I built an application that used some extrnal libraries, Like Tag-lib, Naudio and Windows Media Player.
So they add me to my solution (in the same folder as my EXE file), some DLLs.
I wanted to embed those DLLs to my EXE file, so I looked at the internet and found some options.
The best answer I found was this:
Embedding DLLs in a compiled executable
And it worked, but not for all of the DLLs.
It successfully embedded Naudio and Tag-Lib, But Unabled to embed Windows Media Player's DLLs.
Can anyone help me embed the Windows Media Player's DLLs to my application's EXE?
Update:
After some help (Thanks Mathieu Wybrecht) it worked.
I did everything that he said, but still it isn't working well.
The EXE file work perfectlly, I can move him and it will work.
But when I'm in the project's solution, it error me about the missing Dlls (The Dlls of WMP that Costura.Fody just embed...), and then I copy the Dll again to the folder and the error gone. It seccessed to build the solution, rebuild the solution or starting the program, the DLLs Disapear again (embed to the EXE) and the error comes up again...
Your question is not clear. What do you mean by "when I started to use Windows Media Player, it added a DLL file, and now it doesn't ..."
Where did "it" add a DLL file?
What is "it" ? Your application? Windows Media Player?
What DLL was added?
If the problem is that you want to embed one more DLL in your exe, follow the how-to you found about Costura.Fody.
If the problem occurs at run time, ensure that all embedded DLL don't try to load more dependencies. You can check for their dependencies using "Dependency Walker", it exists for x86 and x64 platform.
Edit: you edited your question, and now I'm back to edit my answer too :)
So, you succeeded to embed few DLL but not every one of them. It can be related to some of following reasons:
Some of them are native DLL (you have to follow a particular process to embed) : you may refer to Fody/Costura unmanaged assemblies and Fody/Costura Native Libraries
For some of them, Reference in your project are maybe not marked as "Copy Local = true" and/or not considered as "Embeded Resources" for some reason
Maybe your library is correctly embedded but still present in your output directory for you may not have installed the clean-output target ?
take a look at Clean output directory
Or you may face another problem that is more specific, try to get a look at Fody/Costura issues, you may find a reason for which your desired libraries are not embedded.
I'm developing an application that depends on some 3rd party dll's (it's actually a plugin to the 3rd party application, and I receive COM objects implementing certain interfaces declared in those dll's). My project contains references to those dll's locally exist on the dev machine, but I want to avoid wraping them inside my installer (for size and legal considerations).
Instead, my installer requires that the dll's are already existing on the target machine, and their path is saved to a text file next to my executable assembly.
How can I use this file to link to the dll's on run time?
Or is it better to add an environment variable during installation and use it instead (how can it be done)?
Using project references, I do not know of a way to have dlls in an arbitrary location. Typically I've handled this issue using an installer, like InstallAware, prompted the user for the 3rd party location, and copied the dlls into my projects folder at the same relative location I chose in my solution file.
If this is improbable for you, you can always load the dlls and create instances of the classes yourself by hand using Assembly.LoadFrom and Activator.CreateInstance.
I hope this helps.
I wrote a dll c++/cli library which uses my other c# dll library. C++/cli library works fine when I've got c# dll in the same folder as application which calls it. This library will be finally loaded to many applications and a C# dll must not be copied into directory with application. It has to be in the same folder as c++/cli library, but in that cases I've got System.IO.FileNotFoundException.
My suggestion is to load c# library manually or to change path where f.ex. firefox is looking for dependencies, but I tried with LoadLibrary() and Assembly::LoadFrom() methods to force loading from right directory. Of course I added directory path with dll to system PATH.
I work on VS2010.
You don't change the default directory where an application will look for dlls.
At design time put your dll in some well know location, the one you are going to deploy to. Add a reference to it, make sure it's set to Don't copy ever, otherwise it will end up in the bin folder. You have to do this otherwise it won't compile.
When you deploy, you'll need one package to deploy common dlls, and one for each application. Careful you don't create your own version of dll hell, if appA needs an older or new version of the common dll, compared to AppB
Add an AppDomain.AssemblyResolve event to main (for windows app). At run time the event handler will get fired when you reference a type in your dll, and the assembly has not yet been loaded.
In there you load it from the well known location. That usually in config, or in a relative path.
E.g.
AllMyApps
CommonDLLS
MyFirstApp
So the path you load the required common dll from would be "..\CommonDlls\MyCommondll.dll".
NB you will want to secure the dlls in some way, otherwise a bad guy might be able to inject their version of one in to your app, which would be bad...
You can use this mechanism to get the dll from a remote server or a database blob as well.
The simplest case is only a few lines of code, just look the event up. Took me about 15 minutes to get this going in a similar scenario.
Not on this machine though, otherwise I'd have pasted in the code.
I'm getting a System.DllNotFoundException for a .dll which is in the same folder as the executable whenever my application attempts to use a function which exists in the DLL. The weird thing is that it is only occurring on one user's PC; it works fine on my dev PC and it works fine on one non-dev PC that I tried it on. Also, there are other DLLs in the folder which are being found and used correctly. The DLL in question is a native library which is referenced by my application via another DLL which is a c# wrapper for the native library.
My initial instinct is that there must be some other library being referenced by this DLL which doesn't exist on the problematic PC, but I cannot imagine what library this PC could be missing that the other non-dev PC has.
So my questions are this: is there a way to determine the dependencies of a given DLL file? Keep in mind that the DLL in question is a native library (i.e. not managed code), and I do not have access to it's source code. And if it turns out no dependency is missing, what else might cause such an issue?
For unmanaged dlls you can use Dependency Walker to find dependencies.
I would suggest using ILSpy to open the dll and view its dependencies first.