Register DLL (ActiveX) for Non-Admin user - dll

I try to register dll (ActiveX) for non-admin user using MSI.
To create registry settings I have register the dll in admin mode, then exported the relevant registry entries and renamed all HKLM to HKCU.
When I install it for non-admin user all works fine. But when I use the same settings with admin user, there is a problem of discovering TypeLib.
What should be changed in the registry entries to work both for admin and non-admin user, when the registration done under HKCU?
Thank you

If your entries are really registered under HKCU, it will work. What MSI installer are you using? There should be a way to specify that it should install in user mode.
Are you letting the dll self-register or having the msi register the dll? it is best practice to have the MSI do it, but it's more of a pain. If you're having the .dll self-register you need to make sure that the dll registers in HKEY_CURRENT_USER and not HKEY_LOCAL_MACHINE, which ATL does by default.
If you built it in VS2008 with ATL, you'll want to add:
AtlSetPerUserRegistration(true);
to your DllRegisterServer and DllUnregisterServer.
Anyway, those are some things to look for. You can use Process Monitor and watch the Reg commands to see exactly what is happening; something somewhere is writing to HKLM.

Related

Advanced Installer VSTO Add-in Deployment to Entire Machine not working

I'm using Advanced Installer to try to create an installation package (single EXE setup file) for an MS Project VSTO add-in. I need the installation Type to be Per Machine but when I chose this option and run the setup.exe file, the Add-in will not load for any of the user's on the target machine. The only way I can get it to load is if I change the installation type to Per User, which I don't want.
I'm fairly certain the problem is related to the registry, because the setup.exe is not adding the proper registry keys under HKEY_LOCAL_MACHINE to load the add-in, even though I have it set up to do so:
What am I doing wrong?
There are other things that needs to be done except windows registry keys. For example, you need to specify whether you want to support per-user or per-computer installations.
The Deploy an Office solution by using Windows Installer article describes all the necessary steps for creating per-use and per-machine Office add-in installers. Make sure that you did everything in your installation package.

Calling regasm without administrative rights for COM interop in Excel VBA

A workaround for calling regasm without the admin rights was described here already:
COM Interop without regasm
I'm trying to create a COM library that my users can deploy and use from Excel VBA without the admin privileges. I liked the regasm workaround, since it seems that people don't have much success with using registration-free COM objects from Excel VBA. I also want early binding so my users can benefit from syntax completion.
The accepted answer in the question mentioned above, however, doesn't describe where to put the assembly dll on the user's computer. Admin rights are required to install the assembly in the GAC, so I'm wondering where one can put the dll file. I presume that the application's dir is being searched for any referenced dlls, but I can't put my dll in the Excel's dir without the admin rights again. Is it possible to use the workaround with the Excel client? Is there any other way to call COM objects from VBA without the need of the admin privileges to deploy them first?
Calling regasm without administrative rights for COM interop
I think it should be possible to use RegistrationServices.RegisterAssembly and RegOverridePredefKey APIs together to implement automatic registration under the HKCU hive, in a UAC-friendly way. I've posted a more detailed answer here.
Yeah, now you have two problems, you cannot put it anywhere you should put it, like the GAC or a c:\program files subdirectory. Since those locations also require UAC elevation. You probably also forgot to run Regasm.exe with the /codebase option, required to tell the CLR where to look for the file.
The user needs to have enough privileges to copy the DLL to a directory he has write access to. That's normally only a directory in c:\users\username, like the appdata subdirectory. The headache you'll have to address that the .reg file needs to be adapted for each individual user since his username is different. So the CodeBase value in the .reg file needs to be changed for each user. This scales poorly, to put it mildly.
The answer you found is just not a very good one. The only solution that really works is to write your own registration function. One that writes the registry keys in HKCU instead of HKLM. Use the [ComRegisterFunction] attribute. You know from the .reg file what keys you need to write. And you use Assembly.GetExecutingAssembly().Location to figure out what to write for CodeBase registry value. Don't forget the [ComUnregisterFunction].
Do keep in mind that, at least in spirit, you are trying to sail around the restrictions that the LAN admin imposed on these users. They do care a lot about knowing what kind of code runs on the machines they support. This may well get you in trouble, at least talk to the guy.

Privileges for installing executables with nsis

I need to write an installer for some executables. The user might copy them wherever he wants but usually this is performed in C:\Program Files\MyProgram
If there's visual studio installed I also need to copy something to system32 (and that requires admin rights I suppose).
Does that make sense to support normal users and admin users? I mean: if I need to install something I always need admin rights, is this correct?
Supporting both can be tricky but it can be done by using RequestExecutionLevel highest and then checking if you actually are admin with the UserInfo plugin. You would then have to tell the user to force the installer to run as admin if they are not already when you detect VS.
A normal user cannot write to $programfiles so you have to default $instdir to $localappdata\Programs\Yourapp. You should also take a look at SetShellVarContext, it will help you with the HKCU vs HKLM issue...

Why does Regasm put ProgId into HKEY_CURRENT_USER?

I have two Virtual Machines that I wish to (Wix) install my software onto. One is Windows XP SP2 and another is Windows XP SP1. Neither of them use domains, and both of them have the local user Administrator with admin privileges.
Running RegAsm.exe to register MyApp.dll on the machine with SP3 puts my ProgId in the folders:
HKEY_CLASSES_ROOT\MyAppProgId
HKEY_LOCAL_MACHINE\Software\Classes\MyAppProgId
whereas running it on the SP2 machine puts it in the folders:
HKEY_CLASSES_ROOT\MyAppProgId
HKEY_CURRENT_USER\Software\Classes\MyAppProgId
I found this while trying to load MyApp.dll from a service. The registry file generated from RegAsm.exe and also Heat.exe both appear to be updating HKEY_CLASSES_ROOT.
Does anyone know what could cause this?
EDIT: I ended up getting around this by writing directly to HKEY_LOCAL_MACHINE instead of HKCR - this involved manually editing a generated .reg file or .wxs file.
On older setups HKEY_LOCAL_MACHINE is writable for a normal user, on newer Windows's (e.g. Windows 7) it is not. Might depend on configuration, user account type etc.
Registered classes go either to HKEY_LOCAL_MACHINE\SOFTWARE\Classes (sometimes writable, as mentioned) or HKEY_CURRENT_USER\Software\Classes (always writable). Both work. The first case is the overwhelming default.
HKEY_CLASSES_ROOT is actually only a view, which merges the contents of the aforementioned branches. This is why you see it under two different locations.
RegAsm seems to be smart enough to detect the readonly condition of HKLM and automagically picks HKCU instead. Or there is some configuration setting which differs between your VMs.
The main difference is that in the second case, the dll is only usable under the user account where you registered it. Your service probably runs under another account, so it cannot load the dll on the 2nd machine.

How to register a COM-visible assembly in HKCU (without MSI)

It appears that regasm.exe is only capable of registering a COM-visible assembly in HKLM, for the whole system. Is there a way to do it for the logged-in user only, without an MSI installer?
I've considered using regasm to dump a .reg file, and then processing that to add the registry entries myself... don't want to reinvent the wheel if I can avoid it.