I need to pass a Scripting.Dictionary between my C# app and another app. I would like to be able to create instances of and modify the dictionary in my C# app.
I know little about Scripting.Dictionary and ActiveX in general. Various forums suggest that I should use functions like System.Type.GetTypeFromProgID() and System.Activator.CreateInstance() to create an instance. Unfortunately this means that it's an opaque object to the rest of my code.
Is this really how it's supposed to be done or is there a better way? Ideally I'd like to import a compile-time type and just use it like any other type. Is this possible?
This article suggests I obtain a "metadata assembly" from the vendor - does anyone know if such an assembly exists for Scripting.Dictionary?
I've just tried the easiest approach, and it seems to work:
Add a COM reference to the scrrun.dll in Visual Studio (it should show up in the COM tab of the Add References dialog), and Visual Studio will automatically create the interop files for you. You can then write code like this:
Scripting.Dictionary d = new Scripting.DictionaryClass();
d.Add( ref myKey, ref myValue );
MyComType.Method( d );
If you have any trouble with that, I can post some more examples, or perhaps a clarification.
Create a wrapper dictionary class which implements IDictionary and which uses the Scripting.Dictionary as its internal storage implementation. Use the wrapper in your .NET code and pass the inner Scripting.Dictionary via COM to the other app.
Related
First, I realize that there are many posts here that discuss this topic. I must have read 20+ of them, easily. But none of them give the answer that I seek.
I have written a tiny C# test COM DLL with a single method in it that prints "I am alive!" in a message box. Using VStudio as admin, I can build and register the COM object. I have successfully called the object from VBA and run the method. And I can see the name of the COM Interface in the VStudio Add Reference / COM dialog box. This all makes me think the object is properly constructed, registered, and usable.
Now I'm trying to call it from a console C# app. Like many others, I'm trying to figure out the equivalent of the VBA "CreateObject("DLLName.ClassName")" code to get hold of the object in C#.
One way is to just add a reference to the DLL to my console app project. I point to the assembly through the Projects section of the Add Reference dialog, not through the COM section of the dialog. Then I can simply say var o = new MyComImplementationClass(); and treat it like any other class. That works, but it means my console app is cheating and not using the COM object through the usual COM GAC interface.
Another way (that doesn't work, but I wish it did), is to add the reference through the COM tab on the Add Reference dialog. I can see it but VS protests that "the XXX.tlb file was exported from a .NET assembly. Add a reference to the assembly instead." Which brings me back to the solution above, which I think means that my app is cheating. (I didn't have to add references to my VBA test app, for example.)
Another way is to use Type.GetTypeFromProgId as shown by this code fragment below. But I can't get that to work either. I must be passing in the incorrect ProgID string - I get the sense it has something to do with registry info and is not the same "DLLName.ClassName" string that I feed CreateObject() in VBA.
public static dynamic ComObjectGet () {
const string progID = "ComExampleDLLName.ComImplementationClassName";
Type foo = Type.GetTypeFromProgID (progID);
dynamic COMobject = Activator.CreateInstance (foo);
return COMobject;
}
Worse yet, on this MSDN example page it says "This method is provided for COM support. Program IDs are not used in Microsoft .NET Framework because they have been superseded by the concept of namespace." So probably I should not be using the GetTypeFromProgID at all.
If it helps any, I can use VSTO in C# to call the MSOffice primary interop assemblies. But they load from the COM tab of the add reference dialogs (which is where I want my COM library to load from).
For clarity, my COM DLL name is ComExampleLibrary.dll. The default namespace is ComExampleNamespace. The interface name is IComInterface, and the implementation classname is ComImplementation. The internal method name is Run.
Could someone give me instructions or a code snippet that does the "right, approved" thing for calling COM objects (not just the ones I write) from C#? Thank you.
Thanks to the people who helped me out, here is the answer. Both GetTypeFromProgID and GetTypeFromCLSID work as shown below. My problem was that I was using "AssemblyName.ClassName" instead of "Namespace.ClassName" in the call to GetTypeFromProgID.
public static dynamic ComObjectGet () {
const string progID = "ComExampleNamespace.ComImplementation";
Type foo = Type.GetTypeFromProgID (progID);
//var bar = Guid.Parse ("99929AA7-0334-4B2D-AC74-5E282A12D06C");
//Type foo = Type.GetTypeFromCLSID (bar);
dynamic COMobject = Activator.CreateInstance (foo);
return COMobject;
}
So my original code was correct, but I was passing in the wrong argument. This snippet is the equivalent of the VBA CreateObject("Namespace.ClassName") call.
I still don't know why I cannot add a reference to the COM item in the COM tab of the Add Reference dialog like I would for any other COM object. I suppose that's a different question.
Is there in C# connect to COM-object and use contents of com-object such as in the Builder c++:
CreateOleObject("some.someClass");
(OLE C # seems to be not supported, except OLEDb, but it is not the current case in my opinion)
I know I can add a link -> COM -> Seeking a registered com-object.
But it does not fit.
Normally, if you need to use a COM object in C#, you would add it as a Reference, and select the registered type library. That will generate an Interop Assembly, after which you can use the COM object just like any other C# class.
Alternatively, you can run the .NET utility tlbimp by hand, which has roughly the same effect but gives you slightly more control.
If you really need to create the object dynamically, without knowing anything about the type ahead of time, you can use the dynamic keyword and the Activator class to create a dynamic instance of a type. The code would look like:
var comType = Type.GetTypeFromProgID("some.someClass");
dynamic obj = Activator.CreateInstance(comType);
This will defer all type checking on obj until run-time, behaving much like VBA would.
I have 2 projects, in one project I have one form and class with different information, this information is acquiring only during runtime, now in another project I have another form, that will use the object of the first class to get the information and to put it inside form.
Basically I did some research and tried using Reflection for that, but all of the examples I found didn't work properly (actually didn't work at all).
Assembly a = Assembly.LoadFile("Server.GUI.LocalGUI.dll");
object o = a.CreateInstance("ServerManager");
Type t = o.GetType();
this is the code that I tried, not sure if it's correct...
I am using .net 2.0
Is anyone have working example of how to use data of one object in another dll on the runtime?
I have 2 projects : MyForm1 and MyForm2. Take reference of project MyForm1 in MyForm2. Fill MyForm1. Create a instance of the MyForm1 in MyForm2 and access the method and its value.
Or create another Library project. Expose a static variable in it. Take reference of this library in both the Forms projects. Assign some value from MyForm1 and access the same property in MyForm2.
But if you really want your code to be a managed code, try learning and implementing MVP. It may give you a new way to look at solutions for your problems.
You can even create both forms in same project. Process the data in a separate library.
if that is want you want to do - the you could do it like this:
Assembly a = Assembly.LoadFile("Server.GUI.LocalGUI.dll");
dynamic o = a.CreateInstance("ServerManager");
o.Method();
But i don't recommend this, unless you absolutly have to. Using the dynamic keyword can be at shortcut - but sometimes a shortcut to a place you don't want to go..
I know, I'm taking a gamble here. I don't know if I can even be helped on this one at all. But, here is the problem.
The company I work for has a fully licensed, if old, developer copy of DTSearch including the C++ source. They use this in an application I'm updating. I've been told to make use of it in the C# additions to this app that are currently being worked on. However, I don't have the .NET assembly and they refuse to implement it for some reason.
So, I can easily view dtengine in the Object Browser and there are lots of lovely objects waiting for me to use them. But none of them will instantiate. Attempting it gets me
'dtengine.SearchJobClass' cannot be embedded. Use the applicable interface instead.
And there are interfaces galore, I can easily implement any of them. Trouble is, "throw new NotImplementedException" doesn't exactly get my searching done.
Does anyone have any clues?
I've used some COM objects that you have to instantiate like so:
Foo f = new FooClass();
Does the DTSearch have similar looking class names?
I also believe that COM interfaces are special and that you can instantiate a COM object by it's interface though I'm having a hard time finding good examples.
I did find this:
http://www.codeproject.com/KB/COM/COMBasics.aspx
note that if you scroll down you'll see them instantiating the Interface in a special way. I'm not saying this is a solution but it may help in your investigation of how to use the DTSearch COM wrapper in your application.
I am new to COM and need to add a Server COM object to my c# application so I can call its methods and implement events. The documentation I have says this requires a COM-aware language such as Visual C++. My app is written in C# so I'm not sure how this is going to work. Any direction would be appreciated.
I am writing an app that communicates with a serial hypercom terminal. The device came with a DLL (the com server interface) that I will need to figure out how to use in my c# application.
I added a reference to the DLL to my project, which shows up as a type library. In object explorer I get interfaces, and some classes etc.
Thanks,
Matt
You can add the COM object as a reference. .NET will create an interop assembly to work with the COM object, just like it was a .NET type.
CComObjectRoot can be used as a base class for all COM objects implemented with ATL. As such you don't have to worry to implement something similar in C#, the required methods (AddRef, Release, QueryInterface) will be generated by tlbexp for classes that are tagged with ClassInterface.
STDMETHODIMP is a define which serves to declare the most common methods that can be called from COM (#define STDMETHODIMP HRESULT STDMETHODCALLTYPE). Again if your class is tagged with ClassInterface you will not have to worry about.
Such construction is required in C++ when your class implements several interfaces. I think this is not required if you tell C# compiler that your C# object implement IDispatch, IFPESOlementationEvents. The appropriate code will be written automatically by the compiler.
Probably everything will not make much sense if you are new to COM and C#, I'll suggest to take a look at the various introduction that you may find on the web, like this.