简体   繁体   English

Directory.Move():拒绝访问路径

[英]Directory.Move(): Access to Path is Denied

I'm writing this Windows Form Application in Visual Studio 2010 using C#.我正在使用 C# 在 Visual Studio 2010 中编写此 Windows 窗体应用程序。

There is a Execute button on the form, the user will hit the button, the program will generate some files and are stored in the Output folder (which is created by the program using Directory.CreateDirectory() )表单上有一个 Execute 按钮,用户点击按钮,程序会生成一些文件并存储在Output文件夹中(由程序使用Directory.CreateDirectory()

I want to create an Archive folder to save the output files from previous runs.我想创建一个存档文件夹来保存以前运行的输出文件。

In the beginning of each run, I try to move the existing Output folder to the Archive folder, then create a new Output folder.在每次运行开始时,我尝试将现有的Output文件夹移动到Archive文件夹,然后创建一个新的Output文件夹。 Below is the function I ran to move directory.下面是我运行移动目录的功能。

static void moveToArchive()
{
    if (!Directory.Exists("Archive")) Directory.CreateDirectory("Archive");
    string timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
    try
    {
        Directory.Move("Output", "Archive\\" + timestamp);
    }
    catch(Exception e)
    {
        Console.WriteLine("Can not move folder: " + e.Message);
    }
}

The problem I ran into confuses me a lot...我遇到的问题让我很困惑......

There are some times that I can successfully move the Output folder to archive, but sometimes it fails.有时我可以成功地将输出文件夹移动到存档,但有时会失败。

The error message I got from catching the exception is Access to path 'Output' is denied.我从捕获异常中得到的错误消息是Access to path 'Output' is denied.

I have checked that all the files in the Output folder are not in use.我已经检查过Output文件夹中的所有文件都没有被使用。 I don't understand how access is denied sometimes and not all the times.我不明白有时访问被拒绝,而不是总是被拒绝。

Can someone explain to me and show me how to resolve the problem?有人可以向我解释并告诉我如何解决问题吗?

--Edit-- - 编辑 -

After HansPassant comment, I modified the function a little to get the current directory and use the full path.在 HansPassant 评论之后,我稍微修改了该函数以获取当前目录并使用完整路径。 However, I'm still having the same issue.但是,我仍然遇到同样的问题。

The function now looks like this:该函数现在看起来像这样:

static void moveToArchive()
{
    string currentDir = Environment.CurrentDirectory;
    Console.WriteLine("Current Directory = " + currentDir);
    if (!Directory.Exists(currentDir + "\\Archive")) Directory.CreateDirectory(currentDir + "\\Archive");
    string timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
    try
    {
        Directory.Move(currentDir + "\\Output", currentDir + "\\Archive\\" + timestamp);
    }
    catch(Exception e)
    {
        Console.WriteLine("Can not move folder: " + e.Message);
    }
}

I printed out the current directory and it is just as what I was expecting, and I'm still having trouble using full path.我打印了当前目录,它正如我所期望的那样,但我仍然无法使用完整路径。 Access to path 'C:\\Users\\Me\\Desktop\\FormApp\\Output' is denied.

--Edit-- - 编辑 -

Thank you everyone for answering and commenting.谢谢大家的回答和评论。

I think some of you miss this part so I'm going stress it a bit more.我想你们中的一些人会错过这部分,所以我要再强调一点。

The Directory.Move() sometimes work and sometimes fails. Directory.Move() 有时工作,有时失败。

When the function succeed, there was no problem.当函数成功时,没有问题。 Output folder is moved to Archive Output文件夹移动到Archive

When the function fails, the exception message I got was Access to path denied.当函数失败时,我得到的异常消息是访问路径被拒绝。

Thank you all for the replies and help.谢谢大家的回复和帮助。 I have figured out what the issue was.我已经弄清楚是什么问题了。

It is because there was a file that's not completely closed.这是因为有一个文件没有完全关闭。

I was checking the files that were generated, and missed the files the program was reading from.我正在检查生成的文件,但错过了程序正在读取的文件。

All files that were generated were closed completely.生成的所有文件都已完全关闭。 It was one file I used StreamReader to open but didn't close.这是我使用StreamReader打开但没有关闭的一个文件。 I modified the code and am now not having problem, so I figure that's were the issue was.我修改了代码,现在没有问题,所以我认为这就是问题所在。

Thanks for all the comments and answers, that definitely help me with thinking and figuring out the problem.感谢所有的评论和答案,这绝对可以帮助我思考和解决问题。

See http://windowsxp.mvps.org/processlock.htm请参阅http://windowsxp.mvps.org/processlock.htm

Sometimes, you try to move or delete a file or folder and receive access violation or file in use - errors.有时,您尝试移动或删除文件或文件夹并收到访问冲突或文件正在使用 - 错误。 To successfully delete a file, you will need to identify the process which has locked the file.要成功删除文件,您需要确定锁定文件的进程。 You need to exit the process first and then delete the particular file.您需要先退出进程,然后删除特定文件。 To know which process has locked a file, you may use one of the methods discussed in this article.要知道哪个进程锁定了文件,您可以使用本文中讨论的方法之一。

Using Process Explorer - download from http://download.sysinternals.com/files/ProcessExplorer.zip使用 Process Explorer - 从http://download.sysinternals.com/files/ProcessExplorer.zip下载

Process Explorer shows you information about which handles and DLLs processes have opened or loaded.进程资源管理器向您显示有关哪些句柄和 DLL 进程已打开或加载的信息。

Download Process Explorer from Microsoft site and run the program.从 Microsoft 站点下载 Process Explorer 并运行该程序。 Click the Find menu, and choose Find Handle or DLL... Type the file name (name of the file which is locked by some process.) After typing the search phrase, click the Search button You should see the list of applications which are accessing the file.单击查找菜单,然后选择查找句柄或 DLL... 输入文件名(被某些进程锁定的文件的名称。) 输入搜索短语后,单击搜索按钮 您应该会看到应用程序列表访问文件。

I bumped on the same problem recently.我最近遇到了同样的问题。 Using PE I'd figured that only process using that particular directory was explorer.exe.使用 PE 我认为只有使用该特定目录的进程是 explorer.exe。 I'd opened few windows with explorer, one pointing to parent directory of one that I was about to move.我用资源管理器打开了几个窗口,一个指向我将要移动的一个的父目录。

It appeared, that after I visited that sub-folder and then returned (even to root level!) the handle was still being kept by explorer, so C# was not able to modify it in any way (changing flags, attributes etc.).看来,在我访问该子文件夹然后返回(甚至到根级别!)后,句柄仍由资源管理器保留,因此 C# 无法以任何方式修改它(更改标志、属性等)。

I had to kill that explorer window in order to made C# operate properly.为了让 C# 正常运行,我不得不关闭那个资源管理器窗口。

Try this: If this does not solve, maybe check/change the antivirus, or the some other program is locking some file in or the folder.试试这个:如果这不能解决,也许检查/更改防病毒软件,或者其他程序正在锁定某个文件或文件夹。

    static object moveLocker = new object();
    static void moveToArchive()
    {
        lock (moveLocker)
        {
            System.Threading.Thread.Sleep(2000);  // Give sometime to ensure all file are closed.

            //Environment.CurrentDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
            string applicationPath = System.AppDomain.CurrentDomain.BaseDirectory;
            string archiveBaseDirectoryPath = System.IO.Path.Combine(applicationPath, "Archive");

            if (!Directory.Exists(archiveBaseDirectoryPath)) Directory.CreateDirectory(archiveBaseDirectoryPath);

            String timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
            String outputDirectory = System.IO.Path.Combine(Environment.CurrentDirectory, "Output");
            String destinationTS = System.IO.Path.Combine(archiveBaseDirectoryPath, timestamp);
            try
            {
                Directory.Move(outputDirectory, destinationTS);                
            }
            catch (Exception ex)
            {
                Console.WriteLine("Can not move folder " + outputDirectory + " to: " + destinationTS + "\n" + ex.Message);
            }
        }
    }
File.SetAttributes(Application.dataPath + "/script", FileAttributes.Normal);
Directory.Move(Application.dataPath + "/script", Application.dataPath + "/../script");

This fixed my problem.这解决了我的问题。

I had the same problem, it failed sometimes but not all the time.我遇到了同样的问题,它有时会失败,但并非总是如此。 I thought I'd wrap it in a Try Catch block and present the user with an Access Denied message and once I wrapped it in the Try Catch block it stopped failing.我以为我会将它包装在 Try Catch 块中并向用户显示拒绝访问的消息,一旦我将它包装在 Try Catch 块中,它就停止失败。 I can't explain why.我无法解释为什么。

 If existingFile.FileName <> newFileName Then
    Dim dir As New IO.DirectoryInfo(existingFile.FilePath)
    Dim path As String = System.IO.Path.GetDirectoryName(dir.FullName)
    newFileName = path & "\" & newFileName

    File.SetAttributes(existingFile.FilePath, FileAttributes.Normal)
        Try
            IO.File.Move(existingFile.FilePath, newFileName)
        Catch ex As Exception

        End Try
End If

I had a similar problem.我有一个类似的问题。 Renamed many directories in a loop when following the certain template.遵循特定模板时,在循环中重命名许多目录。 From time to time the program crashed on different directories.程序有时会在不同的目录上崩溃。 It helped to add a sleep thread before Directory.Move.它有助于在 Directory.Move 之前添加睡眠线程 I need to create some delay.我需要制造一些延迟。 But it slows down the copying process.但它减慢了复制过程。

foreach (var currentFullDirPath in Directory.GetDirectories(startTargetFullDirectory, "*", SearchOption.AllDirectories))
            {
                var shortCurrentFolderName = new DirectoryInfo(currentFullDirPath).Name.ToLower();
                if (shortCurrentFolderName.Contains(shortSourceDirectoryName))
                {
                    // Add Thread.Sleep(1000);
                    Thread.Sleep(1000);
                    var newFullDirName = ...;
                    Directory.Move(currentFullDirPath, newFullDirName);
                }
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM