My issue is this. I was creating a directory and filing it with files for running a specific process and on subsequent runs it would delete the directory, recreate it and start filling it with files.
root\scripts\'Many files'
All this code seemed to run fine without errors until I opened up my Windows Explorer window and navigated into the 'scripts' directory. When I would run it again it would kick me out of the folder as expected when it deleted, but it would throw an exception trying to add files to the directory, and when I looked the 'scripts' directory didn't even exits.
DirectoryNotFoundException was caught: Could not find a part of the path
My Code looked like this.
if (Directory.Exists(scriptsDirectory))
Directory.Delete(scriptsDirectory, true);
Directory.Create(scriptsDirectory));
File.WriteAllText(scriptsDirectory + fileName, output);
I looked on the internet and found this: Windows Explorer and Directory.Delete()
It seems there's something odd with Windows Explorer, but my issue was different. It wouldn't throw an exception on delete, but when I was trying to add files to the directory, b/c the createDirectory didn't seem to fire while I was in the directory.
My solution is below.
My solution was instead of Deleting the Directory, I instead deleted all the files from the directory, and that worked for me.
if (Directory.Exists(strScriptsDirectory))
{
DirectoryInfo directoryInfo = new DirectoryInfo(strScriptsDirectory);
// Delete the files
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
fileInfo.Delete();
// Delete the directories here if you need to.
}
else
Directory.CreateDirectory(strScriptsDirectory);
This fix might not work well for all solutions and the solution provided in the link doesn't seem too great.
Another solution we tired was too write a while (true) loop that had a try catch to try to create the directory and add a file to it (if the add file caused an exception it would be caught and try again) and if it succeeded it would delete the test file and break out of the while.
Does anyone have any cleaner solutions that would allow you to delete a directory and recreate without having to worry about if a user is within an Explorer window?
Related
I have the following piece of code in a .NET 6 app that copies some files to a different destination on the file system:
DirectoryInfo targetDir = GetTargetDir();
foreach (FileInfo fi in GetFilesToCopy())
{
fi.CopyTo(Path.Combine(targetDir.FullName, fi.Name), true);
}
As you can see, I'm passing true to the .CopyTo() method, so it overwrites the file if it already exists.
However, this seems to not work properly:
If the destination file does NOT exist, the copy works fine
If the destination file DOES exist, however, the copy operation fails and throws a UnauthorizedAccessException with an error message like 'Access to the path 'C:\my destination dir\my destination file.ext' is denied.'
I've checked the method documentation, and it says that that exception is thrown if the destination is a directory or if we're trying to copy to a different drive. However, I'm not doing any of those things (and anyway it doesn't explain why it works if the file does not exist)
I've checked all I could think of, and it all seems in order:
The user running the application has permission to write to that location and is the owner of the existing files
The files are not in use, I can easily delete them using windows explorer or cmd
I've also tried running the code as administrator (even though it shouldn't be needed) but same error occurs
Can anyone tell me why this is happening?
Apparently the problem was the files have the Read Only attribute (thanks to #nilsK for pointing me in the right direction).
I've resolved this with the following code:
string destFile = Path.Combine(targetDir.FullName, fi.Name);
if (File.Exists(destFile))
{
File.SetAttributes(destFile, FileAttributes.Normal);
}
fi.CopyTo(destFile, true);
There is a shared network folder at \\FILESERVER\MyFolder. The security principal Everyone has Full Control on This folder, subfolders and files. There are no DENY permissions on the folder. There are three users, and all of them can use File Explorer to enter the directory and create a file named test.txt.
This code runs fine for two of the users:
string testLocation = #"\\FILESERVER\MyFolder\";
string testFullPath = Path.Combine(testLocation, "test.txt");
Directory.CreateDirectory(testLocation);
bool exists = Directory.Exists(testLocation); // RETURNS TRUE!
File.Create(testFullPath); // For one user, this raises:
// System.IO.DirectoryNotFoundException: Could not find part of the path
// '\\FILESERVER\MyFolder\test.txt'
So Directory.CreateDirectory runs fine (the folder already exists), but File.Create seems to think the directory does not exist. As that user, I can type in \\FILESERVER\MyFolder in Explorer, see the existing files there and create new files, no problem. But not when running the code above.
The program's process is running under the user in question.
This only happens with network paths, not local paths. If I change \\FILESERVER\MyFolder to C:\Users\Username\Desktop, the file is created.
The background for the problem is that the program fails to export an XLSX file to the network folder for this specific user. In this case, I attempted to work around the problem after days of researching and not finding anything: If the file fails to export to the network folder, the program exports it to Desktop and then attempts to move it to the network folder. Of course, the program fails when moving. I narrowed it down to the snippet shown above. The code shown above is identical to the code that fails, except that I've changed the name of the server and folder for the example.
Any ideas?
Renaming the directory worked. Instead of \\FILESERVER\MyFolder, the folder is now named \\FILESERVER\MyFolderNew, and it's working. If I rename the folder back to MyFolder, it stops working again.
I don't have time to dig deeper. There are no firewall/antivirus rules regarding this directory, that's all I know. Renaming the folder works for us.
I'm basically creating a directory in MyDocuments. I think it's worth mentioning that MyDocuments at my company is a network path.
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
path = Path.Combine(path, string.Format(#"A\XXX\C\{0:yyyyMMdd_HHmmss}", startTime));
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
The issue here is quite funny. It was working fine for 2 years and recently I cleaned manually path in subdirectory 'XXX'. Now it doesn't work. If I change 'XXX' to anything else it works. It looks like something is wrong with this particular directory. I can delete that directory manually and recreate it in windows explorer. It happens when running from VS2015 and from exec as well. Any ideas?
Edit:
Just to clarify:
Exception thrown: "Could not find a part of the path"
In Line Directory.CreateDirectory(path);
Edit:
The reproduce in windows explorer:
I can create and remove XXX and C this is fine. When I tried to create any subdirectory in C windows explorer hangs. So I removed the entire A directory and now when I try to create it manually I can't recreate A because it says that the folder or a file in it is open in another program. How is it possible if it doesn't exist.
The answer is pretty simple. In your company we use sync center to synchronize data on this shared drive. The root directory wasn't fully synchronized so whenever I tried to create directory it thrown an error. After synchronizing and deleting it from my mirrored version and sync center version I could create it again.
When I try to rename a Directory using the following code:
try
{
System.IO.Directory.Move(oldPath, newPath);
}
catch (System.IO.IOException e2)
{
Console.WriteLine(e2.Message);
}
I get the following exception: The process cannot access the file because it is being used by another process.
I don't understand why it says "file" in the first place.
Also, the directory is empty. What file is it referring to?
Lastly, how to manage to rename the Directory without any exceptions?
UPDATE: I guess I found the reason for the exception, it is because I am trying to rename the file/folder names of files/folders situated in the Google Drive. The Google Drive application is the other process using it! Any solutions to rename a folder in the Google Drive? But the weird thing is that I don't get this exception when I try to rename files located in the Google Drive through C#.
Thanks!
Your folder seems to be in use by another process. Try to close your explorer or other programs, that use that folder. If nothing help - try to restart your machine. If those won't help - consider using Unlocker to free folder from usage of another process. Note that it would be weird, if non-system folder is occupied after restart of the machine
It says "file" because the underlying commands are probably using a
generic move command for both directories and files and the
localized error string contains the word file.
Even if a directory is empty, it can be locked for any edits if you have it "open" in an application (do you have explorer Windows open in the directory, is the command prompt current directory set to the one you want to move/delete)?
Unfortunately there's not much you can do unless you want to start killing offending processes programmatically.
You can use Process Explorer to find the process that has a lock on that folder. See http://windowsxp.mvps.org/processlock.htm for more info.
1 Verify that newPath already does not exist
http://msdn.microsoft.com/en-us/library/system.io.directory.move.aspx
2 Verify that your directory does not contain opened file
Sometimes, no "foo" directory is left after running this code:
string folder = Path.Combine(Path.GetTempPath(), "foo");
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
Process.Start(#"c:\windows\explorer.exe", folder);
Thread.Sleep(TimeSpan.FromSeconds(5));
Directory.Delete(folder, false);
Directory.CreateDirectory(folder);
It seems Windows Explorer keeps a reference to the folder, so the last CreateDirectory has nothing to do, but then the original folder is deleted. How can I fix the code?
EDIT:
I'm sorry that my question wasn't clear. My objective is to create an empty "foo" directory. If the directory already exists, I delete it and create it anew. The problem is that if Windows Explorer is looking at the directory, the CreateDirectory call sometimes fails silently. No exception is raised; the directory just isn't created.
The code above reproduces the issue in my computer. Only the last two lines belong to my actual application. The previous lines are setup. After you run the code, does "foo" always exist? This is not the case half the time in my pc.
For the time being, I'm manually deleting each file and subdirectory of foo.
Since you did not provide details (like exceptions, errors), I will assume this is the problem.
I think the problem is that the explorer is still running when you run the command to delete the folder. This could be a locking problem.
Directory.Delete(folder, false);
Either that, or there is some other application accessing that folder or its sub-folders or files, if any by chance.
I would recommend not touching the folder via explorer or any other app, if possible, and wait for the explorer to exit first, before deleting the folder.
Process p = Process.Start(#"c:\windows\explorer.exe", folder);
Thread.Sleep(TimeSpan.FromSeconds(5));
p.WaitForExit(); //<-------
Directory.Delete(folder, false);
Also, please do not ignore the exceptions and errors thrown and paste them here, if any.
Hope it helps.