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