4

The software company I'm working for builds software for schools, and so our client machines are usually locked down in such a way it makes it pretty impossible for us to install anything on it.

Our old system is primarily based on a (very large) MS Access project and so it gets around the access problems by just running from a local folder.

I've been given the task of redeveloping some of the system into c# .NET - however it would be nice in the interim stages to have the ability to have the access project fire .NET things off.

I have played around with com interops for a few hours today but afaik the only way to make these work is to register them with RegAsm.exe - and unfortunately this isn't an option in the client environments.

I've tried GetObject / CreateObject but neither work when referencing a dll or tlb file, is there any other way this could be achieved?

The ideal solution would be to put the com interop dll in the same directory as the Access project.

And yes, before anyone says it, I know MS Access is evil and only suited for very small projects - but I only arrived here 4 months ago...

Marlon

Marlon
  • 2,129
  • 3
  • 21
  • 40
  • Uh, you may "know" that, but it's not true. Access is not evil, and not unsuited for large projects. It just has to be used appropriately. Your comments imply that Access is not even being used, just Jet, so that suggests a level of confusion that's likely to make it difficult for you to solve your problems. That is, if you don't even understand crucial distinctions about the tools you are using, it's unlikely you're going to be able to code an app that works with those tools for which your level of understanding is pretty foggy. – David-W-Fenton Mar 04 '10 at 19:21
  • Reading your comments below, you say you are "working with an MS Access project, no VB6.exe is compiled" so I'm confused. Is it a VB6 app or an Access application? If the latter, you should be able to get around many problems by not creating references in the Access app and using late binding. But your CreateObject comments tend to suggest that your problem is actually that you can't register needed components, so that won't help. And it's not clear to me what the issue is, i.e., whether it's a .NET issue or an Access issue. In short, there's not enough information to really provide an answer. – David-W-Fenton Mar 04 '10 at 19:24
  • @David I think the problem is that Marlon wants to call into C# objects from an Access application. But he can't register his COM-compatible C# objects because the users don't have permissions. The question is whether there's any technique to get an Access project to call a C# object without ever requiring administrator permissions to get the C# objects registered. – MarkJ Mar 05 '10 at 10:02
  • Is it impossible to register components for the current user? – David-W-Fenton Mar 05 '10 at 20:46
  • yes, we can't have any sort of install process. – Marlon Mar 08 '10 at 11:58

4 Answers4

6

You could host the CLR inside Access:

Add a reference to mscoree (Probably C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscoree.tlb)

Sub Main()
    Dim CORHost As New mscoree.CorRuntimeHost
    Dim Domain As Object
    Dim AssemblyFilename As String
    Dim Classname As String
    Dim Result As Object

    AssemblyFilename = "mscorlib"
    Classname = "System.Collections.ArrayList"

    CORHost.Start
    CORHost.CurrentDomain Domain
    Set Result = Domain.CreateInstance(AssemblyFilename, Classname).Unwrap()

    Result.Add "test"
    MsgBox Result.Count
End Sub

This bypasses the need to use the registry. The down side of this is you have to use late binding with your objects.

You can also add a reference to mscorlib.tlb to get type information for the AppDomain class and others.

Foole
  • 4,754
  • 1
  • 26
  • 23
  • Hello, Thanks for your post, it sounds very promising. I've just tested it out but I get a 'Type Mismatch' error when passing the Domain object to the CORHost.CurrentDomain. I looked at the interface specs and it passes a pointer not an object - will vb6 care about that? (sorry, my vb6 skills are limited). – Marlon Mar 04 '10 at 12:03
  • If you still get the type mismatch with my updated code, try adding a reference to mscorlib.tlb and declaring Domain as an AppDomain. – Foole Mar 04 '10 at 12:20
  • Hello, I still got a Type Mismatch with that code, I also tried adding a reference to mscorlib.tlb but there doesn't seem to be a definition for "AppDomain" in there. Closest thing is AppDomainManager or AppDomainSetup. – Marlon Mar 04 '10 at 12:29
  • That should only be the case if you have put "New" in there. – Foole Mar 04 '10 at 21:52
5

As long as your client systems are Windows XP or later then you have the option of using Registration Free COM. This replaces the need to registry the COM components using regasm (or regsvr32 for native COM servers) in the system registry with XML configuration manifest files.

With this you still use the standard CreateObject calls to create your objects.

shf301
  • 31,086
  • 2
  • 52
  • 86
  • I had a quick read through that tutorial, the only potential concern is because we're working with an MS Access project, no VB6.exe is compiled so I don't think I could compile the manifest with the project. I'll research this further though. – Marlon Mar 04 '10 at 12:14
  • You would probably need to put the manifest with the Access main executable. This is somewhat risky, and you may not have permissions to do it. – MarkJ Mar 04 '10 at 12:27
  • You can load process manifest at run-time -- http://msdn.microsoft.com/en-us/library/aa375259(VS.85).aspx – wqw Mar 04 '10 at 19:23
1

If been using .Net DLLs from my VB6 projects by using manifests. The only requirement is the VB6 executable and .Net DLL be in the same folder.

I'm using UMMM tool to automatically create the dependency entry in the application manifest.

You can use ActCtx.Manifest property to dynamicly load a proper manifest for reg free access to .Net interop coclasses.

wqw
  • 11,771
  • 1
  • 33
  • 41
0

you say you can't install anything, but could you write the necessary stuff into the registry yourself? I think that all regasm does is write all some stuff to the registry, so you could effectively do that from your VB code on startup if its not there and then you might be able to load the interop assembly.

you can use a tool like process monitor to see what gets written to the registry when you run regasm.

I'd make sure you are using the -codebase switch and explicitly defining Guids for your interfaces and classes for the com wrappers as well. not doing so caused me no end of issues trying to get com wrapped .net dlls to work properly

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • 1
    On XP and later COM objects can be registered in the user portion of the registry (HKEY_CURRENT_USER) and you will probably have permissions to write there from the user account. You probably won't have permissions to register the COM objects globally (in HKEY_LOCAL_MACHINE). You could convert what regasm does from HKLM into HKCU – MarkJ Mar 04 '10 at 12:26
  • regasm has a parameter that will create the registry entries as a file - no need to use process monitor – Carl Onager May 13 '13 at 14:59