none
Удаление каталогов, которые на самом деле доступны для удаления - отказано в доступе. RRS feed

  • Вопрос

  • Код, с помощью которого удаляю ряд каталогов:

     

      /// <summary>
      /// Удаление клиента MyProgram
      /// </summary>
      static void Uninstall() {
       string dirName = "MyProgram";
       try {
        //Каталог, в котором прописано меню программы
        string menuDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Programs), dirName);
        //Часть данных программы, относящаяся к пользовательскому профилю
        string profileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), dirName);
        //Часть программы, общая для всех пользователей локального компьютера
        string commonDir = Path.Combine(@"C:\", dirName);
        string[] dirNames = new string[] { menuDir, profileDir, commonDir };
        foreach (DirectoryInfo item in dirNames.Select(n => new DirectoryInfo(n))) {
         //Если каталог существует - его нужно удалить
         if (item.Exists) {      
          //Прежде чем удалить каталог, пробую его переименовать
          //генерирую новое имя для каталога
          string x = GetNewName(item.Parent.FullName);
          item.MoveTo(x);
          //Если переименовать удалось - удаляю каталог
          Directory.Delete(x, true);
         }
        }
       }
       catch (Exception ex) {
        MessageBox.Show(string.Format("В процессе удаления программы возникла ошибка: '{0}'.", ex.Message));
        return;
       }
      }
      /// <summary>
      /// Сгенерировать уникальное имя для каталога
      /// </summary>
      /// <param name="parentDir">Полное имя родительского каталога</param>
      /// <returns>Возвращается новое имя, с указанием полного пути</returns>
      static string GetNewName(string parentDir) {
       string x;
       do {
        x =Path.Combine(parentDir, XSecurity.GenerateString(256));
       } while (Directory.Exists(x));
       return x;
      }
    

     

    В результате работы кода первый же каталог в цикле удаётся переименовать, но вот удалить не получается. Получаю сообщение об ошибке:

    Сообщение об ошибке:
    В процессе удаления программы возникла ошибка: 'Отказано в доступе по пути "C:\Documents and Settings\Developer\Главное меню\Программы\CB4FE32B02D813E8\Инструменты".'.

    Причём файлы удаляются из этих каталогов, а вот сам каталог или подкаталоги (если они есть) - не удалить программно.
    Не пойму, почему отказано в доступе и как это обойти. Через проводник свободно добавляю/переименовываю/удаляю эти каталоги.




    26 марта 2011 г. 7:50

Ответы

  • Добрый день. Спасибо за отклики. По проблеме: взял исходники домой, тестировать и обнаружил, что дома на Windows 7 SP1 x64 Rus и Windows XP SP3 x86 Rus код отработал без ошибок, причём с правами обычного юзера. На работе я тестировал на Windows XP SP3 x86 Rus. Сегодня пришёл на работу и снова запустил тот же код, не внося в него никаких изменений (работаю так же под юзером) - всё заработало! У меня есть предположение в чём может быть дело: Давно заметил, что у меня на работе, на компе ужасно тормозит проводник. Чем дольше он открыт и я работаю в нём - тем больше он выедает память и жутко тормозит, причём часто зависает надолго. Заметил, что если удалить Skype - проводник начинает работать шустрее и не выжирает память... Возможно это совпадение, а возможно, что в пятницу ошибки в процессе работы были обусловлены тем, что проводник тормозил. Чем дальше к вечеру - тем более жуткие тормоза наблюдаются - хоть виртуальную машину переустанавливай... На выходных изучал эту статью: http://www.rsdn.ru/article/dotnet/NET4Security.xml

    Но к моему пятничному случаю она отношения не имеет. Инсталлер/Деинсталлятор написал вручную - работает как нужно. Тему можно закрывать. 


    • Помечено в качестве ответа Abolmasov Dmitry 28 марта 2011 г. 10:49
    28 марта 2011 г. 9:27

