2

I have VS 2015 and want to create a VB.NET DLL to be called from VBA.

When I try to compile and get the DLL, I get "Impossible to write assembly: access denied, make sure you have admin rights" (approximate translation) ==> a compilation error

However, amazingly enough, the DLL does get created, but cannot be linked from VBA.

How can I still do it? I do not have access to admin rights, workspace constraints...

I tried :

VB.NET code is dummy, to check the link :

Public Class main
    Public Function plus(x#) As Double
        plus = x + 1
    End Function
End Class

PS: the error:

1>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(4335,5): error MSB3216: Impossible d'inscrire l'assembly "D:\Full_Path\bin\Debug\LibName.dll" - accès refusé. Assurez-vous que vous exécutez l'application en tant qu'administrateur. L'accès à la clé de Registre 'HKEY_CLASSES_ROOT\LibName.main' est refusé.

1>Exécution de la tâche "RegisterAssembly" terminée -- ÉCHEC.

1>Génération de la cible "UnmanagedRegistration" terminée dans le projet "LibName.vbproj" -- ÉCHEC.

translation:

1>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(4335,5): error MSB3216: Impossible to write assembly "D:\Full_Path\bin\Debug\LibName.dll" - access denied. Make sure you run application as administrator. Acces to registry key 'HKEY_CLASSES_ROOT\LibName.main' denied.

Execution of task "RegisterAssembly" finished -- FAIL.

Generation of task "UnmanagedRegistration" finished in project "LibName.vbproj" -- FAIL.

Pierre
  • 1,046
  • 7
  • 21
  • Make sure you can open visual studio with admin rights, if not then try changing the location of your project. e.g Use your user profile folder or even the desktop to make sure visual studio can write to the path. – Pure Oct 24 '16 at 10:57
  • That's the point. I do not have admin rights. Workspace... :-( I'm modifying the post – Pierre Oct 24 '16 at 11:02
  • just press the Rebuild button multiple times. I'm doing that since VS reports me the same when building my WPF app on a WPF project folder located on my desktop. – Radinator Oct 24 '16 at 11:07
  • Does this link help? http://stackoverflow.com/questions/1170794/a-simple-c-sharp-dll-how-do-i-call-it-from-excel-access-vba-vb6 – djv Oct 24 '16 at 13:57
  • @Verdolino Thanks but not much either... This is C# – Pierre Oct 26 '16 at 11:07
  • @Radinator : this does not seem to achieve much. DLL is created but cannot be linked in VBA. – Pierre Oct 26 '16 at 11:12
  • btw: can you show us how you call the dll from vba? – Radinator Oct 26 '16 at 11:44
  • @Radinator : I merely tried to add a reference to the DLL into VBA, equivalent to : ThisWorkbook.VBProject.References.AddFromFile path – Pierre Oct 26 '16 at 12:13

1 Answers1

4

Maby this is helping you: To make your VB.NET class libary accessable from a VBA project, mark your class with the <System.Runtime.InteropServices.ComVisible(True)>-Attribute.

In your VBA project, add the following references:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoree.tlb (Common Language Runtime Execution Engine 2.4 Library)
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb

And in your VBA code (to "import" the libary):

Sub DLLTest()
    ' You need this to execute functions of the CLR
    Dim clr As mscoree.CorRuntimeHost

    ' Offers you the ability to load functions from the DLL
    Dim domain As mscorlib.AppDomain

    ' Variable to store a instance of your class
    Dim objTest As Object

    ' Create a new RuntimeHost
    Set clr = New mscoree.CorRuntimeHost

    ' Start the RuntimeHost
    clr.Start

    ' Get the default AppDomain
    clr.GetDefaultDomain domain

    ' Create a instance of your DLL class
    ' dll_path is the path pointing to the DLL (can be UNC path)
    Set objTest = domain.CreateInstanceFrom(dll_path, "main").Unwrap

    ' Test 
    Dim result As Double
    result = objTest.plus 1

    ' Delete the reference
    Set objTest = Nothing

    ' Stop the RuntimeHost 
    clr.Stop
End Sub

Credit:

I got the code from here: https://www.vb-paradise.de/index.php/Thread/87001-NET-Dll-in-VBA-ohne-COM-Registrierung-nutzen/

Edit: Here, this code works on my pc

Imports System.Runtime.InteropServices

<ComVisible(True)>
Public Class Main
    Public Function Add(value As Double) As Double
        Return value + 1
    End Function
End Class

Target Framework .NET Framework 3.0

VBA-Editor: Added reference to the *.tbl files and used this code:

Sub DLLTest()
    ' You need this to execute functions of the CLR
    Dim clr As mscoree.CorRuntimeHost

    ' Offers you the ability to load functions from the DLL
    Dim domain As mscorlib.AppDomain

    ' Create a new RuntimeHost
    Set clr = New mscoree.CorRuntimeHost

    ' Start the RuntimeHost
    clr.Start

    ' Get the default AppDomain
    clr.GetDefaultDomain domain

    ' Variable to store a instance of your class
    Dim objTest As Object

    ' Create a instance of your DLL class
    ' dll_path is the path pointing to the DLL (can be UNC path)
    Set objTest = domain.CreateInstanceFrom("C:\TestDll.dll", "TestDll.Main").Unwrap()

    ' Test
    Dim result As Double
    result = objTest.Add(1)
    MsgBox result

    ' Delete the reference
    Set objTest = Nothing

    ' Stop the RuntimeHost
    clr.Stop
End Sub

Placed the dll file on C:\ Combining this with a button and after pressing it, a MessageBox appears that tells me the result (input + 1)

Radinator
  • 1,048
  • 18
  • 58
  • Thanks for your answer, and there is some new thanks to it! Now the problem is merely that the "runtime used to create the library is more recent than the loaded runtime". However v4.0.30319 is the most recent I found in my microsoft.NET framework... surprising. Any insights? – Pierre Oct 26 '16 at 12:07
  • 1
    Ok sry...that's emberassing, but I re-read the article and the author says that this only works 'til .NET FW version 3.5. So you have to set the project target to FW 3.5 and then it should work – Radinator Oct 26 '16 at 12:13
  • I don't understand but indeed framework was 4.6... However when I ask VS to compile in 4, 3.5 or even 2, it still gives me this message... And one of the reference you gave me reads: "Common language Runtime Execution Engine 2.4 Library" – Pierre Oct 26 '16 at 12:26
  • Ok may you take a look at here: http://stackoverflow.com/questions/37074533/how-to-call-net-4-0-methods-from-excel-vba – Radinator Oct 26 '16 at 12:56
  • I think this tutorial is very similar to where I started... and where I got stuck by the fact I'm not an administrator. :-( What I don't understand is how the change of framework in VS2015 changes nothing... – Pierre Oct 26 '16 at 13:04
  • Do you think I should edit my question with your partial answer? – Pierre Oct 26 '16 at 13:12
  • YAAAYYY it worked! It was case sensitive, which i hadn't thought of at first! – Pierre Oct 26 '16 at 14:30
  • Is there a way of using this to go into debug? I'd bet not. But still it does the job! :D – Pierre Oct 26 '16 at 14:39
  • Sorry for the SPAM, but is there a way to truly close the DLL? Even after code has ended, the file is read-only because it is open by excel. – Pierre Oct 26 '16 at 14:52
  • since stackoverflow reminds me to "avoid extended discussions in comments", this is my second last comment: 1) what do you mean "debug"?`VBA code or VB.NET code? 2.) I also don't think there is a "close file" unless you close excel – Radinator Oct 26 '16 at 19:00
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126803/discussion-between-pierre-and-radinator). – Pierre Oct 27 '16 at 08:47