Why does Regasm put ProgId into HKEY_CURRENT_USER? - com

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.

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.

Why does Regsvr32 work on one machine but not the other

When I go to register a dll as an admin on my machine it works fine:
Regsvr32 C:\nameofdll.dll
However when I run it on another machine it fails.
Why is that?
Error codes: Error codes can be looked up using one of these methods.
Regsvr32.exe - Admin Rights Required: As far as I know self-registration requires admin rights since it registers the DLL per-machine - or in other words in the HKLM / HKCR sections of the registry (HKCR is a view into a part of HKLM and a merge from sections of HKCU - in other words it is an "emergent view" from both HKCU and HKLM). Now I see this answer which seems to indicate that there are ways to register COM servers per user? It doesn't work for my test OCX files using this method. I did not try the custom registration EXE from codeproject.
MSI - Per-User COM Registration: Windows Installer - on the other hand - is able to install COM servers per-user for setups that install per-user. Per-user setups are bad for a number of reasons (serviceability, upgrading, patching, various limitations), but that is another story. If you enable Installshield's COM Extract On Build as I showed in another answer, the COM data is added to your MSI in a way that ensures that the COM server can be registered per-user - if the setup is installed per-user, or per-machine if the setup is installed per-machine. This is the standard way to register COM files using Windows Installer.
Bitness: Other problem causes are possible, such as the mentioned "bitness" of the COM server. I have encountered very few x64 COM servers, but they are problematic to deal with using WiX for example. As far as I know the WiX 3.11 release does not support x64 COM servers for extraction. Similar problems could exist in Installshield - I don't know.
Support Page: On a 64-bit version of Windows operating system, there are two versions of the Regsv32.exe file:
The 64-bit version is %systemroot%\System32\regsvr32.exe
The 32-bit version is %systemroot%\SysWoW64\regsvr32.exe
Lacking Dependencies: Self-registration can also fail if there are lacking dependencies for the file in question. You can use a tool such as dependency walker to check, or you can monitor with procmon or any number of scanner tools (have a quick skim). Note that it is also possible that you lack a "language dll" for the COM server. For example: MyApp-English.dll. Such a file should be located next to your main COM server file MyApp.dll or MyApp.ocx to allow registration to work correctly.
Oddities: Numerous other problems can be seen. Ranging from licensing issues, COM interoperability with .NET (regasm.exe), interference from weird security policies, security software interference - anti virus etc... To any number of other specific and rare factors.
Warning: I have seen self-registration perform illegal actions and change core system values during the self-registration process - without any warning or explanation. Hence the recommendation to avoid
self-registration during deployment whenever possible.

Wix Toolset vs. InstallShield - VirtualStore Access

I developed an application with VS2010 and a setup deployment with IS Limited Edition. The application provides some data in a XML file, which is installed in the same folder. If the app was making changes in the XML file, this was saved in virtualStore.
I use now VS2015 and Wix Toolset. The application can be compiled and I was able to code a WXS File. The new built MSI install the app and all seems ok. But now the app cannot access the XML file. The access is denied.
I tried to compare both MSI with Orca, but don't see something noticeable. I'm not sure, if this is a problem of setup or of the application itself.
edit
If I copy the "old" EXE file in the new installation, the application can access the XML file.
Thank you for help and hints
If a program appears to be from before Windows Vista, is running as a limited user, and attempts to write to certain machine-only locations, Windows may redirect its access to the virtual store as part of a backwards compatibility shim. If the program does not appear to be from before Windows Vista, no redirection is performed.
I believe Windows detects whether a program appears to be from before Windows Vista by reading its manifest for supported platforms - the supportedOS elements in the application manifest. My guess is the change in your toolchain from VS 2010 to VS 2015 has resulted in this element being added to your application's manifest (Windows XP is past its supported lifetime and thus Visual Studio 2015 can implicitly assume you are supporting at least Vista).
You may be able to override the manifest, but really you should fix your program to not attempt to write to per-machine locations. Ideally you should use a location such as the LocalAppData folder, although for backwards compatibility there may be benefits to at least reading the old file from the Virtual Store.

On Windows7, regsvr32 doesn't write to HKCR\CLSID

I have created a new simple COM object in Visual Studio 2008 using the ATL-wizard. The object has a single class and simple methods. The ATL-wizard did generate .rgs-files for my class.
When I run regsvr32 Simple.dll on my XP machine the class is registered, information shows up in HKCR\Simple.SimpleObject and in HKCR\CLSID\{guid} as I expect.
However, on my 64bit Windows 7 machine it's not the same. I run regsvr32 as administrator the parts in HKCR\Simple.SimpleObject show up. But the part in HKCR\CLSID never gets there. And hence I cannot create new instances. (Being desperate I have tried both regsvr32 in System32 and in SysWOW64, same effect.)
Why dont regsrv32 put data into HKCR\CLSID?
HKCR is an alias for HKLM\Software\Classes but it doesn't show everything. Look in HKLM\Software\Wow6432Node\Classes\CLSID for the registered {guid}. Which is where c:\system32\syswow64\regsvr32.exe writes them.
You did mention that you already tried that. There's something really wrong with that, you cannot arbitrarily run either version of Regsvr32.exe and get the same DLL registered. A 32-bit DLL cannot be loaded in a 64-bit process. In other words, there's no way for the 64-bit version of Regsvr32.exe to register a 32-bit COM server. And the other way around. Why you didn't get an error message is unguessable from here, the only sane explanation is that you somehow didn't actually run the right version of Regsvr32.
To really debug this, use SysInternals' ProcMon utility. Its trace shows you how the ATL registrar is writing the keys in the registry.
32bit applications and components are getting redirected to a different part of the registry. If you are browsing the registry with the 64bit version of regedit you will not find it at the location you expect.
Therefore your component should register itself in HKEY_CLASSES_ROOT\Wow6432Node\CLSID.
In this registry path it should be visible to all 32bit applications.
See also:
Windows 64-bit registry v.s. 32-bit registry
David Broman's CLR Profiling API Blog: WOW64 and Your Profiler
We just had a similar issue here, Regsvr32 was not reporting an error, but nothing appeared to be written to the registry.
Running 'As Administrator' seemed to do the trick.

Register DLL (ActiveX) for Non-Admin user

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.