How to register library/reference from vba code?

Do you say that it is enough to run regasm.exe on a batch file even without logging in as admin?
RegAsm? Did I miss something? Up until now we were discussing RegSvr32 to register the COM server.
By default RegSvr32 will only register the library at system level (DllRegisterServer) which requires admin permissions. However, if your DLL supports user level installation in its DllInstall function, it can be registered with RegSvr32 by passing the appropriate command line switch.

Independently of RegSvr32 (and RegAsm), you can also write the required Registry settings for the DLL using either a .reg file, a batch script or even VBA. This definitely works without admin permissions when just writing to HKCU for the current user.
 
RegAsm /regfile:filename.reg => reg file for HKLM => change HKLM to HKCU.
 
I wrote regasm.exe because in my case, they are libraries created as dot-net assemblies, with c# language
This is of fundamental importance. You should have included this information in your very first post because people gave you a lot of very good advice which, as it turns out only now, is not really applicable in your case.
 
This is of fundamental importance. You should have included this information in your very first post because people gave you a lot of very good advice which, as it turns out only now, is not really applicable in your case.

You are right
 
These are libraries I created, not the standard ones provided with Access or already present in Windows

My confusion remains. In order to have the file be usable, if YOU created it, how do you not know where it is and what it is? This library didn't get to a usable location via telepathy or time-travel. Someone put it somewhere and, since you created it, how is that someone not you?
 
add to Attachment your COM library.
add also a command file (Register.cmd):
Code:
@ECHO OFF

reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT

"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\regasm.exe" /unregister %~dp0MySocketConnector.dll
"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\regasm.exe" /codebase %~dp0MySocketConnector.dll /tlb %~dp0MySocketConnector.tlb

if %OS%==64BIT "%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" /unregister %~dp0MySocketConnector.dll
if %OS%==64BIT "%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" /codebase %~dp0MySocketConnector.dll /tlb %~dp0MySocketConnector.tlb

Extract both MySocketConnector.dll and Register.cmd on same folder and run Register.cmd using Shell command.
 
My confusion remains. In order to have the file be usable, if YOU created it, how do you not know where it is and what it is? This library didn't get to a usable location via telepathy or time-travel. Someone put it somewhere and, since you created it, how is that someone not you?

The PEPPE.ACCDE program was initially created without the use of external libraries
In later versions, the PEPPE.ACCDE program began using external libraries
A user attempting to use the latest versions of PEPPE.ACCDE without placing the external libraries in the correct location and registering them so the operating system knows about them would be unable to run the program correctly
And the code couldn't provide any useful information other than the fact that something is missing
But what is missing? The code doesn't know
At least until it is provided with a correspondence between the GUID and the library
This last thing, although simple, was missing
 
Do you say that it is enough to run regasm.exe on a batch file even without logging in as admin?
I have an Access procedure that searches for newer versions upon startup
If available, downloads them to the root program directory and creates a new icon on the desktop to launch them
Sometimes, newer versions require an additional library in the references; otherwise, the code won't work correctly
The question is: how can I verify that all the required libraries are loaded, and if not, how can I start the library registration process (using VBA code, I mean)?
My answer? don't try and do this in VBA!!!

Ok, keep in mind there are 3 types of .dll’s that are “common” used with Access.

First type: - windows .dll with entry points
A standard windows .dll, one with entry points. These are the ones that you use VBA declare statements.

Such as this one:
Code:
 Private Declare PtrSafe Function MyCreateObject Lib "nloader.dll" _
            (ByVal strDll As String, ByVal strClass As String) As Object


The above .dll’s are NOT class objects, and do NOT require a regsvr32.exe. And they do NOT require VBA CreateObject.

Second Type: Windows COM objects.

Then we have registered windows “COM” objects. These work much the same when you create an instance of Outlook or Word, or whatever. You thus use VBA CreateObject() in VBA.

Keep in mind, that when using regsve32.exe, there are 2 versions installed on windows

One for x64 bit applications

One for x32 bit applications.

So, depending on which version of Access (x32 or x64), you have to use the correct version of regsvr32.exe.



Third type: .net framework .dll objects - seen in VBA as windows COM objects.

The next type of dll, (and what I tend to use now), are so called .net .dll’s. Such .dll’s require use of the .net regams.exe in place of regsvr32.exe.

