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.
Related
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.
I am using XSockets for having two way (web socket based) communication between an XSockets Server and an existing C# desktop client application.
I have integrated code in my existing client application for communicating with XSockets Server.
For now, XSocket Server starts as a separate console application. It starts fine with no problems.
Then I am using following pseudo code block in my C# client application:
XSocketClient client = new XSocketClient("ws://127.0.0.1:4509/MyController", "*", false); //Error occurs right on execution of this line
client.Open();
Following is the Exception snapshot that throws out;
Exception of type 'XSockets.Plugin.Framework.Exceptions.ExportException' was thrown
Custom Message: Failed to load exported interfaces in assembly Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Source: XSockets.Plugin.Framework
Stack Trace: at XSockets.Plugin.Framework.Composable.SatifyImportsExports()
at XSockets.Plugin.Framework.Composable.Initialize()
at XSockets.Plugin.Framework.Composable.GetExport[T]()
Type: System.IO.FileNotFoundException
Note: If I create a new C# windows form client project and try executing this code, it executes fine and connection is successfully made to the XSocket Server.
Means there is something disturbing from inside my existing client project.
What could the possible reason for this weird exception ? Any ideas? Thanks
Edit: I have noted that if I manually remove Microsoft.Practices.EnterpriseLibrary.Validation DLL from my Bin folder, it raises same kind of exception but with a different custom message this time. I mean then the error is related to some other DLL (of my existing application) present in Bin folder.
I ran into a similar problem yesterday and solved it like so:
Composable.ClearPluginFilters();
Composable.AddPluginFilter("XSockets.*.dll");
This code was called just before I bootstrapped my application and started my server. I know the question is kinda old but if anyone else end up here aswell.
Source from Google Groups
Ok found answer to my own raised question.
There can be two things related to this issue:
Microsoft.Practices.EnterpriseLibrary.Validation.dll was causing problem from the Bin => Release/Debug folders. From Visual studio project references list, right clicked the Microsoft.Practices.EnterpriseLibrary.Validation reference, clicked on Properties and set [Copy Local] property to false. XSocketsClient was now connecting successfully to the XSockets Server but some other logic of my existing application was still needing Enterprise Library which being Copy Local ==> false, was not coming available to the .Net Runtime, so it showed an Exception whenever Runtime was coming across those parts of code.
To resolve the later issue encountered because of removal of Enterprise Library reference, I added again Microsoft.Practices.EnterpriseLibrary.Validation reference and also added one another DLL Microsoft.Practices.EnterpriseLibrary.Common.dll and added its reference to my client application.
Now my client application connects fine to XSocket Server and also now no issue comes with the inclusion of Enterprise Library reference.
Seems like there are some things essential needed by Enterprise Library at runtime which lie in that second DLL.
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.
We got a DLL written by C# programmers, compiled to usable as COM object.
We consult these developers to get the function names, and syntaxes, and we can use it after we registered it with regasm.
This is ok, but we have more questions to produce faster development (on changes), and some things are not understandable or not working.
We used Delphi 6 professional, and assembly made by C# Visual Studio 2008 (as I think).
Let's see them:
1.)
I cannot use the typelib (TLB) of the C# code, because I cannot import into Delphi.
The result was:
"Hiba az OLE beállításjegyzék használata közben."
Translate ~ "Error occured on use OLE typelib/setting lib"
Possible sources of the error:
a.) Delphi 6 cannot import the new COM dll-s.
b.) We must force to C# generate an older formatted TLB.
We tried to re-generate the TLB with regasm, but we also got this error.
May this impossable, but if case b.) happens, what we need to say to C# developers - how to compile the DLL-s?
(DLL-s are unimportable by Delphi, because they don't have self init section).
2.)
Interesting:
All of the parameters correctly converted into variants vica-versa, but if the C# method does not have parameter, I got error in Delphi side...
For example (pseudo):
proc A():bool;
Calling of A is generating an error in Delphi side.
proc A(Dummy: bool):bool;
Calling of A(False) is working fine.
I don't know, why we got this.
What do you thing about this? Is this a C# compiling problem?
Thanks for your help:
dd
Best route here is to obtain source code showing the successful use of the DLL via COM using, say, C#. The developers of the DLL should be able to provide that. The DLL probably also has to be registered with regasm (not regsvr32.exe as it would be for a native COM DLL) before it will be accessible via COM. As always, without more actual code, it is very difficult to answer such questions.
I've been trying to get a registration-free .NET based COM DLL to work, but without success.
In Visual Studio 2008 I added a new C# class library.
I enabled the 'make assembly COM-visible' and 'register for COM interop' options.
I added a public interface and class with some functions.
I added a manifest dependency to my C++ client application: #pragma comment(linker,"/manifestdependency ...
But when I start my application I get 'the application has failed to start because the application configuration is incorrect'.
I've used Microsoft's mt tool to extract the manifest files of both the C++ client application and the C# COM DLL and the information in both is the same (the dependentAssembly in the C++ manifest file contains the same name and version as the assemblyIdentity in the COM manifest file).
I've also tried the approach described on http://msdn.microsoft.com/en-us/library/eew13bza.aspx but with similar results.
Similarly I tried to add a reference to my COM project in 'Framework and References' of my C++ client application. The information on that property page looked promising (it shows options like 'copy local', 'copy dependencies', etc and properties like the 'assemblyIdentity'), but Visual Studio neither copies the DLLs nor adds a dependency to the manifest file automatically.
Note that the 'registered variant' works fine.
Anyone have any ideas of what I'm doing wrong?
Update:
When I create a simple C++ DLL and embed a manifest with the same name and version of my .NET COM DLL (same assemblyIdentity) my application starts up fine. So the problem lies with the manifest file of my .NET COM DLL.
I can successfully extract the manifest from the DLL with mt -managedassemblyname:... and then embed the same manifest with mt -outputresource:..., but this also doesn't cause Windows to successfully resolve the dependency.
I found the steps needed to get registration-free .NET COM interop working myself :-)
Run: mt -managedassemblyname:"myDll.dll" -out:"myDll.manifest"
Clean manifest (see format at http://msdn.microsoft.com/en-us/library/eew13bza.aspx). Mainly I needed to remove all tags except for assemblyIdentity, clrClass and file (and specifically remove the runtime, mvid and dependency tags).
Run mt -outputresource:"myDll.dll" -manifest "myDll.manifest". Basically this adds the modified manifest as a resource to the DLL. Note that this is apparently not the same manifest (location)! If I reextract the manifest with the managedassemblyname option I still get the 'old' manifest. If I extract it with the inputresource option I get the new one.
I pretty much found this all thanks to Windows Vista. Unlike my Windows XP it contains a tool called sxstrace that gives rather detailed information about the problems with side-by-side execution.
When I did this, I started with a very simple, basic component to get the COM stuff sorted. Also I used a script client in the initial development.
I did not use Visual Studio, but instead a text editor for the .NET code. I inserted the GUIDs for the assembly and for the Interfaces, and marked the interfaces for AutoDispatch.
using System;
using Interop=System.Runtime.InteropServices;
namespace Whatever
{
[Interop.Guid("xxxxxxxx-9120-4283-b972-changethis05")]
[Interop.ComVisible(true)]
[Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
public partial class MyClass :
...
}
I made sure my class had a default (no-arguments) constructor.
I ran regasm /codebase by hand, from the command line, specifying the .NET assembly.
I hand-coded the javascript to instantiate the object.
When things were confusing, I checked the ProgId with OleView.exe.
Once you have the very basic stuff working, add complexity gradually, until you get the working solution.
You can also use the approach from the other direction; from the client. .NET Assemblies like System.Random are marked for COM interop when you install .NET, so you can use them to verify that your approach in C++ is correct. Instantiating a System.Random ProgId is something like the "hello, World" of C++-to-.NET-via-COM. If that succeeds, then you know the basic approach in C++ is sound.