2013-05-15 72 views
1

我正在使用Directory.Move(oldDir, newDir)重命名目录。我偶尔会得到一个IOException,表示“访问路径'oldDir'被拒绝”。但是,如果我右键单击资源管理器中的目录,我可以重命名它没有任何问题。C# - 重命名目录的方法

所以我的问题是:是否有任何其他方式来重命名目录而不使用Directory.Move

我想过使用命令shell(Process.Start()),但这应该是我最后一种方式。


进一步详情

程序仍在运行,我得到的异常和手动Windows资源管理器可以重命名它 - 而我的光标暂停在该断点(右键单击>重命名) catch块。我也尝试在Directory.Move上设置一个断点,在浏览器中成功重命名目录(并再次返回),跳过Directory.Move,最后再次返回catch (IOException)

这里是我的代码

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 
     } 
    } 
} 

正如你可以看到我刚刚进入方法。我之前从未触摸过我的程序中的目录。

由于这种方式不适合我,我需要找到另一种方式来做到这一点。


解决方案

public bool Copy() 
{ 
    string destPathRelease = ThisUser.DestPath + "\\Release"; 

    SHFILEOPSTRUCT struc = new SHFILEOPSTRUCT(); 

    struc.hNameMappings = IntPtr.Zero; 
    struc.hwnd = IntPtr.Zero; 
    struc.lpszProgressTitle = "Rename Release directory"; 
    struc.pFrom = destPathRelease + '\0'; 
    struc.pTo = ThisUser.DestPath + '\\' + (string.IsNullOrEmpty(this.currBuildLabel) ? ("Release" + '_' + DateTime.Now.ToString("yyyyMMdd_HHmmss")) : this.currBranchName) + '.' + this.currBuildLabel + '\0'; 
    struc.wFunc = FileFuncFlags.FO_RENAME; 

    int ret = SHFileOperation(ref struc); 
} 

请注意使用pTopFrom零个分隔的双零个结尾的字符串是很重要的。

+0

http://stackoverflow.com/a/2024022/961113 – Habib

+0

这可能是与文件夹中的文件是“只读”,并将有一定的权限限制 – LukeHennerley

+0

@Habib不知道你在试着什么因为在这个线程中没有其他方法作为'Directory.Move'。 @LukeHennerley如果它们是只读的,为什么我可以在Windows资源管理器中重命名它们? @你是否读过完整的问题? (不要试图以任何方式表示) – theknut

回答

2

您可以尝试使用P/Invoke调用SHFileOperation API(或IFileOperation接口)。这是Explorer在理论上使用的,所以它应该更直接地复制功能。

+0

我的英雄!你怎么知道这一切?只是很好奇...... – theknut

0

尝试使用DirectoryInfo.MoveTo()而不是Directory.Move()。

此外,检查this old SO question:它似乎并没有找到你想要的例外,但你可以找到一些好的建议。