Все ответы

  • Посмотреть в сторону Code access security? Но странно, что нельзя удалить только папку. может во время копирования код не полностью "освобождает" нужный каталог?

    Попробуйте удалить все, папку вместе с файлами, до того как удалять/копировать файлы из папки.


    Don't forget to mark the correct answer Blog
    26 марта 2011 г. 13:05
  • Вы пишете свой Uninstaller программы? Могу предложить альтернативу: NSIS или использовать ClickOnce. Так же в студии можно создать "Setup Project", в котором так же можно прописать что ставить и как удалять.

    А как вы удаляете папку с uninstaller-ом? Возможно именно он блокирует удаление.

    28 марта 2011 г. 6:53
    Отвечающий
  • Студийный Setup Project топикстартеру не подошел, т.к. с ним возникла проблема обновления версии файлов. Можете посмотреть подробнее в этом вопросе - возможно вы знаете как ее решить.


    Для связи [mail]
    28 марта 2011 г. 9:09
  • Добрый день. Спасибо за отклики. По проблеме: взял исходники домой, тестировать и обнаружил, что дома на Windows 7 SP1 x64 Rus и Windows XP SP3 x86 Rus код отработал без ошибок, причём с правами обычного юзера. На работе я тестировал на Windows XP SP3 x86 Rus. Сегодня пришёл на работу и снова запустил тот же код, не внося в него никаких изменений (работаю так же под юзером) - всё заработало! У меня есть предположение в чём может быть дело: Давно заметил, что у меня на работе, на компе ужасно тормозит проводник. Чем дольше он открыт и я работаю в нём - тем больше он выедает память и жутко тормозит, причём часто зависает надолго. Заметил, что если удалить Skype - проводник начинает работать шустрее и не выжирает память... Возможно это совпадение, а возможно, что в пятницу ошибки в процессе работы были обусловлены тем, что проводник тормозил. Чем дальше к вечеру - тем более жуткие тормоза наблюдаются - хоть виртуальную машину переустанавливай... На выходных изучал эту статью: http://www.rsdn.ru/article/dotnet/NET4Security.xml

    Но к моему пятничному случаю она отношения не имеет. Инсталлер/Деинсталлятор написал вручную - работает как нужно. Тему можно закрывать. 


    • Помечено в качестве ответа Abolmasov Dmitry 28 марта 2011 г. 10:49
    28 марта 2011 г. 9:27
  • На самом деле это распространенный глюк XP, когда папка не удаляется и якобы чем то занята, но после перезагрузки компьютера проблема исчезает. Что бы гарантировать полное удаление на конечной машине вы можете обработать ошибку и предложить пользователю (или не предлагать) доудалить все необходимое после перезагрузки. Для этого добавьте унинсталлер в RunOnce реестра с каким ключом указывающем путь к лог файлу. А дальше по лог файлу находите не дочищенное и дочищаете...
    28 марта 2011 г. 9:40
    Отвечающий
  • Похожая ситуация возникала с директориями, которые имели атрибут FileAttributes.ReadOnly. Поэтому перед удалением директории я снимал этот атрибут как у папки, так и у содержащихся в ней файлов, затем удалял директорию. Смысл таков:

    foreach (var someDirectoryInfo in new DirectoryInfo(path).EnumerateDirectories("*", SearchOption.AllDirectories)
    {
    	if (FileAttributes.ReadOnly == (someDirectoryInfo.Attributes & FileAttributes.ReadOnly))
    	{
    		someDirectoryInfo.Attributes ^= FileAttributes.ReadOnly;
    	}
    
    	foreach (var someFileInfo in someDirectoryInfo.EnumerateFiles("*"))
    	{
    		if (FileAttributes.ReadOnly == (someFileInfo.Attributes & FileAttributes.ReadOnly))
    		{
    			someFileInfo.Attributes ^= FileAttributes.ReadOnly;
    		}
    	}
    }
    
    Directory.Delete(path, true);
    
    28 марта 2011 г. 10:19
  • Похожая ситуация возникала с директориями, которые имели атрибут FileAttributes.ReadOnly. Поэтому перед удалением директории я снимал этот атрибут как у папки, так и у содержащихся в ней файлов, затем удалял директорию. Смысл таков:

    foreach (var someDirectoryInfo in new DirectoryInfo(path).EnumerateDirectories("*", SearchOption.AllDirectories)
    {
    	if (FileAttributes.ReadOnly == (someDirectoryInfo.Attributes & FileAttributes.ReadOnly))
    	{
    		someDirectoryInfo.Attributes ^= FileAttributes.ReadOnly;
    	}
    
    	foreach (var someFileInfo in someDirectoryInfo.EnumerateFiles("*"))
    	{
    		if (FileAttributes.ReadOnly == (someFileInfo.Attributes & FileAttributes.ReadOnly))
    		{
    			someFileInfo.Attributes ^= FileAttributes.ReadOnly;
    		}
    	}
    }
    
    Directory.Delete(path, true);
    
    Дело в том, что каталогам я не назначал атрибута "только для чтения" - эти каталоги я в качестве эксперимента за минуту до удаления создавал вручную через проводник.
    28 марта 2011 г. 12:59