2013-09-20 2 views
6

Я пишу это приложение Windows Form в Visual Studio 2010 с использованием C#.Directory.Move(): Access to Path Denied

Существует кнопку Выполнить на форме, пользователь нажал на кнопку, программа будет генерировать некоторые файлы и хранятся в папке Output (который создается программой с использованием Directory.CreateDirectory())

Я хочу создайте папку Archive, чтобы сохранить выходные файлы из предыдущих прогонов.

В начале каждого прогона я пытаюсь переместить существующую папку Output в папку Archive, а затем создать новую папку Output. Ниже приведена функция, с которой я работал, чтобы переместить каталог.

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

Проблема я столкнулся путает меня много ...

Есть несколько раз, что я могу успешно переместить папку вывода в архив, но иногда это не удается.

Сообщение об ошибке я получил от ловли исключения составляет Access to path 'Output' is denied.

Я проверил, что все файлы в папке Output не используются. Я не понимаю, как иногда запрещается доступ и не все время.

Может кто-нибудь объяснить мне и показать мне, как решить проблему?

--Edit--

После HansPassant комментарий, я изменил функцию немного, чтобы получить текущий каталог и использовать полный путь. Тем не менее, у меня все еще такая же проблема.

функция теперь выглядит следующим образом:

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

я распечатал текущий каталог, и это так же, как то, что я ожидал, и я все еще возникают проблемы с использованием полного пути. Access to path 'C:\Users\Me\Desktop\FormApp\Output' is denied.

--Edit--

Спасибо всем за ответы и комментирования.

Я думаю, что некоторые из вас пропустили эту часть, поэтому я собираюсь подчеркнуть ее немного больше.

Directory.Move() иногда работает, а иногда и не работает.

Когда функция прошла успешно, проблем не возникло. папка перемещена в Archive

Когда функция не работает, сообщение об ошибке, которое я получил, было Доступ к пути запрещен.

+0

Убедитесь, что существует папка «Выход» и что в родительском каталоге нет файла с именем «Выход» (без расширения файла). – jgauffin

+0

@jgauffin. Папка вывода существует и ни один из файлов внутри нее не указан. Output , Когда moveToArchive() терпит неудачу, вновь созданные выходные файлы были созданы в папке Outuput, переписывая файлы, созданные из предыдущих прогонов. – sora0419

+0

Этот код критически зависит от правильности установки Environment.CurrentDirectory. Это происходит неправильно, это самая худшая глобальная переменная. Всегда используйте полные имена путей, например c: \ foo \ bar \ baz. И * никогда не полагайтесь на возможность записывать файлы c: \ program, UAC останавливается на этом. –

ответ

8

Спасибо всем за ответы и помощь. Я выяснил, в чем проблема.

Это потому, что был файл, который не был полностью закрыт.

Я проверял файлы, которые были сгенерированы, и пропустил файлы, из которых программа читала.

Все файлы, которые были сгенерированы, были полностью закрыты. Это был один файл, который я использовал StreamReader для открытия, но не закрыл. Я изменил код, и теперь у меня нет проблем, поэтому я считаю, что проблема была.

Спасибо за все комментарии и ответы, которые определенно помогают мне думать и решать проблему.

0

Попробуйте следующее: Если это не поможет, возможно, проверьте/измените антивирус, или какая-либо другая программа заблокирует какой-либо файл или папку.

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); 
      } 
     } 
    } 
+0

Спасибо за ответ. Однако, когда я копирую вашу функцию, папка «Выход» вообще не перемещается в архив. – sora0419

+0

Я отредактировал его, попробуйте сейчас. – Tony

+0

Я просто попробовал еще раз, и он все еще не двигается. Моя функция иногда работает, а иногда нет, я использую вашу функцию и ее вообще не выполняю. Я также попытался включить метод блокировки в свою функцию, и это тоже не помогает. – sora0419

2

См http://windowsxp.mvps.org/processlock.htm

Иногда вы пытаетесь переместить или удалить файл или папку и получить нарушение прав доступа или файл в использовании - ошибки. Чтобы успешно удалить файл, вам нужно будет идентифицировать процесс, который заблокировал файл. Сначала вам нужно выйти из процесса, а затем удалить конкретный файл. Чтобы узнать, какой процесс заблокировал файл, вы можете использовать один из методов, обсуждаемых в этой статье.

Использование Process Explorer - скачать с http://download.sysinternals.com/files/ProcessExplorer.zip

Process Explorer отображает информацию о том, какие ручки и открыты или загружены библиотеки DLL процессы.

Загрузите Проводник Процесса с сайта Microsoft и запустите программу. Нажмите «Найти» и выберите «Найти дескриптор» или «DLL» ... Введите имя файла (имя файла, заблокированного каким-либо процессом.) После ввода поисковой фразы нажмите кнопку «Поиск» Вы должны увидеть список приложений, которые обращаются к файлу.

1

Недавно я столкнулся с той же проблемой. Используя PE, я понял, что только процесс, использующий этот конкретный каталог, был explorer.exe. Я открыл несколько окон с помощью проводника, указав на родительский каталог, который я собирался переместить.

Оказалось, что после того, как я посетил эту подпапку, а затем вернулся (даже до уровня root!), Дескриптор по-прежнему хранился в проводнике, поэтому C# не смог каким-либо образом его изменить (изменение флагов, атрибутов и т.д.).

Мне пришлось убить окно проводника, чтобы C# работала правильно.

+0

У меня была такая же проблема с Windows Explorer. довольно смешно думать, что просто смотреть на каталог вызывает отказ в доступе. – viggity

0
File.SetAttributes(Application.dataPath + "/script", FileAttributes.Normal); 
Directory.Move(Application.dataPath + "/script", Application.dataPath + "/../script"); 

Это исправило мою проблему.