Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / Win32

Notifying Windows Explorer about files in use

Rate me:
Please Sign up or sign in to vote.
4.84/5 (47 votes)
26 Mar 2013LGPL33 min read 84.2K   635   132   23
How to notify Windows Explorer about which files are used and locked by your application.

Introduction

While doing some file-related operations like renaming, moving, or deleting, many of you might encounter this kind of a message:

Error - file is in use

This is the standard way Windows Explorer notifies the user that some file is in use, and therefore it cannot be "changed" in any way (that is renamed, moved, deleted, etc.).

Of course, there is a way for an application to notify Windows Explorer about which files are in use. For example, Microsoft Office applications do that. When Windows Explorer is notified, the message saying that the file is in use looks different:

fileisinuse/error2.png

This article explains how to write an application which notifies Windows Explorer about used files.

How to do it?

The easiest way for a developer is to implement a COM interface named IFileIsInUse [^]. Unfortunately, this interface is available only in Windows Vista. Luckily, there is another way. I show an example demonstrating what Windows Explorer (e.g., in Windows XP) does when the user tries to delete a file which is in use. In the following example, an entry abc="123" will mean that the default value of the abc Registry key has to be equal to 123.

  1. At first, the Windows Explorer checks if there is an entry for the file in the Running Object Table (ROT [^]). Using C# terminology, one could say that the ROT is a kind of globally accessible object whose type would be Dictionary<String, ComObject> (of course it is not, because it is not a .NET object).
  2. If there is an appropriate entry for the file, it checks if the COM object implements the IOleObject interface.
  3. If the interface is implemented, it invokes its GetUserClassID(ref Guid userClassId) method. Let's assume that the method assigns a {abcdef12-ca3b-a654-e640-bf50b3aba521} GUID to the userClassId parameter.
  4. Then it checks if the following keys are in the Registry (with their default values set):
    • HKCR\CLSID\{abcdef12-ca3b-a654-e640-bf50b3aba521}\ProgID="ApplicationName"
    • HKCR\ApplicationName\CLSID="{abcdef12-ca3b-a654-e640-bf50b3aba521}"
    • HKCR\ApplicationName\shell\Open\command="path to the application exe file"
  5. Next, in order to display the application name in the message box, it reads the description of the file. The file description can be set using the AssemblyTitle attribute.

If everything is OK, Windows Explorer shows a message box (like the second one from this article) with the name of the application.

Using the code

I have created a FileLocker class which provides methods to notify the Windows Explorer which files are currently used by the application. The class implements the IDisposable interface, so it can be comfortably used with the using keyword. The sample usage is shown on the following code:

C#
// GUID, which must be unique, used to register an application in the registry
[assembly: Guid("{abcdef12-ca3b-a654-e640-bf50b3aba521}")]
// Application title which will be shown by the Windows Explorer
[assembly: AssemblyTitle("FileLockerApplication")]

...

// registers the application in the registry
FileLocker.Register();

string path = "some_file.txt";
// creates or opens the file and locks it
using (FileStream fs = File.Open(path, FileMode.OpenOrCreate,
                                 FileAccess.ReadWrite, FileShare.None))
// notifies Windows Explorer that the file is in use
using (FileLocker fl = new FileLocker(path))
{
    // here might be some code
}
// deletes the file
File.Delete(path);

// unregisters the application from the registry
FileLocker.Unregister();

The appropriate keys in the Registry are created by the FileLocker.Register() method, and deleted by the FileLocker.Unregister() method. They require a permission to write to the Registry, so it is best to invoke them from the application during the installation/uininstallation process. To successfully register, there is also needed a Guid attribute applied to the assembly.

FileLocker class members

Static methods

  • void Register() - Registers the FileLocker. Invokes it from the application during the installation process.
  • void Unregister() - Unregisters the FileLocker. Invokes it from the application during the uninstallation process.

Constructors and instance methods

  • FileLocker(FileInfo fileInfo) and FileLocker(string path) - Initializes a new instance of the FileLocker class and notifies Windows Explorer that the specified file is currently used by the application.
  • void Dispose() - Cancels the notification and disposes the object.

History

  • 1.0 (09.05.2008) - First version. The next version is included in a new project hosted at CodePlex.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer
Poland Poland
I am a graduate of Wroclaw University of Science and Technology, Poland.

My interests: gardening, reading, programming, drawing, Japan, Spain.

Comments and Discussions

 
PraiseUseful article Pin
Member 1215517320-Nov-15 1:50
Member 1215517320-Nov-15 1:50 
GeneralMy vote of 5 Pin
AlphaDeltaTheta2-Jun-13 15:24
AlphaDeltaTheta2-Jun-13 15:24 
QuestionWorking on shared folders Pin
petr.snobelt2-Apr-13 0:34
petr.snobelt2-Apr-13 0:34 
GeneralMy vote of 5 Pin
Member 43208441-Apr-13 15:40
Member 43208441-Apr-13 15:40 
GeneralKeep the locking Pin
Xmen Real 10-Jun-10 16:10
professional Xmen Real 10-Jun-10 16:10 
GeneralMean Code Pin
Jonathan C Dickinson14-May-08 0:14
Jonathan C Dickinson14-May-08 0:14 
GeneralRe: Mean Code Pin
Lukasz Sw.17-May-08 5:51
Lukasz Sw.17-May-08 5:51 
GeneralRe: Mean Code Pin
Jonathan C Dickinson18-May-08 5:06
Jonathan C Dickinson18-May-08 5:06 
GeneralRe: Mean Code Pin
Lukasz Sw.18-May-08 5:12
Lukasz Sw.18-May-08 5:12 
GeneralGood Job Pin
klaus_b13-May-08 19:33
klaus_b13-May-08 19:33 
GeneralRe: Good Job Pin
Lukasz Sw.17-May-08 5:49
Lukasz Sw.17-May-08 5:49 
GeneralRe: Good Job Pin
User 5924118-Sep-08 19:38
User 5924118-Sep-08 19:38 
GeneralNice man Pin
Sacha Barber9-May-08 2:59
Sacha Barber9-May-08 2:59 
GeneralRe: Nice man Pin
Lukasz Sw.9-May-08 7:17
Lukasz Sw.9-May-08 7:17 
GeneralRe: Nice man Pin
Sacha Barber10-May-08 4:43
Sacha Barber10-May-08 4:43 
GeneralRe: Nice man Pin
Lukasz Sw.11-May-08 11:55
Lukasz Sw.11-May-08 11:55 
GeneralRe: Nice man Pin
Sacha Barber11-May-08 21:07
Sacha Barber11-May-08 21:07 
GeneralRe: Nice man Pin
Lukasz Sw.12-May-08 8:37
Lukasz Sw.12-May-08 8:37 
GeneralRe: Nice man Pin
Sacha Barber12-May-08 22:17
Sacha Barber12-May-08 22:17 
GeneralRe: Nice man Pin
Theo Bebekis12-May-10 4:43
Theo Bebekis12-May-10 4:43 
GeneralRe: Nice man Pin
Sacha Barber12-May-10 6:02
Sacha Barber12-May-10 6:02 
GeneralRe: Nice man Pin
Theo Bebekis12-May-10 6:59
Theo Bebekis12-May-10 6:59 
GeneralRe: Nice man Pin
Sacha Barber12-May-10 7:04
Sacha Barber12-May-10 7:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.