Excel-DNA / ExcelDna

Excel-DNA - Free and easy .NET for Excel. This repository contains the core Excel-DNA library.
https://excel-dna.net
zlib License
1.26k stars 270 forks source link

The Ribbon/COM Add-In helper required by add-in could not be registered #648

Closed daveburton1 closed 6 months ago

daveburton1 commented 8 months ago

When trying to register an add-in using v1.6.0 as a user on Excel 365 32-bit, I get the following error due to the fact the machine hive can be written to for the test subkey, but not for the "proper" subkey. Note that the deletion of the test subkey fails but this exception has since been swallowed up in v1.6.0.

Excel version: Microsoft® Excel® for Microsoft 365 MSO (Version 2208 Build 16.0.15601.20764) 32-bit.

ExcelDna.Integration Verbose: 3 : Registering 1 methods
ExcelDna.Integration Information: 3 : Register - XllPath=C:\Users\xxx\xxx.xll, ProcName=f23, FunctionType=QQ, Name=IntelliSenseServerControl_b2f1473c2a6c4934a1d883e47095d6c1 - Result=-1221656550
ExcelDna.Integration Verbose: 4 : Getting Application object
ExcelDna.Integration Verbose: 4 : Got Application object: System.__ComObject
ExcelDna.Integration Verbose: 4 : Loading Ribbon/COM Add-In Dna_c4b01d8bcbc854e4949b1480894f5272_0 / c4b01d8b-cbc8-54e4-949b-1480894f5272
ExcelDna.Integration Verbose: 4 : Loading Ribbon/COM Add-In
ExcelDna.Integration Information: 4 : RegistrationUtil.CanWriteMachineHive - DeleteSubKey failed - ignoring exception UnauthorizedAccessException: Attempted to perform an unauthorized operation.
ExcelDna.Integration Verbose: 4 : RegistrationUtil.CanWriteMachineHive - returning True
ExcelDna.Integration Verbose: 4 : RegistrationUtil.ClassesRootKey - Using HKCR
ExcelDna.Integration Verbose: 4 : ProgIdRegistration - Set Value - HKEY_CLASSES_ROOT\Dna_c4b01d8bcbc854e4949b1480894f5272_0 -> {C4B01D8B-CBC8-54E4-949B-1480894F5272}
ExcelDna.Integration Verbose: 4 : RegistrationUtil.SetValue(HKEY_CLASSES_ROOT\Dna_c4b01d8bcbc854e4949b1480894f5272_0\CLSID, , {C4B01D8B-CBC8-54E4-949B-1480894F5272}, String)
ExcelDna.Integration Error: 4 : The Ribbon/COM Add-In helper required by add-in could not be registered.
This may be due to restricted permissions on the HKCU\Software\Classes key : UnauthorizedAccessException - Access to the registry key 'HKEY_CLASSES_ROOT\Dna_c4b01d8bcbc854e4949b1480894f5272_0\CLSID' is denied.

When reverting to v1.1.0 everything works ok because the test subkey creation fails and the CanWriteMachineHive returns false:

ExcelDna.Integration Verbose: 3 : Registering 1 methods
ExcelDna.Integration Information: 3 : Register - XllPath=C:\Users\xxx\xxx.xll, ProcName=f23, FunctionType=QQ, Name=IntelliSenseServerControl_50f7dbee147d452086352d0bc1d83357 - Result=-1490092006
ExcelDna.Integration Verbose: 4 : Getting Application object
ExcelDna.Integration Verbose: 4 : Got Application object: System.__ComObject
ExcelDna.Integration Verbose: 4 : Loading Ribbon/COM Add-In xxx.RibbonUI Dna.17157386f44451ca8d4d157f6e7eb9ec.0 / 17157386-f444-51ca-8d4d-157f6e7eb9ec
ExcelDna.Integration Verbose: 4 : Loading Ribbon/COM Add-In
ExcelDna.Integration Verbose: 4 : RegistrationUtil.CanWriteMachineHive - UnauthorizedAccessException - False
ExcelDna.Integration Verbose: 4 : RegistrationUtil.CanWriteUserHive - True
ExcelDna.Integration Verbose: 4 : RegistrationUtil.ClassesRootKey - Using Users subkey S-1-5-21-149779583-1301741851-11539462-201521_CLASSES
ExcelDna.Integration Verbose: 4 : ProgIdRegistration - Set Value - HKEY_USERS\S-1-5-21-149779583-1301741851-11539462-201521_CLASSES\Dna.17157386f44451ca8d4d157f6e7eb9ec.0 -> {17157386-F444-51CA-8D4D-157F6E7EB9EC}
ExcelDna.Integration Verbose: 4 : RegistrationUtil.SetValue(HKEY_USERS\S-1-5-21-149779583-1301741851-11539462-201521_CLASSES\Dna.17157386f44451ca8d4d157f6e7eb9ec.0\CLSID, , {17157386-F444-51CA-8D4D-157F6E7EB9EC}, String)

