-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shell extension does not unload from explorer.exe when unregistered from the system #115
Comments
|
From https://www.tenforums.com/performance-maintenance/163171-unload-dll-ram-memory-tweak-question.html :
|
Some thoughts about why this might be occurring:
EDIT:
|
Possible solutions:
|
…DllMain()` function as per solution 3 of #115.
|
Fixed Cache registry key in e7d4b32. |
Disabled option 6: Rewrite the shell extension's high level code based on the code from https://www.codeproject.com/Articles/441/The-Complete-Idiot-s-Guide-to-Writing-Shell-Extens#gettingstarted. |
There does not seems to be a way to "force" or tell File Explorer to unload the Shell Extension once it is unregistered. According to https://stackoverflow.com/questions/11365944/how-to-unload-c-shell-extension-dll-properly, Windows Installer should be able to use MoveFile to move a loaded dll. This could be an acceptable solution. |
* feature-issue115: (39 commits) Enabled building branch "feature-issue115" on AppVeyor. Removed "Cached" shell extension from HKEY_CURRENT_USER as per #115. Changed "unknown interface" logs in function CContextMenu::QueryInterface() from "WARNINGS" to "INFO". Changing implementation for reference counting Added another implementation for QueryInterface which might be helpful for invetigating #115 Added STRICT definition as per new VS2019 ALT project. Moved CContextMenu::m_previousMenu from static to a protected member variable. Disabled debugging hook. Silenced logs from CContextMenu::GetCommandString() Greatly simplified IUnknown::QueryInterface() and DllGetClassObject() implementations. Updated implementations of QueryInterface() Moved dtor scope to protected/private for CClassFactory and CContextMenu classes. Renamed m_cRef to m_refCount. Slightly modified IUnknown::AddRef() implementations. Fixed an invalid implementation of GuidToString(). Added few code optimizations for the Shell Extension. Moved code from shellext.h and shellext.cpp to dedicated files. restored shellext.h duplicate shellext.h to CCriticalSection.h restored shellext.h duplicate shellext.h to CContextMenu.h restored shellext.h ...
This has been proven incorrect. A dumb/empty new shell extension was created (see code attached below). The shell extension is really simple and has no dependencies on other DLL. Once unregistered, File Explorer is still holding to the shell extension's dll file. The file can be moved but not deleted. Waiting 2h+ did not resolved the issue. See the following code used for testing: FooBarShellExt.zip |
…w() #115 Removed conflicting code in CContextMenu.cpp which was overriding ATL code. Fixed custom DllMain() code which was using HRESULT instead of BOOL for return type. Removed debugging code: SA_ENABLE_ATTACH_HOOK_DEBUGGING.
Moved "find missing elements" code from main.cpp to user_feedback.cpp. #115.
I have implemented an utility to restart File Explorer so that uninstalling the shell extension can be done without rebooting. The plan is to modify the uninstaller to show instructions to run the File Explorer restart before actually uninstalling. |
The plan is to show a dialog when uninstalling such as the following:
It seems that showing a dialog or a message box during the uninstall process is a bad idea. This is a bad practice because the uninstaller is usually executed in Silent Mode :
See the following references:
|
Forcing a restart of File Explorer (without the user's consent) may also be a bad idea: According to the link above, it appears the appropriate solution is to use MoveFile:
This would allow the uninstallation of an old version and the installation of a new ShellAnything version. However, the new installed version would not be available to the system:
|
Added a new dialog in the installer about instructions before uninstalling.
Added a new dialog in the installer about instructions before uninstalling. See e453904 for details. |
* feature-issue115: Created a shortcut for `file_explorer_renew.exe` in Start Menu. #115 Added a new dialog in the installer about instructions before uninstalling. Updated INSTALL.md with a new section: Uninstall Shell Extensions without rebooting. #115 * Added license header to all new source files. * Renamed `refresh_file_explorer` to `file_explorer_renew`. Modified refresh_file_explorer for the following: * Modified implementations in file_explorer.cpp to use heap memory instead of stack memory for large strings. * Fixed GetFileExplorerWindowPaths() to loop through all IShellWindows::Item() elements instead of stoping at the first index that reports a "no item at specified index". * Modified OpenFileExplorerWindow() to support lanching explorer.exe with no argument. * Start a default explorer.exe process before trying to renew previous directory windows. * Fixed GetProcessExecPathFromProcessId() that used hardcoded process id `1234`. * Fixed KillFileExplorerProcesses() that waits 30 seconds before reporting an failure. Sometimes, File Explorer can take a long time before closing when killed. Enabled actual killing/opening of File Explorer instances in refresh_file_explorer. #115. Renamed user.* to user_feedback.*. Moved "find missing elements" code from main.cpp to user_feedback.cpp. #115. Partial working refresh_file_explorer. #115 Updated refresh_file_explorer application. Now showing current File Explorer paths in window. #115. Updated code for refresh_file_explorer.exe. Now getting paths from all File Explorer windows. #115. Created empty shell Windowed application `refresh_file_explorer.exe`. Fixed failing unit test: TestShellExtension.testDefaultDllCanUnloadNow() #115 Removed conflicting code in CContextMenu.cpp which was overriding ATL code. Fixed custom DllMain() code which was using HRESULT instead of BOOL for return type. Removed debugging code: SA_ENABLE_ATTACH_HOOK_DEBUGGING. Replace custom registration code in favor of ATL generated code (first draft) #115. Delete deprecated file logger_stub.h Renamed shellext.* to utils.*. Squashed commit of branch 'master' to branch 'feature-issue115'. #115
Leaving the issue opened in case someone else has an actual way of solving the problem. |
Official shell extension example from Microsoft: https://github.com/microsoftarchive/msdn-code-gallery-microsoft/tree/master/OneCodeTeam/C%2B%2B%20Windows%20Shell%20context%20menu%20handler%20(CppShellExtContextMenuHandler) |
Describe the bug
After the shell extension is unregistered from the system, explorer.exe does not unload
sa.shellextension.dll
.To Reproduce
Steps to reproduce the behavior:
register.bat
inside an administrator command prompt.unregister.bat
inside an administrator command prompt.Expected behavior
Explorer.exe should release/unload shell anything dlls when unregistering ShellAnything.
Screenshots
After unregistering the application, if we try to uninstall the application, the following dialog is displayed:
Environment
Additional context
N/A
The text was updated successfully, but these errors were encountered: