filelocksmith.md
1 # File Locksmith 2 3 [Public overview - Microsoft Learn](https://learn.microsoft.com/en-us/windows/powertoys/file-locksmith) 4 5 ## Quick Links 6 7 [All Issues](https://github.com/microsoft/PowerToys/issues?q=is%3Aopen%20label%3A%22Product-File%20Locksmith%22)<br> 8 [Bugs](https://github.com/microsoft/PowerToys/issues?q=is%3Aopen%20label%3A%22Product-File%20Locksmith%22%20label%3AIssue-Bug)<br> 9 [Pull Requests](https://github.com/microsoft/PowerToys/pulls?q=is%3Apr+is%3Aopen+label%3A%22Product-File+Locksmith%22) 10 11 ## Overview 12 13 File Locksmith is a utility in PowerToys that shows which processes are locking or using a specific file. This helps users identify what's preventing them from deleting, moving, or modifying files by revealing the processes that have handles to those files. 14 15 ## Architecture 16 17  18 19 File Locksmith follows a similar architecture to the ImageResizer and NewPlus modules. It consists of: 20 21 1. **Shell Extensions**: 22 - `FileLocksmithExt` - COM-based shell extension for Windows 10 and below 23 - `FileLocksmithContextMenu` - Shell extension for Windows 11 context menu 24 25 2. **Core Components**: 26 - `FileLocksmithLib` - Handles IPC between shell extensions and UI 27 - `FileLocksmithLibInterop` - Core functionality for finding processes locking files 28 - `FileLocksmithUI` - WinUI 3 user interface component 29 30 3. **Settings Integration**: 31 - Settings integration in the PowerToys settings application 32 33 ## Implementation Details 34 35 ### Shell Extensions 36 37 The module adds "Unlock with File Locksmith" to the context menu in File Explorer: 38 39 - For Windows 11, a context menu command is registered as a MSIX sparse package (compiled via appxmanifest.xml) 40 - For Windows 10 and below, a traditional shell extension is registered through registry keys during installation 41 42 ### Process Communication Flow 43 44 1. User enables File Locksmith in PowerToys settings 45 2. User right-clicks on a file and selects "Unlock with File Locksmith" 46 3. The shell extension writes the selected file path to a temporary file (file-based IPC) 47 4. The shell extension launches `PowerToys.FileLocksmithUI.exe` 48 5. The UI reads the file path from the temporary file 49 6. The UI uses `FileLocksmithLibInterop` to scan for processes with handles to the file 50 7. Results are displayed in the UI, showing process information and allowing user action 51 52 ### Core Functionality 53 54 The core functionality to find processes locking files is implemented in [FileLocksmith.cpp](/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmith.cpp), which: 55 56 - Uses low-level Windows APIs via `NtdllExtensions` to iterate through file handles 57 - Examines all running processes to find handles to the specified files 58 - Maps process IDs to the files they're locking 59 - Retrieves process information such as name, user context, and file paths 60 61 ### User Interface 62 63 The UI is built with WinUI 3 and uses MVVM architecture: 64 - View models handle process data and user interactions 65 - Converters transform raw data into UI-friendly formats 66 - The interface shows which processes are locking files, along with icons and process details 67 68 ## Code Structure 69 70 ### Shell Extensions 71 - [ClassFactory.cpp](/src/modules/FileLocksmith/FileLocksmithExt/ClassFactory.cpp): COM class factory that creates instances of shell extension objects 72 - [ExplorerCommand.cpp](/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.cpp): Implements Windows Explorer context menu command for Windows 10 and below 73 - [PowerToysModule.cpp](/src/modules/FileLocksmith/FileLocksmithExt/PowerToysModule.cpp): PowerToys module interface implementation with settings management 74 - [dllmain.cpp](/src/modules/FileLocksmith/FileLocksmithExt/dllmain.cpp): DLL entry point for Windows 10 shell extension 75 - [dllmain.cpp](/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp): Windows 11 context menu integration through MSIX package 76 77 ### Core Libraries 78 - [IPC.cpp](/src/modules/FileLocksmith/FileLocksmithLib/IPC.cpp): File-based inter-process communication between shell extensions and UI 79 - [Settings.cpp](/src/modules/FileLocksmith/FileLocksmithLib/Settings.cpp): Settings management for File Locksmith module 80 - [FileLocksmith.cpp](/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmith.cpp): Core process scanning implementation to find processes locking files 81 - [NativeMethods.cpp](/src/modules/FileLocksmith/FileLocksmithLibInterop/NativeMethods.cpp): Interop layer bridging native C++ with WinRT-based UI 82 - [NtdllBase.cpp](/src/modules/FileLocksmith/FileLocksmithLibInterop/NtdllBase.cpp): Interface to native Windows NT APIs 83 - [NtdllExtensions.cpp](/src/modules/FileLocksmith/FileLocksmithLibInterop/NtdllExtensions.cpp): Process and handle querying utilities using NtQuerySystemInformation 84 - [ProcessResult.cpp](/src/modules/FileLocksmith/FileLocksmithLibInterop/ProcessResult.cpp): Class for storing process information (name, PID, user, file list) 85 86 ### UI Components 87 - [FileCountConverter.cs](/src/modules/FileLocksmith/FileLocksmithUI/Converters/FileCountConverter.cs): Converts file counts for UI display 88 - [FileListToDescriptionConverter.cs](/src/modules/FileLocksmith/FileLocksmithUI/Converters/FileListToDescriptionConverter.cs): Formats file lists for display 89 - [PidToIconConverter.cs](/src/modules/FileLocksmith/FileLocksmithUI/Converters/PidToIconConverter.cs): Extracts icons for processes 90 - [UserToSystemWarningVisibilityConverter.cs](/src/modules/FileLocksmith/FileLocksmithUI/Converters/UserToSystemWarningVisibilityConverter.cs): Shows warnings for system processes 91 - [MainWindow.xaml.cs](/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithXAML/MainWindow.xaml.cs): Main application window implementation 92 - [App.xaml.cs](/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithXAML/App.xaml.cs): Application entry point 93 - [ResourceLoaderInstance.cs](/src/modules/FileLocksmith/FileLocksmithUI/Helpers/ResourceLoaderInstance.cs): Localization resource helper 94 - [MainViewModel.cs](/src/modules/FileLocksmith/FileLocksmithUI/ViewModels/MainViewModel.cs): Main view model that handles loading processes asynchronously 95 96 ### Settings Integration 97 - [FileLocksmithViewModel.cs](/src/settings-ui/Settings.UI/ViewModels/FileLocksmithViewModel.cs): ViewModel for File Locksmith in PowerToys settings 98 - [FileLocksmithLocalProperties.cs](/src/settings-ui/Settings.UI.Library/FileLocksmithLocalProperties.cs): Machine-level settings storage 99 - [FileLocksmithProperties.cs](/src/settings-ui/Settings.UI.Library/FileLocksmithProperties.cs): User-level settings storage 100 - [FileLocksmithSettings.cs](/src/settings-ui/Settings.UI.Library/FileLocksmithSettings.cs): Module settings definitions 101 102 ## Debugging 103 104 To build and debug the File Locksmith module: 105 106 0. **Build FileLocksmith module** 107 - Shutdown the existing release builds of PowerToys 108 - Open the solution in Visual Studio 109 - Build the entire solution 110 - Build the `FileLocksmith` project 111 112 1. **Create certificate and import to Root (if you don't already have)** 113 ```powershell 114 New-SelfSignedCertificate -Subject "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" ` 115 -KeyUsage DigitalSignature ` 116 -Type CodeSigningCert ` 117 -FriendlyName "PowerToys SelfCodeSigning" ` 118 -CertStoreLocation "Cert:\CurrentUser\My" 119 120 $cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.FriendlyName -like "*PowerToys*" } 121 122 Export-Certificate -Cert $cert -FilePath "$env:TEMP\PowerToysCodeSigning.cer" 123 124 # under admin Terminal: 125 Import-Certificate -FilePath "$env:TEMP\PowerToysCodeSigning.cer" -CertStoreLocation Cert:\LocalMachine\Root 126 127 # get Thumbprint 128 Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.FriendlyName -like "*PowerToys*" } 129 ``` 130 131 2. **Sign the MSIX package** 132 ``` 133 SignTool sign /fd SHA256 /sha1 <CERTIFICATE THUMBPRINT> "C:\Users\$env:USERNAME\source\repos\PowerToys\x64\Debug\WinUI3Apps\FileLocksmithContextMenuPackage.msix" 134 ``` 135 SignTool might be not in your PATH, so you may need to specify the full path to it, e.g., `C:\Program Files (x86)\Windows Kits\10\bin\<version>\x64\signtool.exe`. 136 137 **commands example**: 138 ```powershell 139 PS C:\Users\developer> New-SelfSignedCertificate -Subject "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" ` 140 >> -KeyUsage DigitalSignature ` 141 >> -Type CodeSigningCert ` 142 >> -FriendlyName "PowerToys SelfSigned" ` 143 >> -CertStoreLocation "Cert:\CurrentUser\My" 144 145 PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My 146 147 Thumbprint Subject EnhancedKeyUsageList 148 ---------- ------- -------------------- 149 1AA018C2B06B60EAFEE452ADE403306F39058FF5 CN=Microsoft Corpor… Code Signing 150 151 PS C:\Users\developer> Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.FriendlyName -like "*PowerToys*" } 152 153 PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My 154 155 Thumbprint Subject EnhancedKeyUsageList 156 ---------- ------- -------------------- 157 1AA018C2B06B60EAFEE452ADE403306F39058FF5 CN=Microsoft Corpor… Code Signing 158 159 PS C:\Users\developer> & "C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe" sign /fd SHA256 /sha1 1AA018C2B06B60EAFEE452ADE403306F39058FF5 "%REPO_PATH%\PowerToys\x64\Debug\WinUI3Apps\FileLocksmithContextMenuPackage.msix" 160 Done Adding Additional Store 161 Successfully signed: C:\Users\developer\Develop\GitHub\PowerToys\x64\Debug\WinUI3Apps\FileLocksmithContextMenuPackage.msix 162 ``` 163 164 3. **Remove old version** 165 ```powershell 166 Get-AppxPackage -Name Microsoft.PowerToys.FileLocksmithContextMenu* 167 Remove-AppxPackage Microsoft.PowerToys.FileLocksmithContextMenu_1.0.0.0_neutral__8wekyb3d8bbwe 168 ``` 169 170 4. **Install new signed MSIX** 171 ```powershell 172 Add-AppxPackage -Path "%REPO_PATH%\PowerToys\x64\Debug\WinUI3Apps\FileLocksmithContextMenuPackage.msix" -ExternalLocation "%REPO_PATH%\PowerToys\x64\Debug\WinUI3Apps" 173 ``` 174 175 5. **Restart Explorer** 176 - Go to Task Manager and restart explorer.exe 177 178 6. **Debug Process** 179 - Set the breakpoint in [dllmain.cpp](/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp#L116) 180 - Open the **Attach to Process** dialog in Visual Studio 181 - Right-click a file in File Explorer 182 - Attach the debugger to `dllhost.exe` with **FileLocksmith** Title to debug the shell extension 183  184 - Right-click (fast) a file again and select *"Unlock with File Locksmith"* 185 - Attach the debugger to `PowerToys.FileLocksmithUI.exe` to debug the UI 186 187 7. **Alternative Debugging Method** 188 - You can set the `FileLocksmithUI` as startup project directly in Visual Studio, which will launch the UI without needing to go through the shell extension. This is useful for debugging the UI logic without the shell extension overhead. 189 190 ## Known Issues 191 192 There is an open PR to change the IPC mechanism from file-based to pipe-based, but it has blockers: 193 - When restarting as admin, the context menu extension doesn't show 194 - The "Unlock with File Locksmith" option doesn't work when launched as admin 195 196 ## Settings Integration 197 198 File Locksmith integrates with the PowerToys settings through: 199 - [FileLocksmithViewModel.cs](/src/settings-ui/Settings.UI/ViewModels/FileLocksmithViewModel.cs) 200 - [FileLocksmithLocalProperties.cs](/src/settings-ui/Settings.UI.Library/FileLocksmithLocalProperties.cs) 201 - [FileLocksmithProperties.cs](/src/settings-ui/Settings.UI.Library/FileLocksmithProperties.cs) 202 - [FileLocksmithSettings.cs](/src/settings-ui/Settings.UI.Library/FileLocksmithSettings.cs)