Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Process cannot access the file because it is being used by another process on Directory.Move()

We have a client application with the following architecture: a manager process manages a couple of worker processes (reader and writer) and periodically queries the server for version updates. If a version update is available, the manager downloads it to the client computer, shuts down the worker threads, starts an updater process to handle the update and exits. The updater, on startup, receives the manager PID and the update file location; it then waits for the manager to exit, backs up all files of the manager and workers, recreates their directories and spreads the new version files to the new directories.

When going through this process as described, the first call to Directory.Move(string, string) – which serves to back up the manager directory – throws the IOException. The strange thing is, if I let the manager shut down without starting the updater and then start the updater executable myself, the exception is not thrown.

Manager code for managing worker threads:

public void Run()
{
   _config = GetConfiguration();
   Process reader, writer;

   //Start reader and writer with appropriate arguments

   //Keep reader and writer alive

   reader.Kill();
   writer.Kill();

   reader.WaitForExit();
   writer.WaitForExit();

   reader.Dispose();
   writer.Dispose();
}

Manager code for querying the database:

EndpointAddress endpoint;
BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = 2000000000;
ChannelFactory<IService> chanFactory = new ChannelFactory<IService>(httpBinding);
IService service;

try
{
   endpoint = new EndpointAddress(ConfigurationManager.AppSettings["Service URL"]);

   service = chanFactory.CreateChannel(endpoint);

   UpdateInstructions instructions = service.GetUpdateInstructions(_config.SiteID,     Assembly.GetExecutingAssembly().GetName().Version.ToString(), _config.Version);

   HandleUpdateInstructions(instructions); //Downloads files and starts the updater process
}
catch (Exception ex)
{
   //Report exception
}
finally
{
    if (chanFactory.State != CommunicationState.Faulted)
    chanFactory.Close();
}

Manager code for starting the updater process:

private void StartUpdater(string updateFilePath, string configFilePath)
{
   ProcessStartInfo updaterStartInfo = new ProcessStartInfo(_config.UpdaterExePath, string.Format("{0} \"{1}\" \"{2}\"", Process.GetCurrentProcess().Id, updateFilePath, configFilePath));
   Process updater = Process.Start(updaterStartInfo);
   updater.Dispose();
}

Updater code for waiting for the manager to close:

bool isManagerUp = true;

while (isManagerUp)
{
  try
  {
     Process managerProcess = Process.GetProcessById(bDoxForceManagerPID);

     managerProcess.WaitForExit();

     managerProcess.Dispose();

     isManagerUp = false;
  }
  catch
  {
     isManagerUp = false;
  }
}

Updater code for updating a module:

//updateDirectory is the directory of the new files to be inserted, moduleDirectory is the working directory of the module that will be updated, in this case the manager
private void UpdateModule(DirectoryInfo updateDirectory, DirectoryInfo moduleDirectory)           
{
   string backupDirectory = MakeBackupDirectoryFullPath(moduleDirectory.Parent.FullName);

   Directory.Move(moduleDirectory.FullName, backupDirectory); // IOException as described above.
   Directory.CreateDirectory(moduleDirectory.FullName);

   foreach (FileInfo updateFile in updateDirectory.EnumerateFiles())
   {
       string newFilePath = moduleDirectory.FullName + "\\" + updateFile.Name;

       File.Copy(updateFile.FullName, newFilePath);
   }

   Directory.Delete(updateDirectory.FullName, true);
}
like image 366
Mr Mush Avatar asked Jan 16 '12 11:01

Mr Mush


People also ask

How do you fix process Cannot access the file because it is being used by another process?

Applies to: Press Ctrl + Alt + Delete, then click Task Manager. Ensure you're on the Processes tab. Locate and right-click SidekickTrayWPF, then select End Process. If a warning window opens to ask if you want to end the process, click End Process again to confirm.

What does it mean when a file is being used by another process?

This error usually means that either the user or someone else still has that file open. This can happen if the file referenced is open in another program or if a crash occurs while uploading.

How do you close a file in C#?

Use it like this File. Create(myPath). Close(); .


1 Answers

Thank to Adam Caviness answer we were able to figure it out.

Our processes were Console applications, they created a .vshost files that kept on working after the processes were order to terminate. Attempting to move the directory with the running .vshost files caused the problem.

Turning the processes into Windows services didn't create a .vshost files and solved this issue.

like image 158
Mr Mush Avatar answered Sep 24 '22 18:09

Mr Mush