The process is running as the user, can we check for process elevation and try to write to the user hive first if this is the case?

Interestingly I tried running as admin on v1.1.0 and it worked, so I am not sure if the original problem has gone away (the one where if the deletion of the test subkey fails, the failure is ignored). It could be that this exception should no longer be swallowed up.

govert commented 7 months ago

The process is running as the user, can we check for process elevation and try to write to the user hive first if this is the case?

I think this should work - we can experiment a bit.

Sergey-Vlasov commented 7 months ago

@daveburton1

I've tried to reproduce this problem with Excel for Microsoft 365 32-bit on Windows 8.1/10/11, standard/restricted/admin user, but it works correctly for me.

Do you know what Windows or Excel settings restrict registry for this problem to occur?

Sergey-Vlasov commented 7 months ago

@govert

Why we prefer to use machine registry (even if we have access to it) over user registry for ComRegistration?

Standard Windows development practices would say we should use only user registry (and not access machine registry at all).

govert commented 7 months ago

If the process is running with an elevated token ('As Administrator') then then COM entries written to the user hive are ignored. This is a security measure to prevent changes made at user level to allow injection of code into the elevated process. So in this case we have to write to the machine hive for things to work. As far as I understand it, this is not about the user's level of access (whether the user is e.g. a member of the Administrators group), but has to do with whether the process is elevated. I think detecting the elevation wasn't so easy for me at the time, so I just write to the machine hive if possible, and else fall back to user hive. If we have a good way of detecting the elevated token (maybe this answer about GetTokenInformation or similar https://stackoverflow.com/a/95918/44264) then we can only do the machine write in that case.

This discussion makes it less clear that the Windows practice is actually to use the user hive for COM registration - https://github.com/dotnet/runtime/issues/45750#issuecomment-744116595 But I have not run into problem with user-hive registration, and it has served us well so far.

It is probably worth revisiting registration-free COM again someday. I tried and abandoned it long ago, but some of the reasons I abandoned it later turned out not to be right, or just my misunderstandings.

daveburton1 commented 7 months ago

I have the impression it may be antivirus getting in the way, possibly not liking a machine hive registry key being written (that I believe virtually points to click to run), then trying to be deleted by a user process.  I upped the logging but haven’t found any smoking guns yet.Getting the token sounds like the most reliable method here. ThanksOn 11 Nov 2023, at 20:26, Govert van Drimmelen @.***> wrote: If the process is running with an elevated token ('As Administrator') then then COM entries written to the user hive are ignored. This is a security measure to prevent changes made at user level to allow injection of code into the elevated process. So in this case we have to write to the machine hive for things to work. As far as I understand it, this is not about the user's level of access (whether the user is e.g. a member of the Administrators group), but has to do with whether the process is elevated. I think detecting the elevation wasn't so easy for me at the time, so I just write to the machine hive if possible, and else fall back to user hive. If we have a good way of detecting the elevated token (maybe this answer about GetTokenInformation or similar https://stackoverflow.com/a/95918/44264) then we can only do the machine write in that case. This discussion makes it less clear that the Windows practice is actually to use the user hive for COM registration - dotnet/runtime#45750 (comment) But I have not run into problem with user-hive registration, and it has served us well so far. It is probably worth revisiting registration-free COM again someday. I tried and abandoned it long ago, but some of the reasons I abandoned it later turned out not to be right, or just my misunderstandings.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>