I have created an new C# windows forms application. I have added COM Reference "Microsoft Excel 15.0 Object Library" to my project. This project is for importing excel data to the dataset. I have done it. I works fine in my computer. If i run the exe file on another computer it showing error like below.
ERROR:
Unable to cast COM object of type
Microsoft.Office.Interop.Excel.ApplicationClass’ to interface type
‘Microsoft.Office.Interop.Excel._Application’” This operation failed
because the QueryInterface call on the COM component for the interface
with IID '{{000208D5-0000-0000-C000-000000000046}' failed due to the
following error: Error loading type library/DLL (Exception from
HRESULT:0x80029C4A(TYPE_E_CANTLOADLIBRARY)).
COM components are not my specialty, and I do not use them too often. But I will tell you what I have experienced before. Please note that I experienced this about 6 months ago and the circumstances were far from ideal at my work place.
In order to use a/some COM component(s) you also need to have it's dependency installed on the target computer (in this case Excel/Office). Have you checked if the target computer has Excel installed on it?
If not, you can use an OLEDB connection to read Excel files. I don't remember how this is done specifically.
Maybe this can help in some way to read Excel files using OLEDB: http://www.codeproject.com/Tips/705470/Read-and-Write-Excel-Documents-Using-OLEDB
In your proyect references, try to set Copy Local = true in your dll
If you are working on a 64 bit development environment, try explicitly defining the use of non 32 bit version of the library. For doing so in visual studio, tick and then untick the box "Prefer 32-bit" in the build section of the project configuration, which will add <Prefer32Bit>false</Prefer32Bit> in the .csproj file.
Related
I have a native dll (which is an activex control) that I need use with my .NET application without having to register the dll in the registry.
I have read several in depth posts about registration free activation, some of the better ones are
A lengthy one from Steve White and Leslie Muller
This one from samuel jack
And another from Mike Makarov
and from what I can see it is possible. However several hours and hundreds of tests later I just cant get it to work. I've done a bit of PInvoking and even less with ActiveX controls in .NET in my career, so would appreciate any input from anyone whom might have kicked goals on this before.
So far I'm following Steves advice, in terms of building an application that works and then trying to formulate the winning manifest file syntax via repeatedly running the regsvr32 command to add and remove the unmanaged dll's from the registry. Just a bog simple .Net console application with about 10 lines of code...
One part that I am confused about is the interop. The native dll's I have are also accompanied with managed runtime callable wrappers (RCW's). In my .NET application I add reference to these RCW's and then can consume the respective classes and functionality provided for by the unmanaged dll's. I'm not PInvoking via dllimport.
In creating the manifest files I'm unsure if I need to worry about these RCW's and how they work in a registration free scenario, or even if if they need to be in the compiled output?
I've also tried several tools such as (OLE/COM object viewer, Mt.exe from the windows sdk, and regsvr42 from codeproject). But the manifest structure and necessary GUID's all vary between tools and posts.
Current status is that I receive a InvalidCastException "Unable to cast COM object of type System.__ComObject to interface type MyFunkyDllLib.FunkyDllControl. This operation failed because the QueryInterface call on the COM component for the interface with IID '{some guid}' failed due to the following error: Library not registered.
Can anyone confirm the correct syntax for the application and dll manifest files ? Online posts even vary on the name with some using sxs in the name....
Update1:
Whilst Joe's answer below did not work it did give me some better insights into reg free COM. In the properties of the Interop dll (the one that that is added to the project reference from the list of installed COM components on the dev machine) I changed the Isolated Property to True. This has the effect of making VS dump a copy of the COM dll (not the interop, it is embeded in the exe) to the bin\debug folder. VS also then creates a myapplication.exe.manifest.
In this manifest file is supposedly sufficent information for reg free com. I found other posts indicating success with this method but in my case I still ended up with the same InvalidCastException.
Reading over Samuel Jacks post again, I tried his method of creating both a manifest for the exe and the COM dll using the clsid information from the VStudio output manifest when Isolated=true. (I also deleted the <file/> section created by VS from the exe.manifest). After unregistering the COM from the registry I now have success ! The application starts and does not error.
Why this approach works and not the Isolated=true I have no idea because it is beyond my knowledge of manifests and assemblies.
However we are still not at the wizards castle yet Toto.
Now I'm back at the same issue I posted on this SO thread. However in this scenario unit tests are not involved. Just a plain console application with 10 lines of code. Works fine when in normal registered COM mode, but not in reg free mode.
After many hours of trial and error I finally got a solution to how to successfully implement RegFree COM.
Here is a full explanation incase it helps someone else.
I create a new .NET class library in VS
Right click references and select the COM components of interest.
(Note: for the COM to be visible in the list they must be registered
on the development machine. This can be acheived by using the
Regsvr32.exe tool included with windows. Calling "regsvr32
mycomdll.dll" registers it in the windows registry)
Right click the COM reference, goto properties, and then set Isolated=True. This has the effect of causing VS to output a .manifest file supposedly containing all the registry details necessary for a consuming .exe to know what resources to load instead of querying the registry. However in my case it was incomplete. Calls to Interop methods would work, but events from the COM component would not. See step 5 for my solution)
Build the project. The .manifest should appear in the build output.
Open the manifest in notepad or similar. Within the <assembly /> tag I needed to add a <comInterfaceExternalProxyStub /> tag with appropriate IID, tlbid and proxyStubClsid32 GUID elements. Elements of the manifest are documented on msdn. In my case the proxy/stub was proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/> which is the built in windows proxy. The iid and tlbid I originally discovered via Process Monitor whilst calling regsvr32. An easier and more reliable option I later discovered was to use a tool like SxS manifest maker as it added a second <comInterfaceExternalProxyStub /> that I originally did not have.
Create an exe project in VS and reference the previously built library.
Build the exe project.
Run regsvr32 /u mycomdll.dll. To remove all registry associations.
Run the exe. In my case calls to and events from the COM component in the class library worked perfectly.
Caveats: I dont know why VS does not include the <comInterfaceExternalProxyStub /> element automatically in the .manifest. At the time of writing the only way to automatically update the manifest was to add a post build Task in VS. In my case I copied the entire XML manifest into an XML in the class library project and then just overwrote the .manifest file in the build output.
Unit (integration) testing of the COM is inconsistent. Currently in my case calls to Interop methods work, but events do not. It has something to do with the fact that the Test Runner is not compiled with knowledge of the dependencies and therefore such are not present in the activation context.
You are probably missing a typelib declaration...but ignore that for now... Instead, do the following...
After playing with this on and off for a while, I decided that the easiest way to do it is using MSBuild and a GenerateApplicationManifest task. I've been using it with a unmanaged app, but I don't see why it would not work with a managed app. I say "app" ... because my app is managed but I have both COM libraries and .NET assemblies with ComVisible classes in them.
From your description it sounds like you are dealing with having COM and don't have to worry about consuming .NET assemblies from COM. You can google for MSBUILD and GenerateApplicationManifest to get an example MSBuild file.
So, I assume you will not need to populate the "Dependencies" attribute of the task. You will need to populate the "IsolatedComReferences" attribute with a list of your COM DLLs. They can be a simple semi-colon delimited list, but usually they are in "ItemGroup" declarations in the MSBuild project file. The COM DLLs need to be registered at the time you generate the manifest.
As for your RCW, there is nothing special you need to do. IMO, they don't need to be in the manifest. .NET has a way of finding them as long as they are in the same directory as your app/DLLs.
If you use MSBuild, you won't have to generate manifests for your COM DLLs... They probably already have manifests already... Usually, the wizards automatically generate manifests and embed them. The only manifest that will need the COM type information is the manifest you generate with MSBuild.
The whole point of the manifests used in this manner is to populate the manifest space with all the COM information that would be in the registry.
I'm pulling my hair out on this one...
I have a legacy application I built a few years ago that uses AutoItX - all working fine.
The time has come to try and update the app, so I've upgraded it to VS2012/.NET4 and I simply cannot get a reference to the AutoItX library to work.
I have installed the application, have registered the dll with regsvr32, tried every combination of property settings on the reference itself (Embed Interop Types / Isolated), but no joy.
The error I keep getting whenever I try and create an AutoItX3 object is:
Retrieving the COM class factory for component with CLSID
{1A671297-FA74-4422-80FA-6C5D8CE4DE04} failed due to the following
error: 80040154 Class not registered (Exception from HRESULT:
0x80040154 (REGDB_E_CLASSNOTREG)).
Is it an issue that I'm on a 64-bit machine? I'm not trying to use the 64-bit DLL version.
Okay the solution was:
Open up regedit*32 (c:\windows\syswow64\regedit)
Search for AutoItX in HKEY_CLASSES_ROOT\AppID
I found it in HKEY_CLASSES_ROOT\AppID{6E8109C4-F369-415D-AF9A-2AEEFF313234}
Create a blank REG_SZ (String) entry called DllSurrogate
For some reason, this completely solved the issue.
Reference: How to use a 32 bit COM object on Windows Server 2008 (works on 2008 R2 but non 2008)
Hainesy,
do you use a x64-Windows?
I had the same problem when I was starting to have a look at COM.
If so, you should try to register your class in HKEY_LOCAL_MACHINE\SOFTWARE\WoW6432Node\Classes...
Give it a try!
Greeting
I've faced with following problem:
I have an ActiveX Control , on dev machine it is working as expected ,
when trying to create it on other machine I am getting the following error
Error: The system cannot find the file specified.
I am using following line to create it:
var activeX = new ActiveXObject("ScannerViewerControl.ScannerViewer");
I've used installshield for deployment , and marked .NET Com Interop.
I am able to find in registry path to the .dll under HKEY_CLASSES_ROOT.
What am I missing ???
You are probably missing a dependency for the active-x DLL on the client machine. Depending on what version of VS you have installed, you might have a tool called depends, which you can point at a DLL and see the dependencies that are required.
I'm trying to use a 3rd party COM DLL (I don't believe its a .NET component) from a .NET service without registering the COM DLL but I'm having no luck so far.
I've copied the manifest files from here (http://stackoverflow.com/questions/465882/generate-manifest-files-for-registration-free-com) to use as a starting point (I generated the COM DLL manifest using the referenced mt.exe/regsvr42.exe). However all I get is the following error:
Exception: System.InvalidCastException
Message: Unable to cast COM object of type 'LOGICLib.LogicClass' to interface type 'LOGICLib.ILogic'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAA3E8FB4}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
Source: Interop.LOGICLib
at LOGICLib.LogicSecuredClass.Connect(String IP, UInt16 Value, Int32& Result)
at My.Server.MyAssembly.Loader.Connect() in D:\MyProject\Source\Server\MyAssembly\Loader.cs:line 461
The application manifest is named after the exe that starts the service - I've also tried naming it after the assembly that calls the COM DLL. I've tried starting on the command line and via Visual Studio's debugger. I've also tried using the Interop file supplied by the third party and generating my own.
(Note - I've only tested under Windows XP so far.)
I've spent two days on this now and have not progressed at all. Any ideas what I may have missed?
The application manifest is named after the exe that starts the service
Yes, this does not work. Windows always looks for a manifest in the EXE itself, embedded as an unmanaged resource. Only when it cannot find one in there will it look for a .manifest file on disk. Problem is, a managed program built with VS2008 and up already has a manifest. The default one says "I'm Vista aware" only.
You can verify this for yourself by using File + Open + File and selecting your EXE. Open the RT_MANIFEST node and double-click resource 1. If you don't see your reg-free COM manifest entries there then it isn't going to work.
To fix, use Project + Add New Item and select the Application Manifest File item template. You'll get the boilerplate manifest, copy and paste your regfree COM entries in there.
Well, from the exception, you're getting a cast error when trying to cast an object of type LogicClass to an interface type of ILogic. Looks like LogicClass doesn't implement ILogic.
You didn't supply what the DLL is or where you got it, so you're best bet is to look at the documentation for the library you're trying to use. Just a wild guess, but it looks like you're implementing it incorrectly.
I'm trying to get a third party app (hMailServer) to consume my C# library. They support 3rd party libraries using VBScript hooks. I got everything working fine using registration-full COM, but now want to use registration free.
I've modified the hMailServer.exe manifest and added a manifest to my C# library. Now the hMailServer service starts up just fine and SxS trace shows that the library is found. If I neglect to create my C# library manifest I get an error that "Windows could not start the hMailServer service on Local Computer... because its side by side configuration is incorrect" and sxstrace gives errors so I know the manifests are fine. However, the VBScript events fail to run with the following error:
Script Error: Source(null) - Error:
8013101B - Description(null) - Line: 2
Column: 1 - Code(null)
The first 2 lines of the VB6 script just read:
Dim oHandlers
Set oHandlers = CreateObject("hMailServerPlugins.EventHandlers")
(hMailServerPlugins.EventHandlers is obviously the name of my COM visible class)
As mentioned, everything works just fine with COM registration. Any idea what I'm missing?
This may be a bit late, but I've seen this error if you've mixed .Net framework versions. If you've spun up a CLR of a lesser version first, then attempts to create a C# COM object using a newer framework after the fact will fail with that exception.