Windows allows use of a COM object without having to register the COM dll.
The mechanism is to include a "dependent assembly" in the application's manifest:
MyProgram.exe.manifest
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity type="win32" name="myapp.exe" version="1.2.3.4" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Contoso.Frobber" version="5.1.81.4" />
</dependentAssembly>
</dependency>
</assembly>
And then your folder contains:
MyProgram.exe
MyProgram.exe.manifest (if you're using an external manifest; could also be embedded at RT_MANIFEST resource)
Contoso.Frobber.manifest (the COM DLL manifest)
confrob.dll (the dll containing the COM classes we want to use)
with the COM dll's assembly manifest containing:
Contoso.Frobber.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Contoso.Frobber" version="1.0.0.0" />
<file name = "confrob.dll">
<comClass
progid="Frobber.Gizmo"
clsid="{00028C00-0000-0000-0000-000000000046}"
description="Gizmo Frobber by Contoso"
threadingModel = "Apartment" />
<typelib
tlbid="{00028C01-0000-0000-0000-000000000046}"
version="1.0"
helpdir=""/>
</file>
</assembly>
Excellent. i can now use a COM object from a (native or .NET) executable without having to register the COM object.
Now i want to use a COM object from an ASP.NET web-site, without registering the COM object.
Possible?
Bonus Chatter
Windows also allows an exe to call a .NET library, without having to install the .NET assembly into the Global Assembly Cache.
Although I can't test it right now I am pretty sure that this works:
IF the manifest for a DLL is external it will usually be ignored when the DLL is loaded via LoadLibrary (according to MSDN). IF the manifest is embedded into the DLL it is usually honored.
Embed the manifest into the ASP.NET application (i.e. code-behind DLL) - for some ways on how to do this see here and here and here.
UPDATE - as per comments:
The above is a workaround as there is no general way to do this (isolation), at least the ASP.NET creators haven't intended this to be possible - for example the above workaround won't work in cases where the application does not compile to a DLL...
Recently we were handling a similar case that we needed to enable Side by Side COM(reg-free COM) in IIS hosted ASP.NET core application, and we made it like:
embed the manifest to an assembly(.dll)
use CreateActCtx() to activate the manifest.
This approach works fine and it's recommended by MS .NET Runtime Interop Team.
Related
There are two projects in solution.One is API and other is for OrganizationServiceCall.
I have installed one nuget package called Microsoft.CrmSdk.XrmTooling.CoreAssembly it has installed default package Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.19.8.1660 with it.
But I have installed Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.22 in other project.While Call API I got this error :
{"Could not load file or assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.19.8.16603"}.
How can i done work while same Solution have different version of nuget pacakge conflicts?
Some work arounds that you can try
If second project api has no issue with latest version ,Also try Upgrading it to Microsoft.IdentityModel.Clients.ActiveDirectory version 3.19.8
Or Update all NuGet packages to the latest if its ok.
Or one may need to edit your csproj manually to add that specific version in thart particular project.
Use a single assembly version with Binding Redirect in config file
i) NuGet won't handle the references in the program. It just
manages packages. We may have to force our project to use the
loaded assembly with binding redirect.
ii) This specifies which version of assembly to use instead of old
version. It is not necessarily requires later version be specified
in newVersion, earlier version can be provided as well in
newVersion. If there are different versions, try make them uniform
across projects. Issue should be solved.
Here oneproject is referred to ActiveDirectory versions > 3.0, other
project needs less version that that. Adding a binding redirect to
the app.config can help fix problem in some cases. But before that
please make sure that particular dlls are present in the
configuration file.
Note that the runtime section is the one to be added.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
...
<runtime>
....
<dependentAssembly>
<assemblyIdentity
name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="3.0.0.0-3.19.8.16603" newVersion="3.19.8.16603" />
</dependentAssembly>
.....
</runtime>
</configuration>
And try to explicitly set Specific Version for whatever DLL giving you version issues(Microsoft.IdentityModel.Clients.ActiveDirectory) to False from Visual Studio.
Other way, you can try is to auto-generate binding redirects.
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
References:
azure-sdk-for-media-services :issues(github)
How to resolve “Could not load file or assembly | by Chirag
Rupani | Medium
Troubleshooting NuGet Package Restore in Visual Studio | Microsoft
Docs
I have created a sample application using 64 version of CefSharp 3. It works fine while all the required libraries are in the same folder as the main application executable. I am wondering if there is a way to read the CefSharp required dlls from another path.
I am looking for a folder structure as follows
Debug\MyApp.Exe
Debug\Assemblies\CefSharp.BrowserSubprocess.exe
Debug\Assemblies\CefSharp.BrowserSubprocess.exe
Debug\Assemblies\CefSharp.Core.dll
Debug\Assemblies\CefSharp.dll
Debug\Assemblies\CefSharp.Wpf.dll
Debug\Assemblies\icudt.dll
Debug\Assemblies\libcef.dll
Debug\Assemblies\Locales\en-US.pak
in other words i need to read the required cefsharp dlls and locales from different folder than my application (MyApp.exe)
I have created the config file MyApp.exe.config as follows
<?xml version="1.0"?>
<configuration>
<!--
These settings only apply to the bootstrap AppDomain.
Modify Web.config to alter the configuration of the application.
-->
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Assemblies"/>
</assemblyBinding>
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
but still using the above browser shows blank page. it only works if all of them in one folder
Any help will be highly appreciated
I finally found the problem. due to running the browser on separate process and dependency of the CefSharp.BrowserSubprocess.exe to CefSharp.dll and CefSharp.Core.dll the same config file had to be created for the sub process.
The only change i had to make was creating the file CefSharp.BrowserSubprocess.exe.config and copy the same configuration as in MyApp.exe.config
I have a QT app which uses a LIB that depends on the 2008 C++ MSVCR90.dll.
When I deploy my app, on some computers the following error is presented:
how can I solve this issue?
someone mentioned to me that if I include a manifest file, this should help. so I prepared the following manifest file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="*" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
in the .pro file I've added the following:
CONFIG += embed_manifest_exe
win32:CONFIG(release, debug|release) {
QMAKE_POST_LINK = $$quote(C:/Program Files (x86)/Windows Kits/8.1/bin/x64/mt.exe -nologo -manifest \"ISHEmulauncher.exe.manifest\" -outputresource:$(DESTDIR_TARGET);1)
}
else:win32:CONFIG(debug, debug|release) {
QMAKE_POST_LINK = $$quote(C:/Program Files (x86)/Windows Kits/8.1/bin/x64mt.exe -nologo -manifest \"ISHEmulauncher.exe.manifest\" -outputresource:$(DESTDIR_TARGET);1)
}
but the manifest that is created is different from the one I prepared and does not include the VS90 dependency and therefor I'm still facing the same error.
any suggestions?
thanks!
Redistributables are pretty annoying to manage. Typically what I have needed to do is to run the MSVC C++ redistributable installer on every deployment machine (as part of the install process) to avoid this error.
The article here may shed some light on the situation:
http://msdn.microsoft.com/en-us/library/ms235299(v=vs.90).aspx
https://qt-project.org/doc/qt-5.0/qtdoc/deployment-windows.html#application-dependencies
I have tried to get the right dll's off my development machine and just deploy it into my application's folder. If you don't mind having another step in your installer of installing the redistributable package, the links below should help.
http://www.microsoft.com/en-us/download/details.aspx?id=29
http://www.microsoft.com/en-us/download/details.aspx?id=26368
Also if your app is compiled for 32 bit, you only need the 32 bit redistributables. If you compiled your app in x64, then you need the 64 bit redistributables.
Related:
Qt5 Deployment on Windows
Hope that helps.
I solved the problem by unchecking the "shadow build" option in QT.
after that, the manifest file I defined wasn't ignored and the library was loaded correctly.
I have a mixed-mode DLL built in visual studio 2005. In dependency walker, my DLL is showing a dependency of the following CRT Dlls. Note this is on my Windows 7 developement machine.
c:\windows\winsxs\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4927_none_d08a205e442db5b5\MSVCP80.DLL
"\MSVCR80.DLL
"\MSVCM80.DLL
8.0.50727.4927
On my Windows 7 dev machine using Visual Studio 2005 this compiles and runs just fine. the problem is it wont run on my Windows XP test machine with the latest CRT installed.
When I drag the DLL into depenency walker on the XP machine it seems to be searching for the DLLs in \System32... (I went to show full path and there was no paths for them, just a yellow exclamation mark)
The problem is that this version (build 4927) of the crt in WinSxS is not installed on the XP test machine. it has Visual Studio 2005 with the latest CRT installed (sp1?).
8.0.50727.4053 is the latest version I could find on MSDN.
I realize this is not the most exciting question posted on SO, but does anyone know what is up with this 4927 runtime?
*
EDIT
*
The manifest generated by MT.exe:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.4053" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
So, there is 3 different versions it is targeting...
Revision 4927 is a Windows 7 specific version, probably used by Microsoft binaries. Your build should not create a dependency on it, 4053 is the last one for VS2005. Don't troubleshoot this with depends.exe btw, it isn't good at tracking winsxs dependencies.
Start troubleshooting this by double-checking what dependency your build generates. First look in vc\include\crtassem.h, the _CRT_ASSEMBLY_VERSION macro generates the manifest entry. Next is to check the manifest that's embedded in your executable. Your project's Release directory contains the .embed.manifest file that was embedded. And File + Open + File on your executable lets you peek at the actual embedded RT_MANIFEST resource.
I have the following situation
Project A
- Uses Castle Windsor v2.2
- Uses Project B via WindsorContainer
Project B
- Uses NHibernate
- Uses Castle Windsor v2.1
In the bin folder of Project A I have the dll Castle.DynamicProxy2.dll v2.2 and NHibernate dlls. Now the problem is that NHibernate is dependent on Castle.DynamicProxy2.dll v2.1 which is not there. How do I resolve this situation.
I used the following configuration to resolve the issue.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Castle.DynamicProxy2" publicKeyToken="407dd0808d44fbdc" />
<codeBase version="2.1.0.0" href="v2.1\Castle.DynamicProxy2.dll" />
<codeBase version="2.2.0.0" href="v2.2\Castle.DynamicProxy2.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" />
<codeBase version="1.1.0.0" href="v2.1\Castle.Core.dll" />
<codeBase version="1.2.0.0" href="v2.2\Castle.Core.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
One thing very, very, very important that one might miss if he is not paying enough attention.
The assembly you write in the codeBase version tag, must be strong named.
From the following link: http://msdn.microsoft.com/en-us/library/efs781xb.aspx
For assemblies without a strong name, version is ignored and the
loader uses the first appearance of <codebase> inside
<dependentAssembly>. If there is an entry in the application
configuration file that redirects binding to another assembly, the
redirection will take precedence even if the assembly version doesnt
match the binding request.
One solution (or workaround) would be to install both versions in the Global Assembly Cache (GAC) on the machine(s) on which your software needs to run, and reference the assemblies using their strong names. This assumes that the assemblies do indeed have strong names.
Installing into the GAC will be a pain if you have more than a few developers or if you plan to deploy your solution to many computers (eg as an end-user application). In this case, I believe (but I might be wrong) that your only option is to merge one of the two versions into the assembly requiring that version. In your specific case, you need Castle.DynamicProxy2.dll v2.1 to be merged into NHibernate.dll.
You can use a tool called ILMerge to merge the assemblies. The command you will need to run looks something like this (untested):
ILMerge /t:library /internalize /out:Deploy/NHibernate.dll
NHibernate.dll Castle.DynamicProxy2.dll
The /internalize switch tells ILMerge to mark all types from the second assembly (Castle in this case) internal in the output assembly. Without this, you might get compile errors when you try to compile a project referencing both your new NHibernate.dll and the shelf version of Castle.DynamicProxy2.dll v2.2, as they will contain classes with the exact same names.