What regams.exe does is creates/installs the.net .dll as a windows standard registered COM object. And again, there is a x64 bit version, and a x32 bit version of regasm.exe.

However, I have found more and more installation sites have more and more locked down computers. This means that attempts to register a .dll tends to require elevated rights.

As a result, I now use a “side load” approach, and thus don’t have to register my .net .dll’s with regasm.exe. This allows so called x-copy deployments (you only need to copy the access front end, and some .dll’s into the same folder – and everything just works! So, this is COM free .net registration, and it saves me boatloads of hassles.

So, both regsver32, and regams (for .net .dll’s) tends these days to required elevated rights.

And if you are IN LUCK?

If you only are using regasm (.net .dlls), then I suggest you grab a copy of my VBA .net loader – it will load the .dll’s for you, and do so without requiring regasm. Just place the .dll in the same location as the access front end, and you good to go.



I have a .net .dll that does PDF mering from VBA -- and thus you can try my sample Access PDF merge here:

Link:

[link not allowed]

The above includes a access form that looks like this:
1761597178715.png



(do keep in mind that when you download the .zip file, make sure to un-block the downloaded file before un-zipping. However, I assume all developers do this by habit anyway (unblock).

Speaking of hassles? Before I adopted the .net side loading approach from VBA? I still STRONG recommend that you adopt a installer.

That installer can:

Check for Access, or Access runtime – it not present, then install it.

Check for and register your required .dll’s .

Check for things like say a custom bar code font, and again, if missing, then install the font.

Place a shortcut on the desktop.

Check if your trying to install to a computer running terminal services, and thus change/use a different location then say C: drive.

So, all of these “common” install issues? Including building a automatic front end updater? They can all with ease be “solved” by adopting a installer.

And with just a few lines of VBA code, you can leverage the installer to also “auto update” your front end with great ease…

There are a number of free installers one can use – I’ve been using Inno installer for years but really, the point here is to adopt “some” kind of installer, since they tend to have options to register .dlls, and even .net ones. And you can detect if office is a x64 bit install, or a x32 one….

Edit: seems I can't post links - perhaps I'm new here (no worries).


Regards,

Albert D. Kallal (Access MVP 2003-2017)

Edmonton, Alberta, Canada
 
Hi Albert, just a quick heads up, due to this site's propensity to attract spammers, you will need to have around 100 posts before you will be able to post links.
(y)
d
 
My answer? don't try and do this in VBA!!!

Ok, keep in mind there are 3 types of .dll’s that are “common” used with Access.

First type: - windows .dll with entry points
A standard windows .dll, one with entry points. These are the ones that you use VBA declare statements.

Such as this one:
Code:
 Private Declare PtrSafe Function MyCreateObject Lib "nloader.dll" _
            (ByVal strDll As String, ByVal strClass As String) As Object


The above .dll’s are NOT class objects, and do NOT require a regsvr32.exe. And they do NOT require VBA CreateObject.

Second Type: Windows COM objects.

Then we have registered windows “COM” objects. These work much the same when you create an instance of Outlook or Word, or whatever. You thus use VBA CreateObject() in VBA.

Keep in mind, that when using regsve32.exe, there are 2 versions installed on windows

One for x64 bit applications

One for x32 bit applications.

So, depending on which version of Access (x32 or x64), you have to use the correct version of regsvr32.exe.



Third type: .net framework .dll objects - seen in VBA as windows COM objects.

The next type of dll, (and what I tend to use now), are so called .net .dll’s. Such .dll’s require use of the .net regams.exe in place of regsvr32.exe.

What regams.exe does is creates/installs the.net .dll as a windows standard registered COM object. And again, there is a x64 bit version, and a x32 bit version of regasm.exe.

However, I have found more and more installation sites have more and more locked down computers. This means that attempts to register a .dll tends to require elevated rights.

As a result, I now use a “side load” approach, and thus don’t have to register my .net .dll’s with regasm.exe. This allows so called x-copy deployments (you only need to copy the access front end, and some .dll’s into the same folder – and everything just works! So, this is COM free .net registration, and it saves me boatloads of hassles.

So, both regsver32, and regams (for .net .dll’s) tends these days to required elevated rights.

And if you are IN LUCK?

If you only are using regasm (.net .dlls), then I suggest you grab a copy of my VBA .net loader – it will load the .dll’s for you, and do so without requiring regasm. Just place the .dll in the same location as the access front end, and you good to go.



I have a .net .dll that does PDF mering from VBA -- and thus you can try my sample Access PDF merge here:

Link:

[link not allowed]

The above includes a access form that looks like this:
View attachment 121979


(do keep in mind that when you download the .zip file, make sure to un-block the downloaded file before un-zipping. However, I assume all developers do this by habit anyway (unblock).

Speaking of hassles? Before I adopted the .net side loading approach from VBA? I still STRONG recommend that you adopt a installer.

That installer can:

Check for Access, or Access runtime – it not present, then install it.

Check for and register your required .dll’s .

Check for things like say a custom bar code font, and again, if missing, then install the font.

Place a shortcut on the desktop.

Check if your trying to install to a computer running terminal services, and thus change/use a different location then say C: drive.

So, all of these “common” install issues? Including building a automatic front end updater? They can all with ease be “solved” by adopting a installer.

And with just a few lines of VBA code, you can leverage the installer to also “auto update” your front end with great ease…

There are a number of free installers one can use – I’ve been using Inno installer for years but really, the point here is to adopt “some” kind of installer, since they tend to have options to register .dlls, and even .net ones. And you can detect if office is a x64 bit install, or a x32 one….

Edit: seems I can't post links - perhaps I'm new here (no worries).


Regards,

Albert D. Kallal (Access MVP 2003-2017)

Edmonton, Alberta, Canada

I have been using Albert's loader for loading my Autodesk Vault interface, it work great. His sample PDF merge is also very handy.

PS it would be nice if this site would wave the limits for Albert so he could better participate in this forum.
 
Good to see you posting here Albert and hadn't realised you had in fact been a member since 2009.
I've just spent half an hour reading all your old posts to this forum, full of wisdom and, of course, written in your own unique and entertaining style.

So although you certainly aren't new here, a huge welcome to the forum
 
As I pointed out, you can get away without having to use regasm to use/load such .net .dlls. Thus, you only have to place the .dll in the same folder as the Access front end.
And rather nice?
Since you not using a global regasm.exe? Then you can deploy multiple front ends, and each can have their own set of .dlls.
Without having to register the .dll's, then deployment issues are much eliminated.
I have some sites with about 100 desktops. And it seems every few months, their IT department locks down the computers more and more.
Elimination of regasm thus removed another failure point and hassle.

So, with my .net loader, then you dispense with having to use shell() or whatever to trigger use of regasm....

And while the .net loader is a standard windows .dll? Well, once again, I don't want to hard code the path name to that .dll loader, so I use the long time API "load library" for this purpose....

I do plan to post the source code for the loader on git hub, but VS2022 will decompile the code for you anyway....

Consider giving that loader a try -- given your .dlls are .net, then that's quite much what I designed this for....

So, I now often write .net code for use with VBA, since it's become oh so easy to do so with this loader....

R
Albert
 
I do plan to post the source code for the loader on git hub, but VS2022 will decompile the code for you anyway....

We are looking forward to it 😁

Could you give us some more details on how to create an external library, usable in Access, that works correctly even without performing the registration procedure in the operating system?
This would certainly be an option that many users would appreciate.
 
Last edited:
Ok, a great question!

>Could you give us some more details on how to create an external library, usable in Access

The short answer? (with some caveats attached?)

If you have some existing .net .dll’s and were/are using regasm?

Well, in theory, you don’t have to change anything at all using my .net loader

(except that you don’t need regams.exe anymore!!).


Now, when I said “sort of”?

Well, you don’t have to change any of the .net code, but on the VBA side?


Well, you do have to adopt what we call late binding.

However, I’m hoping that over time, like most developers, one moved towards “late binding” anyway.

Thus, we are NOT using a tools->reference(s) in VBA.

Why?

Well, with late binding, then you don’t have to reference a “specific” version of Outlook, word, Excel etc., or in this case the .net dll.


On my site, I posted a really cool word merge utility. I wrote that word merge utility about 20 years ago. And today, if you go and grab that word merge code, and drop it into your existing Access application?

It will just work, and the reason of course is that I adopted late binding.

So, late binding is a REALLY nice approach if you going to deploy Access applications in say a corporate environment, since what happens if they upgrade office?

Well, now your tools->references etc. in VBA will in near all cases break. But, with late binding, they don’t break, and continue to work!!!

So, what do I mean by late binding?


Well, code like this:

Code:
      Dim MyWord as new Word.Application

Becomes:
      ‘Dim MyWord as new Word.Application     ‘ early bind – for devlopment
       Dim MyWord as Object
       Set MyWord = CreateObject(“Word.Application”)

I'm hoping all have done the above.

So, when I suggested/hinted that you don’t have to change “any thing” for current code you have, and my .net loader?

Well, you do have some minor steps:

First, tools->references, and remove the reference to the COM library.

We not going to use tools->references anymore, and as noted, this is good practice to adopt, since you then (often) eliminate broken references.

Note that some developers will during first development round and testing?

Sure, use early binding, and use tools->references from VBA.

This gives nice error checking, and gives intel-sense in VBA.

But, once you have everything all nice and fuzzy warm and working?

Then (hopefully) most development changes are down to a dull roar, and you don’t require much change in code (say in the future). So, then you change the code to late binding, and thus avoid deployment issues.

So, second step (after removing the references in VBA->tools->references?

So, for non .net stuff, you would use CreateObject().

However, for the custom .net loader, then you use this code:

(this example is for my PDF merging library I use in VBA)


Code:
Dim MyPdf as New Pmerge.Pmerge

Above now becomes this:

Dim MyPdf As Object

Set MyPdf = CreateObjectNET("Pmerge.dll", "Pmerge.Pmerge")

So, just like for late binding, you in place of CreateObject, use CreateObjectNET, and ALSO have to give the name of the .dll you want to load.

(and of course you need my .net loader code added to your application).

So, really, if you “already” were using late binding, then only one line of code change is required.

Note that the name of the .dll in above is assumed to be in the same directory as the current Access front end.


So, above is a quick summary.

Now, to answer the question in full?

How do you create these objects (.dlls) in .net?

Well, there is the easy way, and the hard way.

I’ll start another post here on how to create such .dll’s in vb.net, and it REALLY easy!
(I'll post in a bit - later this evening - stay tuned, since everyone will be surprised HOW easy it is to create such .dll's in .net)

R
Albert
 
Ok, so let's put all the steps together as to what you need for this to work.

First up, you need the code module (and 2 .dll's) from the sample PDF merge utility I posted here.

Assuming you have the above?

Ok, then let's from scratch create a .net .dll for use from VBA.

As noted, the .net world has near un-limited features, and often such features are built into .net.
And when they are not? Well, there is a gazillion NuGet libaries you can add to .net.
(this is how the PDF merge sample was made - I used iTextSharp - a common well known PDF library for .net).

Ok, so, let's do somthing simple. We will in an Access form, display a image. Then use .net to rotate the image.

In fact, you can Google, or even GPT how to do this in vb.net.

The .net code looks like this to rotate a given image (file).

Code:
' Load the image from file
        Dim imagePath As String = "C:\path\to\your\image.jpg"
        Dim img As Image = Image.FromFile(imagePath)

        ' Rotate the image 90 degrees clockwise
        img.RotateFlip(RotateFlipType.Rotate90FlipNone)

        ' Save the rotated image to a new file
        Dim outputPath As String = "C:\path\to\your\rotated_image.jpg"
        img.Save(outputPath, ImageFormat.Jpeg)

        ' Clean up
img.Dispose()

So, really, just a few lines of vb.net.

So, now let's create a .net .dll for use from Access.

So, assuming one has Visual Studio installed (the free community edition works just fine for this.

So, the first step is to create a new project in VS. We want to create a SUPER simple project, and the correct program is to create a .net class project.

Perhaps only trick is to make sure you choose/create the correct kind of project. One "challenge" in .net is that over the years, .net has become the ultimate Swiss army knife - and there are BOATLOADS of projects too choose from. This is what happens when a company keeps throwing money at a particular platform - it just grows and grows!!! It would be un-kind of me to state that VS now has too many project types, ranging from web, to desktop to Android development, and much more!!!

So, we need to choose + create a .net framework (not .net standard, or what was/is called .net core).

So, in create new project, choose this project type:

1761785952795.png



Ok, so now we have this:

1761786028410.png


And then we now have this:

(but, let' right click on the class, and rename it, like this:


clsRoate.gif


Now, add a reference to System.Drawring to use the image stuff in .net.

Hence this:
1761786590131.png


Ok, so let's add a simple method (sub) to this code, based on that vb.net code to rotate that image.

So, our class becomes this:

Code:
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices


<ClassInterface(ClassInterfaceType.AutoDual)>
Public Class clsRotate

    Public Sub RotatePic(imagePath As String, intRoate As Integer)

        ' Load the image from file
        Dim img As Image = Image.FromFile(imagePath)

        ' Rotate the image 90 degrees clockwise

        Select Case intRoate
            Case 1
                img.RotateFlip(RotateFlipType.Rotate90FlipNone)
            Case 2
                img.RotateFlip(RotateFlipType.Rotate180FlipNone)
            Case 3
                img.RotateFlip(RotateFlipType.Rotate270FlipNone)
        End Select

        ' Save the rotated image
        img.Save(imagePath, ImageFormat.Jpeg)

        ' Clean up
        img.Dispose()

    End Sub


End Class

So, you can adopt the above cookie cutter design over and over.
You need to add (as per above), the following:

Imports System.Runtime.InteropServices

And this just before the class:
<ClassInterface(ClassInterfaceType.AutoDual)>

And only one more step, and we have our .net dll.

In the project settings, under assembly, check the box "Make assembly COM-Visible"

this one:

1761787283280.png


If you build this project, and want to use regasm? Then I suggest you force the project to x86, or x64 if using x64 bit Access/office.

However, as noted, with our .net loader, we don't need (nor care) to use regasm.

So, I'll reply a bit later as to what the VBA code looks like, but really, after anyone done the above, you are now on the road to freely building .dll'ss for use with Access. And EVEN if you don't want to use my .net loader, the above will work just fine using regasm.exe, and setting a reference from VBA .....

R
Albert
 
Yes, they should just "work", and no need to re-compile, assuming say .net 4.x.

So, lets complete this example. We will build the above, and then copy the .dll into the same folder where our front end is.

Our Access form looks like this:

crotate.gif


And the code behind for this simple form?
There is the button to select a file, (show the picture), and then the button to rotate the picture.

This code behind:

Code:
Option Compare Database
Option Explicit

Private Sub cmdFileSel_Click()


    Dim f       As FileDialog
    Set f = Application.FileDialog(msoFileDialogFilePicker)
    f.Filters.Clear
    f.Filters.Add "jpg picture", "*.jpg"
    
    f.Show
    
    If f.SelectedItems.Count > 0 Then
    
        Text1 = f.SelectedItems(1)
        Image1.Picture = Text1
            
    End If
    

End Sub

Private Sub cmdRotate_Click()

    Dim picObj        As Object
    Set picObj = CreateObjectNET("VBPicRotate.dll", "VBPicRotate.clsRotate")
    
    picObj.RotatePic Me.Text1.Value, 1
        
    Image1.Picture = Text1      ' this will re-load (refresh) the picture..
    
End Sub

So, kind of simple. There are "more" issues to address, but as you can see, it's not really hard to create that .net .dll.
And, without having to register it (regasm)? Then this allows adopting such .net code with a lot less work and hassle.

As noted, you will require the 2 .dll's (nloader.dll, and nloader64.dll). And you want the code module from that merge pdf example.
With above, then you can now just "drop in" the .net .dll, and you off to the races.
In fact, if you x32, or x64 (known ahead of time), then you only need one of the above .dll's (nloader = x32 bits, and nloader64 = x64 bits). However, they are small, so I usually just dump/include both .dll's.

So, in theory, while we can address the "really big" topic of using an installer?
Well, you can even deploy say using a zip file, since no registration of the .net .dll's are required......

Your above code samples look 100% correct for late binding.
Only got-ya is to watch for some cases in which a constant is used, as late binding will not include those constants.....

So, all in all?
It's not all that hard to create the .net class library. And while most examples are long and wordy code, including that of building a interface?
You really don't need all that jazz in most cases - just a simple .net class.

R
Albert
 

Users who are viewing this thread

Back
Top Bottom