I am creating a excel application in VB.net using VisualStudio 2008.
while adding reference Microsoft.office.interop.excel we have both managed ( On the .NET TAB) and unmanaged (on the COM TAB).
currently i am referencing the COM tab but it is not showing the errors properly.
can i use the excel interop on .NET tab?
which one is the better way to reference and what is the difference between those two?
Yes, do use the .NET interop library to create the namespace 'Microsoft.Office.Interop.Excel'
Then define an application object with
Private app As Microsoft.Office.Interop.Excel.Application
and either a) connect to an a running Excel application with
app = CType(GetObject([Class]:="Excel.Application"), Microsoft.Office.Interop.Excel.Application)
or b) create a new Excel application with
app = CType(CreateObject(ProgId:="Excel.Application"), Microsoft.Office.Interop.Excel.Application)
Good luck!
The .NET version of the Interop library is basically the COM component in a .NET wrapper. It is advisable to use the .NET implementation.
Related
Since VSTO has yet not been ported to .NET Core, can I do it the old fashioned way and create a unmanaged shim to load the CLR and host the managed .Core 5 add-in?
My particular use case is an Outlook COM add-in that is currently built using VSTO against .NET framework 4.7 but I want to start leveraging .NET 5. In terms of interaction with Outlook, it just adds some buttons on the Ribbon and makes a few calls into the Outlook object model. I don't need to do anything like VSTO document based add-in in Excel for example.
I don't want to down the JS path as there is quite a bit of C# code that would need to be ported.
I found this https://github.com/jozefizso/COMShimWizard/releases which shows how to do it with the .NET framework, and am assuming its pretty close if not identical to what the shim wizard did back in VS 2010.
Since I need to load .NET 5 I believe to load the CLR I will need to do something along the lines of what is outlined here: https://learn.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting.
Before I dig further into it, is the approach likely to work? In particular, will in be possible to do necessary COM gymnastics to instantiate the managed components?
And assuming all this is feasible, will this be more or less equivalent to what VSTO does for .NET framework 4.x, i.e. is it less safe or performant in any way or will there be any functionality that won't be available compared with an add-in built with VSTO?
Update 1
I did some more research which raised some additional potential issues.
For the .NET framework case, once a class has been loaded into the CLR it is relatively easy to "unwrap" the returned reference to get a COM pointer which can be used to access COM interfaces that the type implements. It is not clear to me how this can be done when loading the .NET Core runtime using netfxr interface.
.NET Core does not have the concept of app domains, does that mean the multiple add-ins loaded into the Core runtime would not be isolated, or there a way to achieve some degree of isolation? From what I have read it seems that maybe their heaps would at least be isolated but I'm not sure.
Update 2
From reading this https://github.com/dotnet/runtime/blob/main/docs/design/features/COM-activation.md it seems that in Core, requests to types in assemblies as COM servers will result in auto loading the Core runtime (if it isn't already loaded) and create the object in a separate AssemblyLoadContext so maybe a shim is not needed at all? On the other hand it seems that if the Core runtime is already loaded and the version does match what is required by type you are trying to create, then the type will fail to load, so that seem to be a problem...
I successfully created in VB6 the VB6_IDE_Add_In, that has references to Microsoft "Visual Basic 6.0 Extensibility". However, to use this add-in in VBA IDE (Excel, Access) I obliged to make a copy of VB6_IDE_Add_In project, rename it to VBA_IDE_Add_In, rename its properties etc. and, the main, change mentioned reference to "Microsoft Visual Basic for Applications Extensibility 5.3".
Finally I have two dll - the one for VB6, and the second - for VBA. Both of them I must to "regsvr32" and manually move VBA-IDE-Add-In registry key from VB6 key "[HKCU\Software\Microsoft\Visual Basic\6.0\Addins]" to VBA key [HKCU\Software\Microsoft\VBA\VBE\6.0\Addins]...
Is there a way to compile a single dll that will use right reference accordingly to the VB6 or the VBA environment, using conditional compilation or command line parameter?
Unfortunately, this is my first add-in and my experience is insufficient in this matter...
I doubt you'll be able to compile a single add-in in VB6 for VB6 and VBA, as both libraries share the same name VBIDE and your VB6 project won't allow two references with the same name. MZTools 3.0, when it was written in VB6, used to publish a version for VB5 (which uses yet another, earlier version of VB extensibility library), VB6 and VBA. Since the release of MZ Tools Version 8, the source has been migrated to .NET, and it is much easier to support multiple environments and 32-bit/64-bit versions of VB/VBA hosts.
You would be wise to follow the lead, and develop a solution using .NET. A .NET solution like MZ Tools, or Rubberduck VBA, can be used by 32-bit and 64-bit hosts, and by creating your own Interop Assemblies (and embedding their types) from the VBIDE type libraries, you can create a single dll for VB5, VB6 and VBA.
Rubberduck VBA hasn't yet added support for VB6, but we're working on it:
Shared VB6 and VBA extensibility add-in with OnConnect and OnDisconnect handling
I want to create activeX objects (.OCX files) using VB.net visual studio 2010 or 2015.
Is there any way to create activex objects using these tools.
In my project i have software like graphics builder it will accept activex objects, by registering it.
So i want to create some new customized activex objects.
.Net Cannot create pure ActiveX controls.You can create a .NET DLL with a COM callable wrapper, which is actually a .DLL, using the COM Class.
If you don't need to call the component from a COM then create a standard .NET DLL.
I'm facing problem while reference vb6 dll in .net project. When ever i refer a vb6 dll in .net project the interop dll is created with same version(1.2.0.0). Its creating problem for me as the setup used to deploy the application at client side does not replace the dll if the version is same as before. I want to change the version of the interop dll (created using vb6 dll). I read it cam done using tlbIMP but how to create tlb file for vb6 dll. Or is there is any other way to achieve this.
Thanks
Saurabh
Here's a small batch file we use to create our interop dll so it's strongly named:
sn.exe -i MichiganLTAP.pfx MagicContainerName
tlbimp.exe ourVb6.dll /out:Our.Strongnamed.Interop.dll /asmversion:7.1.0.0 /keycontainer:MagicContainerName /machine:X86 /namespace:Our.Strongnamed /verbose /sysarray
sn.exe -d MagicContainerName
The important switch from your perspective is: /asmversion:7.1.0.0
You should be able to set that to whatever you want. Check out the MSDN Library page for more info on the switches available.
It makes very little sense to make the version number of the interop library different from the version number of the type library that was created by VB6. There is a one-to-one mapping between what's in the interop library vs the code you wrote in VB6. The interop library simply contains IL declarations for the VB6 COM interfaces, there is no actual code. The CLR uses it to quickly generate the RCW for the interface.
Change the type library version number in VB6 with Project + Properties, Make tab, Version number. Major and minor is what counts. Do this only when you make a change in the publicly visible VB6 classes. Doing so is required btw, it avoids DLL Hell.
I am very new to VB.net. I have written these objects in VB6 before. I'm just lost in VB.net, but (kicking and screaming) I have to learn how to do this. I've been googling for hours with only minor steps forward. Can anyone post a link that explains start to finish how to do this?
I have managed to write the class object, What I can not tell is how to register it and where the name1 and name2 in the CreateObject("Name1.Name2") come from.
Regsrv32 will not work. It says "Entry Point not found" and will not register it. Also, I can not drop it into the Assemblies directory. I read something about a regasm command one uses, but I can't seem to make this work either.
Thanks in advance for any assistance.
I am going to assume you are not trying to write a COM DLL but rather a complete project that call various sub assemblies like a VB6 EXE call a ActiveX DLL. If you can be more specific about what you are trying to do it would help me better.
Several points about VB.NET versus VB6.
1) For .NET only projects there is no registration. If a EXE or DLL references another .NET DLL the only requirement is that the DLLs be present in the parent's directory.
2) You can do a COM style registration for .NET apps only by registering the .NET assembly in the GAC. However there are several requirements for doing this. Do a search on the .NET GAC and it will give you the scoop on how to do this.
3) You can setup the .NET assembly to use COM in which case it will operate by the rules of COM including registration with regsvr.
You will find for .NET only project that #2, or #3 only come in rare instances. #1 will apply for 90% of your DLL assemblies. Of This is dependent on your project.
A common use for CreateObject is allow for plug-ins or installable libraries. .NET handles this through the Reflection API. With the reflection API you can look in a directory, go through each .NET DLL and see what them and create objects from what you find. Search for .NET Reflection to read up on this.
If your project is .NET only then I recommend that you create a Assembly that is reference by both the master assembly and the individual sub assembly that define the interfaces of the objects you are creating. This when you use the reflection API and determine the Object type you can assign it to a variable of that interface and code it noramlly with intellisense and other aids.
if you have old COM ActiveX Controls or DLLs .NET will generate a wrapper class that exposes the ActiveX Objects to .NET. I would spend some time learning how .NET does this. What I do create a dummy project and have .NET reference the ActiveX stuff I need. I then find the wrapper projects and DLL it made and move them into a central area. That why when I work on subsquent projects using the same ActiveX stuff I know where all the wrappers are.
You have to go to your class library properties and select the option "Register for COM interop". This will make your assembly available to COM.
You want to create what's called a COM Callable Wrapper (aka CCW) for your .NET component. This basically entails setting up some COM interfaces with some GUIDs and either enabling "Register for COM Interop" in the project properties (as mentioned) or using regasm.exe.