¶The annoying hidden current directory lock
I'm one of those people who uses the Command Prompt all of the time on a Windows system, and I frequently run into cases where some program has annoyingly locked a directory and I get "in use by another program" errors trying to remove it.
The usual reason is that some program that I've launched has it locked as its process current directory. Most often it's Notepad, since I launch Notepad all the time to view one-off files or to temporarily record snippets of text. Each Win32 program has a current directory as part of process state, and annoyingly, it keeps a lock on this directory -- which means you can't move or delete it. Usually what I do then is dig out Process Explorer and use its search function to hunt down the offender.
A more subtle cause of this problem is a program in which you've used an Open or Save dialog and have browsed into a directory. The common file dialogs change the process current directory as the user browses the filesystem, and this can also lead to accidentally locking folders. For example, you could open a file through File / Open, thus changing the process current directory to that file's containing folder, and then use drag-and-drop to reopen a different file. However, the drag and drop operation doesn't change the current directory, which still points to and is locking down the old location. This nonintuitive behavior also causes some gotchas for GUI programs:
- Any relative paths lacking a drive specifier need to be used or resolved before the GUI comes up. Otherwise, the user may change the current directory, and then those paths can't be properly resolved anymore.
- Worker threads shouldn't ever use relative paths since the current directory is a per-process and not a per-thread state. (Corollary: A module or library should never attempt to use SetCurrentDirectory to try to resolve relative paths.)
On the bright side, this behavior also has a use: if a program is stuck with an unwanted current directory, you can bring up a file dialog to change it. You do need to either accept the operation or keep the dialog up while you fiddle with the directory, because when you cancel the file dialog it will attempt to restore the original current directory. I've seen some people work around this issue by using an unlocker style program to forcibly close the offending file handle instead, without the program knowing. As a programmer, the thought of a user closing random kernel handles in a program terrifies me, but somehow they manage not to lose all of their work constantly.
For these reasons, my current thinking is that for programs which don't have file UI, it might be a good idea to call SetCurrentDirectory() on startup to change the current directory to a decent default, such as the program EXE directory or the user profile root, to avoid mysteriously locking down a random directory. This also has the benefit of avoiding random surprises if someone accidentally sneaks a relative path into a config file. For programs that do have file UI, it's less clear as doing so might undesirably change the initial file dialog location. The rules for that are somewhat obscure and change with each version of Windows; they are documented under the lpstrInitialDir parameter of the OPENFILENAME Structure.