예제 #1
0
        public void New_Converts()
        {
            var info = new RM_PROCESS_INFO
            {
                ApplicationType = ApplicationType.MainWindow,
                AppStatus       = ApplicationStatus.Running,
                bRestartable    = true,
                Process         = new RM_UNIQUE_PROCESS
                {
                    dwProcessId      = 1234,
                    ProcessStartTime = new System.Runtime.InteropServices.ComTypes.FILETIME
                    {
                        dwHighDateTime = 30635685,
                        dwLowDateTime  = 1855111194,
                    },
                },
                strAppName          = "TestApp",
                strServiceShortName = "TestService",
                TSSessionId         = 1,
            };

            var sut = new ProcessInfo(info, RebootReason.PermissionDenied);

            Assert.Equal(ApplicationStatus.Running, sut.ApplicationStatus);
            Assert.Equal(ApplicationType.MainWindow, sut.ApplicationType);
            Assert.Equal("TestApp", sut.Description);
            Assert.Equal(1234, sut.Id);
            Assert.True(sut.IsRestartable);
            Assert.Equal(RebootReason.PermissionDenied, sut.RebootReason);
            Assert.Equal("TestService", sut.ServiceName);
            Assert.Equal(DateTimeOffset.FromFileTime(131579267020668954), sut.StartTime);
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ProcessInfo"/> class.
        /// </summary>
        /// <param name="process">The <see cref="RM_PROCESS_INFO"/> to adapt.</param>
        /// <param name="reason">The <see cref="RebootReason"/> of why the computer must be restarted.</param>
        internal ProcessInfo(RM_PROCESS_INFO process, RebootReason reason)
        {
            var fileTime = ((long)process.Process.ProcessStartTime.dwHighDateTime << 32) + process.Process.ProcessStartTime.dwLowDateTime;

            Id                = process.Process.dwProcessId;
            StartTime         = DateTimeOffset.FromFileTime(fileTime);
            Description       = process.strAppName;
            ServiceName       = process.strServiceShortName;
            ApplicationType   = process.ApplicationType;
            ApplicationStatus = process.AppStatus;
            IsRestartable     = process.bRestartable;
            RebootReason      = reason;
        }
예제 #3
0
        /// <summary>
        /// Gets the applications and services that will be shut down and possibly restated.
        /// </summary>
        /// <returns>An enumeration of <see cref="IProcessInfo"/> objects.</returns>
        /// <exception cref="ObjectDisposedException">This object has already been disposed.</exception>
        /// <exception cref="Win32Exception">An error occurred.</exception>
        internal IEnumerable <IProcessInfo> GetProcesses()
        {
            ThrowIfDisposed();

            if (IsRegistered)
            {
                var error  = NativeMethods.ERROR_SUCCESS;
                var length = 0;
                RM_PROCESS_INFO[] processes = null;
                var reason = RebootReason.None;

                do
                {
                    error = RestartManagerService.GetProcesses(SessionId, out var required, ref length, processes, out reason);
                    if (error == NativeMethods.ERROR_SUCCESS)
                    {
                        break;
                    }
                    else if (error == NativeMethods.ERROR_MORE_DATA)
                    {
                        length    = required;
                        processes = new RM_PROCESS_INFO[length];
                    }
                    else
                    {
                        ThrowOnError(error);
                    }
                }while (error == NativeMethods.ERROR_MORE_DATA);

                if (processes != null && processes.Length > 0)
                {
                    return(processes
                           .Select(process => new ProcessInfo(process, reason))
                           .ToArray());
                }
            }

            return(Enumerable.Empty <IProcessInfo>());
        }
예제 #4
0
        public void IsEqual()
        {
            var info = new RM_PROCESS_INFO
            {
                Process = new RM_UNIQUE_PROCESS
                {
                    dwProcessId = 0,
                },
                ApplicationType = ApplicationType.MainWindow,
                bRestartable    = true,
            };

            var a = new ProcessInfo(info, RebootReason.None);

            info.ApplicationType = ApplicationType.Console;
            info.bRestartable    = false;

            var b = new ProcessInfo(info, RebootReason.PermissionDenied);

            Assert.True(a.Equals(a));
            Assert.False(a.Equals(b));
            Assert.False(b.Equals(a));
        }
예제 #5
0
        public static List <Process> GetProcessesLockingFile(string path)
        {
            int handle;

            if (RmStartSession(out handle, 0, Guid.NewGuid().ToString()) != RmResult.ERROR_SUCCESS)
            {
                throw new Exception("Could not begin session. Unable to determine file lockers.");
            }

            try
            {
                string[] resources = { path }; // Just checking on one resource.
                if (RmRegisterResources(handle, (uint)resources.LongLength, resources, 0, null, 0, null) != RmResult.ERROR_SUCCESS)
                {
                    throw new Exception("Could not register resource.");
                }

                // The first try is done expecting at most ten processes to lock the file.
                uint     arraySize = 10;
                RmResult result;
                do
                {
                    RM_PROCESS_INFO[] array = new RM_PROCESS_INFO[arraySize];
                    uint             requiredArraySize;
                    RM_REBOOT_REASON lpdwRebootReasons;
                    result = RmGetList(handle, out requiredArraySize, ref arraySize, array, out lpdwRebootReasons);

                    if (result == RmResult.ERROR_SUCCESS)
                    {
                        // Adjust the array length to fit the actual count.
                        Array.Resize(ref array, (int)requiredArraySize);

                        List <Process> processes = new List <Process>((int)arraySize);
                        // Enumerate all of the results and add them to the
                        // list to be returned
                        for (int i = 0; i < arraySize; i++)
                        {
                            try
                            {
                                processes.Add(Process.GetProcessById(array[i].Process.dwProcessId));
                            }
                            // catch the error -- in case the process is no longer running
                            catch (ArgumentException) { }
                        }
                        return(processes);
                    }
                    else if (result == RmResult.ERROR_MORE_DATA)
                    {
                        // We need to initialize a bigger array. We only set the size, and do another iteration.
                        // (the out parameter requiredArraySize contains the expected value for the next try)
                        arraySize = requiredArraySize;
                    }
                    else
                    {
                        throw new Exception("Could not list processes locking resource. Failed to get size of result.");
                    }
                } while (result != RmResult.ERROR_SUCCESS);
            }
            finally
            {
                RmEndSession(handle);
            }

            return(new List <Process>());
        }