Skip to content

Commit a50c851

Browse files
committed
* Fixed issue #148: Can't uninstall.
Now silencing error 0x8002801c if found and detecting that TypeLib is not already registered on system.
1 parent 8dce952 commit a50c851

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changes for 0.10.0
55
* Fixed issue #31 : (twice) Error in logs for CContextMenu::GetCommandString()
66
* Fixed issue #109: Implement default and verbose logging.
77
* Fixed issue #110: Create a simple command line arguments debugging application.
8+
* Fixed issue #148: Can't uninstall.
89
* Fixed issue #150: ico icon (that do not specifically force index=0) are not working.
910
* Fixed issue #157: Compilation fails on Github Action: `fatal error C1083: Cannot open include file: 'atlbase.h': No such file or directory`.
1011
* Fixed issue #158: Compilation fails on Github Action: `CPack error : Problem running WiX.`.

src/shellextension/dllmain.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "GlogUtils.h"
4848
#include "SaUtils.h"
4949
#include "utils.h"
50+
#include "TypeLibHelper.h"
5051

5152
#include "rapidassist/errors.h"
5253

@@ -133,6 +134,35 @@ STDAPI DllUnregisterServer(void)
133134
// unregisters object, typelib and all interfaces in typelib
134135
HRESULT hr = _AtlModule.DllUnregisterServer();
135136

137+
// Issue #148 - Can't uninstall
138+
if ( hr == TYPE_E_REGISTRYACCESS )
139+
{
140+
// Unregistration has failed with error 0x8002801c.
141+
// Function _AtlModule.DllUnregisterServer() can also return TYPE_E_REGISTRYACCESS if the TypeLib is not registered on system.
142+
// For example, calling `_AtlModule.DllUnregisterServer()` twice, the second call will return TYPE_E_REGISTRYACCESS.
143+
// See issue #148 for details.
144+
// Is this failure because the TypeLib is not registered?
145+
146+
// Get typelib attributes
147+
TLIBATTR sTLibAttr;
148+
ZeroMemory(&sTLibAttr, sizeof(TLIBATTR));
149+
if (FAILED(GetTypeLibAttribute(_AtlComModule.m_hInstTypeLib, 0, &sTLibAttr)))
150+
return hr; // return original error
151+
152+
// Silence the original error only if the TypeLib is not registered on system.
153+
HRESULT hr2 = IsTypeLibRegisteredOnSystem(&sTLibAttr);
154+
if (SUCCEEDED(hr2) && hr2 == S_FALSE)
155+
{
156+
// We could assume the error is because the typelib is not registered.
157+
// To be certain, we should register the typelib and retry the unregistration:
158+
// _AtlModule.DllRegisterServer(); // don't care about the actual result
159+
// hr = _AtlModule.DllUnregisterServer();
160+
// but that could mess up the system if another software is listening for new typelib registrations events.
161+
// So we just overrides the original result.
162+
return S_OK;
163+
}
164+
}
165+
136166
if (SUCCEEDED(hr))
137167
{
138168
// Notify the Shell to pick the changes:

0 commit comments

Comments
 (0)