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

We have a client application with the following architecture: the control process manages several workflows (reader and writer) and periodically requests a server for version updates. If a version update is available, the dispatcher downloads it to the client computer, disables workflows, and starts the update process to process the update and exit. Update at startup receives the PID manager and the location of the update file; he waits until the manager leaves, backing up all the manager and work files, recreates their directories and distributes the new version files to new directories.

When passing through this process, as described, the first call to Directory.Move(string, string) - which serves to back up the manager's directory - throws an IOException . The strange thing is that if I let the manager disconnect without starting the updater, and then run the update executable itself, an exception will not be thrown.

Manager code for managing workflows:

 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 to start the update 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(); } 

Update code to wait for dispatcher to close:

 bool isManagerUp = true; while (isManagerUp) { try { Process managerProcess = Process.GetProcessById(bDoxForceManagerPID); managerProcess.WaitForExit(); managerProcess.Dispose(); isManagerUp = false; } catch { isManagerUp = false; } } 

Update code for updating the 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); } 
+4
source share
2 answers

Thanks to Adam Caviness for the answer we were able to understand.

Our processes were console applications, they created .vshost files that continued to work after the processes were completed. An attempt to move the directory with running .vshost files caused a problem.

Inclusion of processes in Windows services did not create .vshost files and solved this problem.

+3
source

I suggest you use the MS (formally SysInternals) Process Monitor to track this and therefore first exclude any antivirus / antivirus programs / heuristics (unless you go to the commandos like we developers). The key to this makes me tell you in this direction that you can run the updater yourself, and the exception is not thrown. Only this year I ran into this problem and had to add an exception to the AV directory.

+2
source

Source: https://habr.com/ru/post/1391248/


All Articles