Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rename a folder in c# which is currently opened by windows explorer

When renaming a folder in C#, System.IO.Directory.Move throws System.IO.IOException (message "access denied") if that folder or any subfolder is currently opened by a (Windows 7) explorer window. Using the commandline RENAME fails, too. Using a second explorer windows succeeds.

The error persists even after collapsing the parent folder (or its parents). In fact the particular explorer window needs to be closed. So the explorer seems to create some locks just to show the folder structure and does not release them even if the actual folder isnt displayed anymore (which is pure nonsens IMO).

Is there a way to rename a folder (in program e.g. using C#), that is presently displayed (or was visible, see above) by an explorer window?

Update

Found a way as described by my own answer to this question (see below) using SHFileOperation(). However, this solution is not very feasible (see also below).

like image 664
user2261015 Avatar asked Sep 02 '15 07:09

user2261015


People also ask

How do you rename a directory in C?

rename() function in C It renames a file or directory from oldname to newname . The rename operation is same as move, hence you can also use this function to move a file. It accepts two parameter oldname and newname which is pointer to constant character, defining old and new name of file.

How do I rename a folder on my C drive Windows 10?

You can go to C drive (the OS drive) -> Users folder. Then click the search box at the upper-right in File Explorer, and search the user folder name you want to change. In the search result list, find the user folder and right-click it and you will see the Rename option.

What is rename function in C?

The rename function is part of the <stdio. h> header file in C. It is used to change the name of an existing file to a new one. The function takes in two parameters: old filename.


2 Answers

So I'm answering my own question after some further reasearch..

The folder can be renamed using SHFileOperation() as shown here: https://docs.microsoft.com/en-us/windows/win32/shell/manage
(whether this uses the 'magic' mentioned by Wouter or not. ;-)

But if there is a windows/.Net API such as System.IO.Directory.Move, WTF do I need to use the Shell? Not talking about performance ...

Anyway, using SHFileOperation() is a pain in the a.. using C# since you need to declare all this p-invoke stuff. And in this particular case you need to use different structs for 32 and 64-bit windows, since the packing is different (see https://www.pinvoke.net/default.aspx/shell32.shfileoperation). This is very cumbersome, as usually I'd specify AnyCPU as target. At this point you either need to branch at runtime (very bad indeed), depending whether you are a 64 or 32 bit process, or you build differently for two different targets, which is quite a big impact just to work around the silly explorer.

Regards

like image 171
user2261015 Avatar answered Sep 28 '22 04:09

user2261015


I had the same problem. As soon as I had an explorer window open and once navigated into the folder to rename, the Directory.Move failed with a "access denied" (Windows 7 Professional 64bit, application compiled as x86).

Interestingly, the command Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(...) succeeds to move the contents to a new directory, it only fails to delete the old directory if you are staying inside a subfolder of the directory to move. This can be fixed by catching the exception that is thrown on the first error and try again a second time. Now the source folder is also removed.

like image 35
LionAM Avatar answered Sep 28 '22 03:09

LionAM