C # - Способы переименования каталога

Я использую Directory.Move(oldDir, newDir) для переименования каталога. Время от времени я получаю сообщение IOException о том, что "Доступ к пути "oldDir" запрещен". Однако, если я щелкну правой кнопкой мыши каталог в проводнике, я смогу переименовать его без каких-либо проблем.

Итак, мой вопрос: есть ли другие способы переименовать каталог без использования Directory.Move?

Я думал об использовании командной оболочки (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);
}

Обратите внимание, что важно использовать pTo и pFrom как строки, разделенные нулями и заканчивающиеся двойными нулями.


person theknut    schedule 15.05.2013    source источник
comment
stackoverflow.com/a/2024022/961113   -  person Habib    schedule 15.05.2013
comment
Это, вероятно, будет связано с файлом в папке, который является Read-only, и у него будут ограничены определенные права.   -  person LukeHennerley    schedule 15.05.2013
comment
@ Хабиб не уверен, что вы пытаетесь сказать, поскольку в этой теме нет других методов, кроме Directory.Move. @LukeHennerley, если они будут доступны только для чтения, почему я могу переименовать их в проводнике Windows? @both Вы прочитали весь вопрос? (ни в коем случае не пытаюсь быть злым)   -  person theknut    schedule 15.05.2013
comment
@theknut Вы запускаете этот код из Visual Studio с правами администратора? если нет запусти от имени админа и проверь, а также попробуй дать полное разрешение всем пользователям на твою исходную папку и проверь.   -  person Damith    schedule 15.05.2013


Ответы (2)


Вы можете попробовать использовать P/Invoke для вызова SHFileOperation API (или IFileOperation). Это то, что Explorer использует в теории, поэтому он должен воспроизводить функциональность более непосредственно.

person Jon Grant    schedule 15.05.2013
comment
Мой герой! Откуда ты вообще все это знаешь? Просто из любопытства... - person theknut; 15.05.2013

Попробуйте использовать DirectoryInfo.MoveTo() вместо Directory.Move().

Кроме того, проверьте этот старый SO вопрос: кажется, у него нет того же исключения, что и вы, но вы можете найти хороший совет.

person Spaceman    schedule 15.05.2013