/// <summary> /// Returns process arguments with replaced values. /// </summary> /// <param name="e">File watcher event args for running a process.</param> /// <returns>Process arguments with replaced values.</returns> private static string GetProcessArguments(FileWatcherEventArgs e) { // If something to replace if (!String.IsNullOrEmpty(e.ConfigurationKeyValuePair.Value.ProcessArguments)) { string arguments = e.ConfigurationKeyValuePair.Value.ProcessArguments; // Replace escape strings with values. if (e.ConfigurationKeyValuePair.Value.ProcessUseChangeTypeAsArgument) { arguments = GetArgumentsWithChangeType(arguments, e); } if (e.ConfigurationKeyValuePair.Value.ProcessUseFileNameAsArgument) { arguments = GetArgumentsWithFileName(arguments, e); } if (e.ConfigurationKeyValuePair.Value.ProcessUseOldFileNameAsArgument) { arguments = GetArgumentsWithOldFileName(arguments, e); } return(arguments); } return(e.ConfigurationKeyValuePair.Value.ProcessArguments); // Nothing to replace. }
/// <summary> /// Initializes a new instance of the ProcessRunner class. /// </summary> /// <param name="fileWatcherEventArgs">File watcher event args for running a process.</param> /// <exception cref="ArgumentNullException">fileWatcherEventArgs is null.</exception> public ProcessRunner(FileWatcherEventArgs fileWatcherEventArgs) { if (fileWatcherEventArgs == null) { throw new ArgumentNullException("fileWatcherEventArgs", Resources.ArgumentNullException); } _fileWatcherEventArgs = fileWatcherEventArgs; }
/// <summary> /// Replaces change type escape string with the file name. /// </summary> /// <param name="arguments">Arguments string.</param> /// <param name="e">File watcher event args for running a process.</param> /// <returns>Returns arguments with change type.</returns> private static string GetArgumentsWithChangeType(string arguments, FileWatcherEventArgs e) { if (!String.IsNullOrEmpty(arguments)) { if (!String.IsNullOrEmpty(e.ConfigurationKeyValuePair.Value.ProcessArgumentsChangeTypeEscapeString)) { return(arguments.Replace(e.ConfigurationKeyValuePair.Value.ProcessArgumentsChangeTypeEscapeString, e.ChangeType)); } return(arguments); } return(String.Empty); }
/// <summary> /// Tries to rename file. /// </summary> /// <param name="process">Running process.</param> /// <param name="renameResult">Rename result.</param> /// <returns>Returns new FileWatcherEventArgs with new renamed file path or null /// if the process is re-queued or rename fails or is canceled.</returns> private static FileWatcherEventArgs TryRenameFile(FileWatcherEventArgs process, out RenameResult renameResult) { string fileName = Path.GetFileName(process.FullPath); if (fileName == null) { renameResult = RenameResult.Cancel; return null; } const string FileNameFormat = @"{0}.{{{1}}}.process"; string newFileName = String.Format(CultureInfo.CurrentCulture, FileNameFormat, fileName, process.Id); string newFullPath = process.FullPath.Remove(process.FullPath.Length - fileName.Length, fileName.Length) + newFileName; try { // Rename file. File.Move(process.FullPath, newFullPath); renameResult = RenameResult.Success; } catch (PathTooLongException) { renameResult = RenameResult.Cancel; return null; } catch (DirectoryNotFoundException) { renameResult = RenameResult.Cancel; return null; } catch (FileNotFoundException) { renameResult = RenameResult.Cancel; return null; } catch (UnauthorizedAccessException) { renameResult = RenameResult.Cancel; return null; } catch (NotSupportedException) { renameResult = RenameResult.Cancel; return null; } catch (ArgumentException) { renameResult = RenameResult.Cancel; return null; } catch (IOException) // File can be locked by another process or something else goes wrong. { // Retry renaming. renameResult = RenameResult.Retry; return null; } // Return new process with renamed file information. return new FileWatcherEventArgs(process.ConfigurationKeyValuePair, process.ChangeType, newFileName, newFullPath, process.FullPath, process.Id); }
/// <summary> /// Replaces old file name escape string with the old file name. /// </summary> /// <param name="arguments">Arguments string.</param> /// <param name="e">File watcher event args for running a process.</param> /// <returns>Returns arguments with old file name.</returns> private static string GetArgumentsWithOldFileName(string arguments, FileWatcherEventArgs e) { if (!String.IsNullOrEmpty(arguments)) { if (!String.IsNullOrEmpty(e.ConfigurationKeyValuePair.Value.ProcessArgumentsOldFileNameEscapeString)) { return arguments.Replace(e.ConfigurationKeyValuePair.Value.ProcessArgumentsOldFileNameEscapeString, e.OldFullPath); } return arguments; } return String.Empty; }
/// <summary> /// Formats message. /// </summary> /// <param name="fileWatcherEventArgs">Message.</param> /// <returns>Formatted message.</returns> /// <exception cref="ArgumentNullException">fileWatcherEventArgs is null.</exception> public string Format(FileWatcherEventArgs fileWatcherEventArgs) { if (fileWatcherEventArgs == null) { throw new ArgumentNullException("fileWatcherEventArgs", Resources.ArgumentNullException); } if (String.Compare(fileWatcherEventArgs.ChangeType, Resources.ChangeTypeSystemGenerated, StringComparison.Ordinal) == 0) { return String.Format(CultureInfo.CurrentCulture, @Resources.MessageFileSystemChange, @DateTime.Now, @Resources.MessageTypeInfo, @Resources.MessageSystemGenerated, @fileWatcherEventArgs.FullPath); } return String.Format(CultureInfo.CurrentCulture, @Resources.MessageFileSystemChange, @DateTime.Now, @Resources.MessageTypeInfo, @fileWatcherEventArgs.ChangeType.ToLower(CultureInfo.CurrentCulture), @fileWatcherEventArgs.FullPath); }
/// <summary> /// Handles system changed event. Runs in the main thread. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">Event data.</param> private void OnSystemChanged(object sender, FileWatcherEventArgs e) { EventHandler<FileWatcherEventArgs> handler = SystemChanged; if (handler != null) { handler(this, e); } // If file watcher is configured for running a process or calling a service. if (e.ConfigurationKeyValuePair.Value.StartProcess || e.ConfigurationKeyValuePair.Value.CallService) { // Enqueue process for a run. EnqueueProcess(e); // Add available process for the file watcher. AddAvailableProcess(e.ConfigurationKeyValuePair.Key); } }
/// <summary> /// Enqueues process to process queue. Signals processThreadAutoResetEvent. /// </summary> /// <param name="e">File watcher event args for running a process.</param> private void EnqueueProcess(FileWatcherEventArgs e) { lock (_lockProcessQueue) { _processQueue.Enqueue(e); // Signal syncProcessAutoResetEvent there is an item to process. _processThreadAutoResetEvent.Set(); } }
/// <summary> /// Start the process or calls service synchronized with other processes. /// </summary> /// <param name="e">File watcher event args for running a process.</param> private void StartProcessSynchronized(FileWatcherEventArgs e) { // If no process is running yet. Then start the process. if (!IsProcessRunning()) { StartProcessSynchronizedHelper(e); } else { bool exitLoop = false; // Wait until the current running process has exited. while (!exitLoop) { if (!IsProcessRunning()) { exitLoop = true; StartProcessSynchronizedHelper(e); } else { _syncProcessAutoResetEvent.WaitOne(); } } } }
/// <summary> /// Call service specified in file watcher event args. /// </summary> /// <param name="e">File watcher event args for calling a service.</param> private void CallServiceSynchronized(FileWatcherEventArgs e) { // Turn on process running for synchronization of processes. SetProcessRunningOn(); // Increase external process counter. SetExternalProcessRunningOn(); // Run threaded event in main thread. _synchronizationContext.Send(new SendOrPostCallback(delegate { EventHandler<ServiceBeginCallEventArgs> handler = ServiceBeginCall; if (handler != null) { handler(this, new ServiceBeginCallEventArgs(e.ConfigurationKeyValuePair.Key, GetProcessQueueCount(), e.Id)); } }), null); FileWatcherStreamingServiceProxy fileWatcherStreamingServiceProxy = null; FileWatcherServiceProxy fileWatcherServiceProxy = null; if (e.ConfigurationKeyValuePair.Value.StreamFile) { fileWatcherStreamingServiceProxy = CreateStreamingProxy(e.ConfigurationKeyValuePair.Key); } else { fileWatcherServiceProxy = CreateProxy(e.ConfigurationKeyValuePair.Key); } // If failed to create a proxy. if (fileWatcherStreamingServiceProxy == null && fileWatcherServiceProxy == null) { // Decrease external process counter. SetExternalProcessRunningOff(); // Run threaded event in main thread. _synchronizationContext.Send(new SendOrPostCallback(delegate { EventHandler<ServiceProxyCreationErrorEventArgs> handler = ServiceProxyCreationError; if (handler != null) { handler(this, new ServiceProxyCreationErrorEventArgs(e.ConfigurationKeyValuePair.Key, e.Id, GetProcessQueueCount())); } }), null); // Remove available process from the file watcher. RemoveAvailableProcess(e.ConfigurationKeyValuePair.Key); // Decrease file watcher process count. RemoveProcessFromProcessBatchSize(e.ConfigurationKeyValuePair.Key); SetProcessRunningOff(); return; } try { IResponse response; string checksum = CalculateMD5Sum(e.FullPath); if (e.ConfigurationKeyValuePair.Value.StreamFile) { using (Stream fileStream = File.OpenRead(e.FullPath)) { response = new SystemChangedRespMC(); response.Message = fileWatcherStreamingServiceProxy.SystemChangedStreaming(e.ChangeType, checksum, e.ConfigurationKeyValuePair.Key, e.DateTime, e.FileName, fileStream.Length, e.FullPath, e.Id, Environment.MachineName, e.OldFullPath, fileStream); } // Close proxy. fileWatcherStreamingServiceProxy.Close(); } else { response = fileWatcherServiceProxy.SystemChanged(CreateRequest(e, checksum)); // Close proxy. fileWatcherServiceProxy.Close(); } // Decrease external process counter. SetExternalProcessRunningOff(); if (response == null) { // Run threaded event in main thread. _synchronizationContext.Send(new SendOrPostCallback(delegate { EventHandler<ServiceCalledEventArgs> handler = ServiceCalled; if (handler != null) { handler(this, new ServiceCalledEventArgs(e.ConfigurationKeyValuePair.Key, String.Empty, e.Id)); } }), null); } else { // Run threaded event in main thread. _synchronizationContext.Send(new SendOrPostCallback(delegate { EventHandler<ServiceCalledEventArgs> handler = ServiceCalled; if (handler != null) { handler(this, new ServiceCalledEventArgs(e.ConfigurationKeyValuePair.Key, response.Message, e.Id)); } }), null); } } catch (Exception ex) { // Abort proxy. if (e.ConfigurationKeyValuePair.Value.StreamFile) { fileWatcherStreamingServiceProxy.Abort(); } else { fileWatcherServiceProxy.Abort(); } // Decrease external process counter. SetExternalProcessRunningOff(); // Run threaded event in main thread. _synchronizationContext.Send(new SendOrPostCallback(delegate { EventHandler<ServiceErrorEventArgs> handler = ServiceError; if (handler != null) { handler(this, new ServiceErrorEventArgs(e.ConfigurationKeyValuePair.Key, ex, e.Id, GetProcessQueueCount())); } }), null); } finally { // Remove available process from the file watcher. RemoveAvailableProcess(e.ConfigurationKeyValuePair.Key); // Decrease file watcher process count. RemoveProcessFromProcessBatchSize(e.ConfigurationKeyValuePair.Key); SetProcessRunningOff(); } }
/// <summary> /// Begins calling of service. /// </summary> /// <param name="e">File watcher event args for calling a service.</param> private void BeginCallService(FileWatcherEventArgs e) { // Turn on process running for synchronization of processes. SetProcessRunningOn(); // Increase external process counter. SetExternalProcessRunningOn(); // Run threaded event in main thread. _synchronizationContext.Send(new SendOrPostCallback(delegate { EventHandler<ServiceBeginCallEventArgs> handler = ServiceBeginCall; if (handler != null) { handler(this, new ServiceBeginCallEventArgs(e.ConfigurationKeyValuePair.Key, GetProcessQueueCount(), e.Id)); } }), null); CallServiceDelegate callServiceDelegate = new CallServiceDelegate(CallService); callServiceDelegate.BeginInvoke(e, null, null); }
/// <summary> /// Builds service request. /// </summary> /// <param name="e">File watcher event args for calling a service.</param> /// <param name="checksum">File checksum.</param> /// <returns>Service request.</returns> private static SystemChangedReqDC CreateRequest(FileWatcherEventArgs e, string checksum) { SystemChangedReqDC request = new SystemChangedReqDC(); request.ChangeType = e.ChangeType; request.DaemonName = e.ConfigurationKeyValuePair.Key; request.DateTime = e.DateTime; request.FileName = e.FileName; request.FullPath = e.FullPath; request.Id = e.Id; request.OldFullPath = e.OldFullPath; request.MachineName = Environment.MachineName; request.Checksum = checksum; return request; }
/// <summary> /// Runs synchronous or asynchronous process. /// </summary> /// <param name="process">Process to run.</param> private void RunProcessHelper(FileWatcherEventArgs process) { #if (!_NET_20) // If to call service. if (process.ConfigurationKeyValuePair.Value.CallService) { BeginCallService(process); } else { #endif StartProcess(process); #if (!_NET_20) } #endif }
/// <summary> /// Start the process or calls service synchronized with other processes. /// </summary> /// <param name="e">File watcher event args for running a process.</param> private void StartProcessSynchronizedHelper(FileWatcherEventArgs e) { #if (!_NET_20) // If to call service. if (e.ConfigurationKeyValuePair.Value.CallService) { CallServiceSynchronized(e); } else { #endif StartProcess(e); #if (!_NET_20) } #endif }
/// <summary> /// Runs synchronous or asynchronous process. /// </summary> /// <param name="process">Process to run.</param> private void RunProcess(FileWatcherEventArgs process) { // Increase file watcher process count. AddProcessToProcessBatchSize(process.ConfigurationKeyValuePair.Key); // Check if to use synchronized execution. if (SynchronousExecution) { StartProcessSynchronized(process); } else { RunProcessHelper(process); } }
/// <summary> /// Returns true if file is locked. /// </summary> /// <param name="process">Process to run.</param> /// <returns>True if file is locked.</returns> /// <remarks>Returns false if full path is a directory or file does not exist.</remarks> private static bool IsFileLocked(FileWatcherEventArgs process) { // If file is a directory. if (Directory.Exists(process.FullPath)) { return false; } // If file does not exist. if (!File.Exists(process.FullPath)) { return false; } try { FileInfo fileInfo = new FileInfo(process.FullPath); DateTime lastWrite = fileInfo.LastWriteTime; // Filter too fresh files. lastWrite = lastWrite.AddMilliseconds( process.ConfigurationKeyValuePair.Value.ProcessLockFileLastWriteDelay); // Check last write and creation time. if (lastWrite < DateTime.Now) { // If file can be opened or there is a critical error when opening the file. if (TryOpenFile(process.FullPath)) { return false; } } // File is locked. return true; } catch (SecurityException) { return false; } catch (UnauthorizedAccessException) { return false; } catch (PathTooLongException) { return false; } catch (NotSupportedException) { return false; } catch (IOException) { return false; } }
/// <summary> /// Start process specified in file watcher event args. /// </summary> /// <param name="e">File watcher event args for running a process.</param> /// <exception cref="Win32Exception">Unexpected error.</exception> private void StartProcess(FileWatcherEventArgs e) { try { // Turn on process running for synchronization of processes. SetProcessRunningOn(); // Increase external process counter. SetExternalProcessRunningOn(); ProcessRunner processRunner = new ProcessRunner(e); // Subscribe to process events. processRunner.ProcessStarted += new EventHandler<ProcessStartedEventArgs>(OnProcessStarted); processRunner.ProcessExited += new EventHandler<ProcessExitEventArgs>(OnProcessExited); if (e.ConfigurationKeyValuePair.Value.ProcessRedirectStandardOutput) { processRunner.ProcessErrorData += new EventHandler<ProcessDataEventArgs>(OnProcessErrorData); } if (e.ConfigurationKeyValuePair.Value.ProcessRedirectStandardError) { processRunner.ProcessOutputData += new EventHandler<ProcessDataEventArgs>(OnProcessOutputData); } processRunner.StartProcess(); } catch (InvalidOperationException exception) { RaiseProcessError(exception, e); } catch (ArgumentException exception) { RaiseProcessError(exception, e); } catch (Win32Exception exception) { if (exception.NativeErrorCode == ErrorFileNotFound) { RaiseProcessError(exception, e); } else if (exception.NativeErrorCode == ErrorAccessDenied) { RaiseProcessError(exception, e); } else if (exception.NativeErrorCode == // User account. ErrorUnknownUserNameOrBadPassword) { RaiseProcessError(exception, e); } else if (exception.NativeErrorCode == // User account. ErrorUserAccountRestriction) { RaiseProcessError(exception, e); } else // Unexpected error occured. { // Raise event since we are in a thread. RaiseProcessError(exception, e); } } }
/// <summary> /// Raises process error event. Reduces process counts. /// </summary> /// <param name="exception">Exception that occured.</param> /// <param name="e">Event data.</param> private void RaiseProcessError(Exception exception, FileWatcherEventArgs e) { // Decrease external process counter. SetExternalProcessRunningOff(); ProcessErrorEventArgs processErrorEventArgs = new ProcessErrorEventArgs(e.ConfigurationKeyValuePair.Key, exception, GetProcessQueueCount()); OnProcessError(this, processErrorEventArgs); // Remove available process from the file watcher. RemoveAvailableProcess(e.ConfigurationKeyValuePair.Key); // Decrease file watcher process count. RemoveProcessFromProcessBatchSize(e.ConfigurationKeyValuePair.Key); SetProcessRunningOff(); }
/// <summary> /// Returns true if process should be re-enqueued. /// </summary> /// <param name="process">Process to check.</param> /// <returns>True if process should be re-enqueued.</returns> private bool CheckEnqueueCount(FileWatcherEventArgs process) { // If no limit set. if (process.ConfigurationKeyValuePair.Value.ProcessLockFileRetries == 0) { return true; } // If not controller is stopping and if the process queue limit is not reached. if (!IsControllerStopping && process.ConfigurationKeyValuePair.Value.ProcessLockFileRetriesQueueLimit >= (GetProcessQueueCount() + 1)) { return true; } // Check the process retries count. return _lockedProcesses[process.Id] <= process.ConfigurationKeyValuePair.Value.ProcessLockFileRetries; }
/// <summary> /// Handles system changed event. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">Event data.</param> /// <exception cref="ArgumentNullException">e is null.</exception> protected override void OnSystemChanged(object sender, FileWatcherEventArgs e) { if (e == null) { throw new ArgumentNullException("e", Resources.ArgumentNullException); } base.OnSystemChanged(sender, e); if (e.ConfigurationKeyValuePair.Value.DisplayFileSystemChange) { _consoleView.EchoLine(String.Format(CultureInfo.CurrentCulture, Resources.MessageFileChanged, @e.ChangeType, @e.FileName)); } }
/// <summary> /// Returns true if process is ready to run. Removes locked process if process is not re-enqueued. /// </summary> /// <param name="process">Process to check.</param> /// <returns>True if process is ready to run.</returns> private bool CheckFileMustExist(FileWatcherEventArgs process) { if (process.ConfigurationKeyValuePair.Value.ProcessFileMustExist) { if (!File.Exists(process.FullPath)) { // Remove locked process (file). if (_lockedProcesses.ContainsKey(process.Id)) { _lockedProcesses.Remove(process.Id); } // Remove process. return false; } } // Run process. return true; }
/// <summary> /// Handles system changed event. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">Event data.</param> /// <exception cref="ArgumentNullException">e is null.</exception> protected override void OnSystemChanged(object sender, FileWatcherEventArgs e) { if (e == null) { throw new ArgumentNullException("e", Resources.ArgumentNullException); } base.OnSystemChanged(sender, e); _fileWatcherSortedDictionary[e.ConfigurationKeyValuePair.Key].LastEventType = e.ChangeType; _fileWatcherSortedDictionary[e.ConfigurationKeyValuePair.Key].LastEventTime = e.DateTime.ToLocalTime().ToString(CultureInfo.CurrentCulture); IncreaseEventCount(e.ConfigurationKeyValuePair.Key); UpdateList(false); }
/// <summary> /// Returns true if process is ready to run. Waits if all processes are delayed or locked. /// </summary> /// <param name="process">Process to check.</param> /// <returns>True if process is ready to run.</returns> private bool CheckProcessDelay(FileWatcherEventArgs process) { if (process.ConfigurationKeyValuePair.Value.ProcessDelay == 0) { // Run process. return true; } DateTime delayedTime = process.DateTime.AddMilliseconds( process.ConfigurationKeyValuePair.Value.ProcessDelay); if (delayedTime > DateTime.Now) { if (!_delayedProcesses.ContainsKey(process.Id)) { _delayedProcesses.Add(process.Id, true); } // If all processes are delayed. if ((GetProcessQueueCount() + 1) == _delayedProcesses.Count) { Thread.Sleep(ProcessInterval); } // If all processes are locked or delayed. else if ((GetProcessQueueCount() + 1) == (_lockedProcesses.Count + _delayedProcesses.Count)) { Thread.Sleep(ProcessInterval); } // Re-enqueues process for a run. return false; } if (_delayedProcesses.ContainsKey(process.Id)) { _delayedProcesses.Remove(process.Id); } // Run process. return true; }
/// <summary> /// Returns process arguments with replaced values. /// </summary> /// <param name="e">File watcher event args for running a process.</param> /// <returns>Process arguments with replaced values.</returns> private static string GetProcessArguments(FileWatcherEventArgs e) { // If something to replace if (!String.IsNullOrEmpty(e.ConfigurationKeyValuePair.Value.ProcessArguments)) { string arguments = e.ConfigurationKeyValuePair.Value.ProcessArguments; // Replace escape strings with values. if (e.ConfigurationKeyValuePair.Value.ProcessUseChangeTypeAsArgument) { arguments = GetArgumentsWithChangeType(arguments, e); } if (e.ConfigurationKeyValuePair.Value.ProcessUseFileNameAsArgument) { arguments = GetArgumentsWithFileName(arguments, e); } if (e.ConfigurationKeyValuePair.Value.ProcessUseOldFileNameAsArgument) { arguments = GetArgumentsWithOldFileName(arguments, e); } return arguments; } return e.ConfigurationKeyValuePair.Value.ProcessArguments; // Nothing to replace. }
/// <summary> /// Returns true if process is ready to run. Waits if all processes are delayed or locked. /// </summary> /// <param name="process">Process to check.</param> /// <returns>True if process is ready to run.</returns> private bool CheckFileLock(FileWatcherEventArgs process) { if (!process.ConfigurationKeyValuePair.Value.ProcessLockFile) { // Run process. return true; } // Check if file is locked. if (IsFileLocked(process)) { if (_lockedProcesses.ContainsKey(process.Id)) { // Nice overflow. if (_lockedProcesses[process.Id] != Int32.MaxValue) { // Increase enqueue count. _lockedProcesses[process.Id]++; } } else { // Add locked process (file) if it does not exists. _lockedProcesses.Add(process.Id, 1); } // If all processes are locked. if ((GetProcessQueueCount() + 1) == _lockedProcesses.Count) { Thread.Sleep(ProcessInterval); } // If all processes are locked or delayed. else if ((GetProcessQueueCount() + 1) == (_lockedProcesses.Count + _delayedProcesses.Count)) { Thread.Sleep(ProcessInterval); } // Re-enqueues process for a run. return false; } // Remove locked process (file). if (_lockedProcesses.ContainsKey(process.Id)) { _lockedProcesses.Remove(process.Id); } // Run process. return true; }
/// <summary> /// Handles system changed event. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">Event data.</param> /// <exception cref="ArgumentNullException">e is null.</exception> protected virtual void OnSystemChanged(object sender, FileWatcherEventArgs e) { if (e == null) { throw new ArgumentNullException("e", Resources.ArgumentNullException); } if (e.ConfigurationKeyValuePair.Value.LogFileSystemChange) { _logger.Log(_formatter.Format(e)); } }
/// <summary> /// Calls rename file and counts rename retries. /// </summary> /// <param name="process">Running process.</param> /// <param name="renameResult">Rename result.</param> /// <returns>Returns new FileWatcherEventArgs with new renamed file path or null /// if the process is re-queued or rename fails or is canceled.</returns> private FileWatcherEventArgs CallRenameFile(FileWatcherEventArgs process, out RenameResult renameResult) { // If file is a directory. if (Directory.Exists(process.FullPath)) { renameResult = RenameResult.Cancel; return null; } // Check if file exists. if (!File.Exists(process.FullPath)) { renameResult = RenameResult.Cancel; return null; } // Check retries count if to continue. if (_tryRenameFile.ContainsKey(process.Id)) { if (process.ConfigurationKeyValuePair.Value.TryRenameFileRetries == _tryRenameFile[process.Id]) { renameResult = RenameResult.Cancel; return null; } } // Try to rename the file. FileWatcherEventArgs fileWatcherEventArgs = TryRenameFile(process, out renameResult); // If to re-enqueue. if (renameResult == RenameResult.Retry) { // Add or increment counter. if (!_tryRenameFile.ContainsKey(process.Id)) { _tryRenameFile.Add(process.Id, 0); } else { _tryRenameFile[process.Id]++; } } else // Remove counter. { if (_tryRenameFile.ContainsKey(process.Id)) { _tryRenameFile.Remove(process.Id); } } // Return original process or a new process with renamed file path. return fileWatcherEventArgs; }