Find which process is using a file, folder, or port on Windows, Linux, and macOS.
You want to rename, move, or delete a file, and the system refuses because "another program" has it open, without saying which one. oflh (Open File Lock Handle) answers that question. Point it at a file, a folder, or a whole drive and it lists every process using it, along with the parent processes that started each one. Point it at a port and it shows which process is bound to it. Then you close that program, or terminate it from oflh after a confirmation.
It is free and open source, and runs on Windows, macOS, and Linux (x86-64 and ARM64). There is a desktop app for clicking through results and an interactive terminal app for the command line; both use the same Rust scanner. It is for anyone who has hit a locked file in Explorer or Finder, and for developers and administrators chasing a busy build folder, mount point, or port.
Editorial coverage: OFLH on WinFuture (German). Thank you to the WinFuture editorial team for featuring OFLH. Read the article (German).
You can also find OFLH's software listing on AlternativeTo.
Reach for it when:
- Windows says "The action can't be completed because the file is open in another program" or "The process cannot access the file because it is being used by another process".
rm,umount, or a build fails with "Device or resource busy" or "Text file busy".- A dev server won't start because of "address already in use" (
EADDRINUSE). - A folder can't be renamed or deleted and you don't know which file inside it is held.
Desktop app example (Windows): a graphical window with the process list, matching files, local ports, and parent process tree.
Terminal app example (CLI / TUI): the interactive terminal interface. Click the image to watch the recording.
Terminal demo (GIF) · asciinema recording
Open a file, a folder, or a whole drive: use Open file or Open folder, drop it onto the window, paste a path, or on Windows right-click it in File Explorer and choose Inspect file or Inspect folder. The Processes view then lists every process that uses the target, as in the screenshot above. Click a row to see its PID, memory and CPU use, the exact files it has open (Matching handles), its Local ports, and its Process ancestry. The search box matches process names, PIDs, and full paths, and Auto refresh keeps the list current while you work. The app is available in English, German, and Simplified Chinese, with light and dark themes.
Using a file is not the same as locking it. Tick Lock evidence only to keep rows with lock or sharing-conflict evidence. Windows can show that a file is blocked but not always which process blocked it; those rows say owner unverified.
Right-click a row for its actions: copy its path or PID, reveal the file in the file manager, jump to its matching handles, or end the process. Terminate asks the process to exit; Force terminate stops it immediately. Closing the application yourself is still the safest option.
Nothing is ended without this confirmation. It names every target, including selected processes hidden by a filter, and Cancel is the default. Right before acting, oflh checks that each PID still belongs to the process you picked, so a reused PID cannot redirect the action. Unsaved work in that program can still be lost.
The Ports view lists local TCP listeners and bound UDP sockets with the process that owns each one. Search port:3000 for one port, or combine terms such as tcp, udp, or pid:1234. It shows local bindings only, not established connections or whether a port is reachable from outside.
The desktop guide covers every view, filter, and shortcut.
Whole-drive scans take a fraction of a second. Inspecting all of C:\
took 352 ms on a GitHub Actions runner. oflh does not walk the directory tree. It asks the operating system which files each running process
holds and matches those references against your target. The cost grows with
the number of open handles on the system, not the number of files on disk, so
C:\ or / is barely slower than a small folder. See
measured scan times.
One tool, three platforms, files and ports together. The same workflow and
search syntax work on Windows, Linux, and macOS, on x86-64 and ARM64. Port
lookup reads OS socket tables directly; oflh does not shell out to lsof,
ss, netstat, or handle.exe.
It tells you which app to close, not just which PID. Every result carries
the process's parent chain, so a node, dotnet, or browser helper process
can be traced back to the editor, terminal, browser, or service that started
it.
It separates "open" from "locked". A file being open does not mean it is locked. oflh reports lock evidence separately (POSIX/flock/OFD locks on Linux, byte-range conflicts on macOS, sharing violations on Windows) and says plainly when the owner of a Windows lock cannot be proven.
It is careful with your processes. oflh never closes handles inside another process. To free a file it asks the application to close, or terminates the process after a confirmation that defaults to Cancel. Before acting it checks that the PID still belongs to the same process (PID plus start time), so a reused PID cannot redirect the action.
Small, local, open source. The terminal app is a single 5–6 MB executable with no installer or runtime. Scanning happens on your machine; nothing about your files or processes is uploaded. MIT licensed, and every pull request is tested on native Linux, macOS, and Windows runners for both x86-64 and ARM64.
Every GitHub release
has builds for Windows, Linux, and macOS on x86-64 (amd64) and ARM64 (arm64,
including Apple Silicon), plus a checksums.txt with SHA-256 hashes. The
website picks the right download for you.
| Platform | Package |
|---|---|
| Windows | oflh-desktop.windows.<arch>-installer.exe |
| macOS | oflh-desktop.darwin.<arch>.dmg |
| Linux | .deb, .rpm, or a .tar.gz archive for other glibc distributions (details) |
On Windows and macOS the app can download and install updates itself after you confirm; on Linux, install new packages manually. ARM32 is not supported.
Desktop app: available since v0.2.0.
Releases are not code-signed or notarized, so Windows may show "unknown
publisher" and macOS Gatekeeper may block the app. Verify the download against
checksums.txt before bypassing the warning. If macOS reports the app as
damaged, clear the quarantine flag:
xattr -cr "/Applications/OFLH Desktop.app"Homebrew (macOS and Linux):
brew install karimz1/tap/oflh-cliOr download the standalone executable for your platform. It needs no installer:
| Platform | File |
|---|---|
| Windows | oflh-cli.windows.amd64.exe, oflh-cli.windows.arm64.exe |
| Linux | oflh-cli.linux.amd64, oflh-cli.linux.arm64 |
| macOS | oflh-cli.darwin.arm64 (Apple Silicon), oflh-cli.darwin.amd64 (Intel) |
# macOS / Linux
chmod +x ./oflh-cli.darwin.arm64
./oflh-cli.darwin.arm64 ./build# Windows (PowerShell)
.\oflh-cli.windows.amd64.exe .\buildRename the file to oflh (oflh.exe on Windows) and put it on your PATH to
run it from anywhere.
See Development for cloning the repository, prerequisites, and build commands for the desktop and terminal apps.
- Choose Open file or Open folder, drop a path onto the window, or (on Windows) right-click it in File Explorer and choose Inspect file or Inspect folder.
- Click a process to see its matching files, local ports, and parent tree.
- Narrow the list with search, Column filters, or Lock evidence only.
- Close the application normally, or use Terminate from oflh. Save your work first; terminating a process can lose unsaved changes.
- Refresh (
F5) to confirm the file is no longer in use.
The desktop guide covers filters, selection, ports, and administrator retry.
Run these commands in a terminal:
oflh ./build # a folder
oflh ./build/plugin.dll # a single file
oflh --port 3000 # TCP listener or bound UDP socket on port 3000The terminal guide covers whole-drive scans, reading results, search, ports, process actions, and keyboard shortcuts.
Recorded scans with an entire drive or root as the target:
| Platform | Target | Scan time |
|---|---|---|
| Windows x64 | C:\ |
352 ms |
| Windows ARM64 | C:\ |
510 ms |
| Linux x86-64 | / |
195 ms |
These are single backend measurements from October 2026: Windows on GitHub's native runners, Linux on a local machine. They exclude app startup and rendering, and each scan reported some permission warnings. Your numbers will depend on hardware, process count, and privileges.
On a synthetic Windows folder of 2,048 files with 128 held open, the current backend takes 315 ms on x64 and 353 ms on ARM64, down from 3,303 ms and 5,384 ms with the earlier Restart Manager backend (median of five runs). Inspection performance has the method, raw data, and commands to reproduce.
- Open is not locked. The Processes view lists every process with a reference to the target. Only Locked files requires lock evidence.
- Windows cannot always name the lock owner. A sharing violation proves the file is restricted, not which process restricted it. Such rows are labeled owner unverified.
- You see what your account can see. Processes owned by other users or protected by the OS may be missing; scans with gaps show "Results may be incomplete". Run elevated for broader coverage.
- Results are a snapshot. An empty result does not guarantee the file is free a moment later. Refresh after closing a program.
- Ports are local bindings only: TCP listeners and bound UDP sockets, not established connections or remote reachability.
- Terminating has consequences. Unsaved work can be lost, and stopping a parent can take its children with it.
Platform support details what each OS backend can and cannot detect.
Scanning is local. File names, file contents, process data, and results never
leave your machine. Release builds check for a newer version at startup and
hourly by fetching a small JSON manifest from the OFLH website (GitHub as a
fallback); the request carries no paths or process data. Turn it off in the
terminal app with --no-update-check.
Open the file in OFLH Desktop, or run oflh path\to\file in a terminal. You get
every process Windows reports as using that file, including programs that
loaded it as a module. Lock evidence only in the desktop app and
Locked files in the terminal app filter for lock or sharing-conflict evidence. To
check a folder or a whole drive, open the folder or C:\ instead.
In the desktop app, open Ports and search port:8080 to see its TCP listener
or bound UDP socket with the owning process. In a terminal, run
oflh --port 8080 for one port or oflh --ports for all local bindings.
Something else has a file, a memory mapping, or the folder itself open: a terminal whose working directory is inside it, a build server, an indexer, or antivirus. Point oflh at the folder; it checks every descendant in one scan and shows how each process uses it: open file, mapped file, executable, or (on Linux and macOS) working directory.
No. Tools that force-close a handle inside another process can corrupt that program's state, so oflh does not do it. It identifies the process and lets you close it normally or terminate it.
No. oflh runs as a normal user and shows the processes your account can inspect. Running it elevated reveals more processes. The desktop app offers Retry with administrator privileges when a termination is denied.
Those are good tools tied to one platform. oflh gives the same interactive view on Windows, Linux, and macOS, covers files and ports in one place, shows each process's parent chain, reports lock evidence separately from plain open files, and can scan a whole drive quickly because it never walks the directory tree.
Not yet. Both interfaces are interactive: the terminal app exits with an error when stdin or stdout is not a terminal, and there is no JSON output mode.
oflh reads process and socket information from the OS. It never writes to the files it inspects. Process actions always ask for confirmation with Cancel preselected and re-verify the process identity before sending anything.
| Guide | What's in it |
|---|---|
| Desktop guide | Inspecting, filtering, ports, actions, updates |
| Terminal guide | Search syntax, ports, process actions, keys, languages |
| Platform support | How each OS backend works and what it can miss |
| Inspection performance | Benchmarks and how to reproduce them |
| Development | Building, testing, and project layout |
| Architecture | Crates, threading, process-safety design |
| Contributing | Bug reports and pull requests |
The desktop app (Settings → Language), terminal app, and CLI help
(--language en|de|zh) are available in English, German, and Simplified Chinese.
To correct a translation, see the
desktop translation guide or the
terminal notes.
Found a bug? Open an issue. oflh is an independent project released under the MIT License. If it saves you time, you can support it through GitHub Sponsors or Buy Me a Coffee.




