/ doc / devdocs / modules / filelocksmith.md
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  ![Diagram](../images/filelocksmith/diagram.png)
 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     ![Attach to Process](../images/filelocksmith/debug.png)
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)