/// <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.
        }
Beispiel #2
0
 /// <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>
 /// 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);
        }
Beispiel #6
0
 /// <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;
 }
Beispiel #7
0
        /// <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;
 }
Beispiel #23
0
        /// <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;
        }
Beispiel #25
0
        /// <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;
        }