How to write C# to call vb6 code? - c#

I have an activeX DLL in VB6 , and i've been asked to run some tests with it. since i dont have VB6 environment anymore, i thought it'll be best to try and make a simple C# program that will call the registered COM Dll. to do that i copied the DLL into c:\windows\system32, used regsrv32 to register the DLL, restarted the computer and this DLL is added to COM so I added it to my project and referenced to it from my project. I created an object from it and tried to invoke a function from that but there is nothing available but DllUnusedClass and DllUnused.

You say you've added a reference to the COM dll to your project, now I would right click on the reference and select "View in object browser". This will show you which types are available in the referenced dll.
It may be you're not creating the appropriate type of object, so viewing it in object browser should help you decide which type of object to create.

Make sure that any class you have in the VB6 project, that you want to access from your .Net application, has the Instancing property set to 6 - GlobalMultiUse so that it is in scope.
I have tested your scenario with the Instancing property set to the default 5 - MultiUse and experienced the same issue you described.

Related

Unable to detect COM wrapped InterOp

I have a library in C#, which i have exposed through COM to an unmanaged application in C++. On one machine, everything seems to have gone well. The interface is visible, is exposed, and the application is able to view it successfully, and use its functions.
On another machine, however, the .NET COM InterOp DLL is simply not visible to the calling application, I cannot debug on that machine so it is not immediately clear where the error is. I get a COM exception which indicates that I failed to create the COM object.
The DLL is present in the GAC, and the class is also registered in the registry, with the same class GUID as I have specified for it.
I have tried moving the assembly to the local folder, but still no detection. The DLL is dependent on another assembly which is present with it in the same folder. Moreover, the object creation for the other DLL, is dynamic and so it should not affect the object creation for the first assembly.
I might be overlooking a simple, fundamental step, since COM is new to me.
What could be the possible reason?

How to make my dll loadable from codebase only?

My project(some kind of processing engine) is separated into 2 dlls: one with interface declarations and one with functionality.Usually the project is used by external Delphi project via COM technology.
Lets say my program slices fruits. External delphi programm creates Fruit object and fills its properties: weight (int), Name (string) and ProgressUpdater (of type IProgressUpdater which is declared in second dll with interfaces).After this exst programm creater Slicer, makes Slicer.AddFruit(newFruit) and calls Slicer.Slice().
Nothing special. In real life delphi project is Outlook addin. But here is the problem - sometimes some VSTO addins makes Outlook work in "shadow copy files" mode, so when delphi project starts and creats Slicer object, our c# assembly will be put in temp folder and assembly will be created with this local path. Well... this is still not an issue. But the problem is when delphi project creates newFruit and then passes ProgressUpdater object, in my Slicer assembly I can not get external ProgressUpdater: "Return argument has an invalid type", but still can get field with simple types(Weight, Name).
It only happens when shadowCopyFiles mode is on. So my guess is - external ProgressUpdater's assembly and Slicer assembly are placed to different places, so they can not be passed. My question is how to avoid my dll being "shadow copied"? Or is there some different solution?
So as a result I still have no answer for exact question. But the problem is solved (thanks to HansPassant) by using GAC, because assemblies at GAC will be never shadow-copied (actually linker will always first probe assemblies in GAC and then in other places).
Possible answer to the question is to go currentDomain.AssemblyResolve way, but I could not apply this solution to dll which contains public interfaces(types) only. Maybe it will be suitable solution for some cases.
You can use reflection to load DLL dynamically from any location you want. If you can go this way, I can provide further code for loading DLLs.

ActiveX component can't create object? .NET COM

I am currently trying to reference a .NET COM library in my Visual Basic 6 application. I have registered it, using Regasm and I have set ComVisible to true within my class. However when I try to run my application i get the following error:
ActiveX component can't create object.
My library consists of a very simple function (since I just wanted to test if I could even run it), it just returns the string "Hello World".
I had to use a different machine (machine 1) to create my C# .Net class and then copy that class onto another machine (machine 2) and from there register the dll and reference it in my project. I then tested my project on a separate machine (machine 3) which is were I received the error.
I really need help with this, I have already tried to un-register and re-register it and still to no avail.
Try this.
From an elevated command prompt:
RegAsm /codebase /tlb AssemblyName.dll. Take note of the .tlb file generated.
RegTlib File.tlb
Open your VB6 project and reference the .tlb file.

C# DLL noob, how to get functions

I've been given a dll to talk to a device, I have little to no experience in C# and I'm supposed to get the device initialized by the end of the week. The dll has methods to open ports and send messages, but I have no idea how to get access to the functions
I know its a bit ridiculous to ask but im running out of time.
Thanks,
Add a Reference to the .dll file in your C# project.
Add a Using namespace at the top of whatever class is going to interact with the .dll methods.
You will now be able to access the methods.
Edit: If your library is unmanaged you'll have to use Pinvoke.
Generally speaking, a feature to call from managed code into unmanaged code (which I assume your DLL is) is called P/Invoke and generally involves annotating required static extern methods with attributes.
Add a reference to the dll in your project (selet browse to find it) and you should be able to access the functions within. As for how to make your device work with it, I think you're on your own :)
If the DLL is a .Net assembly, you can load it into a Visual Studio project by adding it as a reference.
In the absence of documentation, it can also be extremely helpful to load the assembly into .Net Reflector, which lets you inspect the guts of the assembly, even to the point of disassembling the code inside the methods.
1- If it is managed Dll , i.e. Written using .net framework than calling a method from the dll is like you are calling a method from your own class.
just add the reference of the dll in your project and include the namespace reference by 'Using' keyword.
2- If it is not than you need to import your dll dynamically, you can use [DllImport]

Can a referenced DLL be loaded even if it's not called?

Env.: .NET / VS2008
Hi All,
My app uses a 3rd party DLL assembly separately installed on some systems (clearly identified) but not all of them.
Which means that on some systems, the DLL is not there hence must not be called. To solve this, I have 2 versions of the app (using 2 configurations) for the 2 use cases. In one of them, all calls to the DLL are #if'ed out.
Since there are no calls to the DLL compiled at all in the app(they're #if'ed out), is it safe to assume that the app won't try to load the DLL even though it is referenced?
Or should I also exclude the reference?
Note: Asked in reaction to womp's comment in this question.
TIA,
IIRC, the C# compiler will omit references to dll's that are never actually used in the code. So if all code is inside #ifs, the reference to the dll will not be there in your compiled app, and the dll will never be loaded.
You can check this using Reflector, by the way. Just drag & drop your compiled app into Reflector, and look at the References node. ILDASM also provides this feature, I think.
Caveat: DllImports and dynamic type loading (e.g., Type.GetType("type,dll")) will dynamically load dlls without the C# compiler knowing or caring. But again, if inside the proper #ifs, nothing will be loaded.
I would exclude it. It might load it no matter what and if you have a type reference, then that also could cause a problem.
Why not load the the assembly dynamically if needed/available? And then if its gets added at a later date you can just make use of it? You'll only need one version of your app also.
You are safe with a reference but without the actual DLL if you never (obviously) instantiate and referenced class AND never refer to the Class in any instantiated or referenced object.
Typically your DLL will be loaded the first time the Class Constructor of a referenced Class is run.
HTH
Jan

Categories

Resources