无法在 C# 中重命名目录但手动

Posted

技术标签:

【中文标题】无法在 C# 中重命名目录但手动【英文标题】:Can't rename directory in C# but manually 【发布时间】:2013-04-23 05:13:09 【问题描述】:

我正在使用Directory.Move(oldDir, newDir) 重命名目录。我时不时收到IOException“对路径“oldDir”的访问被拒绝”。但是,如果我右键单击资源管理器中的目录,我可以重命名它而不会出现任何问题。怎么样?我怎样才能让它工作?

编辑

程序仍在运行,我得到了异常并且可以在我的光标暂停在断点上时手动重命名它。我还尝试在Directory.Move 设置断点,成功重命名资源管理器中的目录(然后再次返回),跨过Directory.Move 并再次进入catch (IOException)。所以我不明白为什么我的程序应该锁定目录。肯定还有别的。

有什么想法吗?

编辑 2

这是我的代码

public bool Copy()

    string destPathRelease = ThisUser.DestPath + "\\Release";

    if (Directory.Exists(destPathRelease))
    
        try
        
            string newPath = ThisUser.DestPath + '\\' + (string.IsNullOrEmpty(currBuildLabel) ? ("Release" + '_' + DateTime.Now.ToString("yyyyMMdd_HHmmss")) : currBranchName) + '.' + currBuildLabel;
            Directory.Move(destPathRelease, newPath);

            catch (IOException)
            
               // Breakpoint
            
        
    

如您所见,我刚刚输入了方法。我以前从未接触过程序中的目录。还有其他方法可以重命名目录吗?

【问题讨论】:

您在哪个平台上运行? WinForms、WPF、Silverlight、ASP 等? 这是 Windows 控制台应用程序。 你找到解决办法了吗? 【参考方案1】:

这是在跨平台的 C# .NET Core 中重命名目录的最安全方法。

    /// <summary>
    /// Renames a folder name
    /// </summary>
    /// <param name="directory">The full directory of the folder</param>
    /// <param name="newFolderName">New name of the folder</param>
    /// <returns>Returns true if rename is successfull</returns>
    public static bool RenameFolder(string directory, string newFolderName)
    
        try
        
            if (string.IsNullOrWhiteSpace(directory) ||
                string.IsNullOrWhiteSpace(newFolderName))
            
                return false;
            


            var oldDirectory = new DirectoryInfo(directory);

            if (!oldDirectory.Exists)
            
                return false;
            

            if (string.Equals(oldDirectory.Name, newFolderName, StringComparison.OrdinalIgnoreCase))
            
                //new folder name is the same with the old one.
                return false;
            

            string newDirectory;

            if (oldDirectory.Parent == null)
            
                //root directory
                newDirectory = Path.Combine(directory, newFolderName);
            
            else
            
                newDirectory = Path.Combine(oldDirectory.Parent.FullName, newFolderName);
            

            if (Directory.Exists(newDirectory))
            
                //target directory already exists
                return false;
            

            oldDirectory.MoveTo(newDirectory);

            return true;
        
        catch
        
            //ignored
            return false;
        
    

【讨论】:

【参考方案2】:

如果目标目录的父目录不存在,Directory.Move 操作将失败。我一直在试图找出与此大致相似的东西。

【讨论】:

【参考方案3】:

如果没有看到更多代码,我会说您的应用程序正在锁定目录中的文件,您可以使用 Process explorer 查看正在访问目录的内容

从介绍到流程浏览器:

有没有想过哪个程序打开了特定的文件或目录?现在你可以找出答案了。 Process Explorer 向您显示有关已打开或加载哪些句柄和 DLL 进程的信息。

可能还值得确保没有其他东西正在从该目录复制文件/向该目录复制文件 - 例如保管箱。我最近遇到了一个问题,Visual Studio 由于文件锁定而停止调试 - 最后它在临时锁定文件的驱动器上建立索引。进程资源管理器仅部分提供帮助,因为它显示“系统”具有文件锁定,而不是另一个应用程序。

【讨论】:

完全忘记了进程资源管理器。我现在就测试一下。另请参阅 Stefano Altieri 的回答中的我的 cmets。 找不到任何有用的东西,很遗憾。正如我在 Stefano Altieri 的回答中提到的,我在 IOException 中的断点上,可以手动重命名目录。这很奇怪……你知道吗? 会不会是当你得到你的异常时,不管是什么持有锁都会释放它? (例如,您从 using 块中突破等)? 又出现了问题。我在Directory.Move 设置了一个断点,成功地在资源管理器中重命名了目录(然后再次返回),跨过Directory.Move 并再次进入catch (IOException)。有任何想法吗? :'( 很高兴您找到了解决方案!我也从答案中学到了一些新东西:)【参考方案4】:

您需要检查运行 .net 应用程序的用户。它没有执行重命名的正确权限。

这是:

为 Web 应用程序运行应用程序池的用户 控制台/winforms 应用程序的记录应用程序 为服务或计划任务配置的用户

【讨论】:

“时不时”意味着在大多数情况下它会起作用。此外,重命名目录的用户是创建它的用户。应该不是问题。 您或其他应用程序是否在使用目录中的文件? 我猜不是因为我可以使用 Windows 资源管理器重命名它。我已经检查过了。 这还不够。如果代码中有未使用的文件锁,它将在进程结束或 GC 运行时释放。尝试检查 FileStreams 并确保您使用的是“使用块”。 @NDJ 的回答也是调试问题的好方法。 我可以在 catch 部分的断点处重命名目录。所以程序还在运行,我得到了异常,可以手动重命名。

以上是关于无法在 C# 中重命名目录但手动的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 中重命名某些内容时,如何查看“无法解决的冲突”是啥?

在 C# / Python 中重命名远程文件服务器上的文件

在 MonoTouch 中重命名命名空间

在颠覆工作副本中重命名目录的明智方法

如何在 Xcode 5 中重命名项目?

如何在 Emacs 中重命名打开的文件?