Ejemplo n.º 1
0
        internal ProcessInfo(NativeMethods.RM_PROCESS_INFO processInfo)
        {
            ProcessId = (int)processInfo.Process.dwProcessId;
            // ProcessStartTime is returned as local time, not UTC.
            StartTime = DateTime.FromFileTime((((long)processInfo.Process.ProcessStartTime.dwHighDateTime) << 32) |
                                              processInfo.Process.ProcessStartTime.dwLowDateTime);
            ApplicationName           = processInfo.strAppName;
            ServiceShortName          = processInfo.strServiceShortName;
            ApplicationType           = (ApplicationType)processInfo.ApplicationType;
            ApplicationStatus         = (ApplicationStatus)processInfo.AppStatus;
            Restartable               = processInfo.bRestartable;
            TerminalServicesSessionId = (int)processInfo.TSSessionId;

            try
            {
                var process = Process.GetProcessById(ProcessId);
                if (string.IsNullOrWhiteSpace(ApplicationName))
                {
                    ApplicationName = process.ProcessName;
                }

                FilePath = process.MainModule.FileName;
                UserName = NativeMethods.GetProcessOwner(process.SafeHandle);
            }
            catch
            {
            }
        }
Ejemplo n.º 2
0
 internal ProcessInfo(NativeMethods.RM_PROCESS_INFO processInfo)
 {
     ProcessId = (int)processInfo.Process.dwProcessId;
     // ProcessStartTime is returned as local time, not UTC.
     StartTime = DateTime.FromFileTime((((long)processInfo.Process.ProcessStartTime.dwHighDateTime) << 32) |
                                       processInfo.Process.ProcessStartTime.dwLowDateTime);
     ApplicationName           = processInfo.strAppName;
     ServiceShortName          = processInfo.strServiceShortName;
     ApplicationType           = (ApplicationType)processInfo.ApplicationType;
     ApplicationStatus         = (ApplicationStatus)processInfo.AppStatus;
     Restartable               = processInfo.bRestartable;
     TerminalServicesSessionId = (int)processInfo.TSSessionId;
 }
Ejemplo n.º 3
0
        public static IEnumerable<ProcessInfo> GetLockingProcessInfos(params string[] paths)
        {
            if (paths == null)
                throw new ArgumentNullException("paths");

            const int maxRetries = 6;

            // See http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx.
            var key = new StringBuilder(new string('\0', NativeMethods.CCH_RM_SESSION_KEY + 1));

            uint handle;
            int res = NativeMethods.RmStartSession(out handle, 0, key);
            if (res != 0)
                throw GetException(res, "RmStartSession", "Failed to begin restart manager session.");

            try
            {
                string[] resources = paths;
                res = NativeMethods.RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
                if (res != 0)
                    throw GetException(res, "RmRegisterResources", "Could not register resources.");

                //
                // Obtain the list of affected applications/services.
                //
                // NOTE: Restart Manager returns the results into the buffer allocated by the caller. The first call to 
                // RmGetList() will return the size of the buffer (i.e. nProcInfoNeeded) the caller needs to allocate. 
                // The caller then needs to allocate the buffer (i.e. rgAffectedApps) and make another RmGetList() 
                // call to ask Restart Manager to write the results into the buffer. However, since Restart Manager 
                // refreshes the list every time RmGetList()is called, it is possible that the size returned by the first 
                // RmGetList()call is not sufficient to hold the results discovered by the second RmGetList() call. Therefore, 
                // it is recommended that the caller follows the following practice to handle this race condition:
                //
                //    Use a loop to call RmGetList() in case the buffer allocated according to the size returned in previous 
                //    call is not enough.
                // 
                uint pnProcInfo = 0;
                NativeMethods.RM_PROCESS_INFO[] rgAffectedApps = null;
                int retry = 0;
                do
                {
                    uint lpdwRebootReasons = (uint)NativeMethods.RM_REBOOT_REASON.RmRebootReasonNone;
                    uint pnProcInfoNeeded;
                    res = NativeMethods.RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, rgAffectedApps, ref lpdwRebootReasons);
                    if (res == 0)
                    {
                        // If pnProcInfo == 0, then there is simply no locking process (found), in this case rgAffectedApps is "null".
                        if (pnProcInfo == 0)
                            return Enumerable.Empty<ProcessInfo>();

                        Debug.Assert(rgAffectedApps != null, "rgAffectedApps != null");
                        var lockInfos = new List<ProcessInfo>((int)pnProcInfo);
                        for (int i = 0; i < pnProcInfo; i++)
                        {
                            lockInfos.Add(new ProcessInfo(rgAffectedApps[i]));
                        }
                        return lockInfos;
                    }

                    if (res != NativeMethods.ERROR_MORE_DATA)
                        throw GetException(res, "RmGetList", string.Format("Failed to get entries (retry {0}).", retry));

                    pnProcInfo = pnProcInfoNeeded;
                    rgAffectedApps = new NativeMethods.RM_PROCESS_INFO[pnProcInfo];
                } while ((res == NativeMethods.ERROR_MORE_DATA) && (retry++ < maxRetries));
            }
            finally
            {
                res = NativeMethods.RmEndSession(handle);
                if (res != 0)
                    throw GetException(res, "RmEndSession", "Failed to end the restart manager session.");
            }

            return Enumerable.Empty<ProcessInfo>();
        }
Ejemplo n.º 4
0
        public static IEnumerable <ProcessInfo> GetLockingProcessInfos(params string[] paths)
        {
            if (paths == null)
            {
                throw new ArgumentNullException("paths");
            }

            const int maxRetries = 6;

            // See http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx.
            var key = new StringBuilder(new string('\0', NativeMethods.CCH_RM_SESSION_KEY + 1));

            uint handle;
            int  res = NativeMethods.RmStartSession(out handle, 0, key);

            if (res != 0)
            {
                throw GetException(res, "RmStartSession", "Failed to begin restart manager session.");
            }

            try
            {
                string[] resources = paths;
                res = NativeMethods.RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
                if (res != 0)
                {
                    throw GetException(res, "RmRegisterResources", "Could not register resources.");
                }

                //
                // Obtain the list of affected applications/services.
                //
                // NOTE: Restart Manager returns the results into the buffer allocated by the caller. The first call to
                // RmGetList() will return the size of the buffer (i.e. nProcInfoNeeded) the caller needs to allocate.
                // The caller then needs to allocate the buffer (i.e. rgAffectedApps) and make another RmGetList()
                // call to ask Restart Manager to write the results into the buffer. However, since Restart Manager
                // refreshes the list every time RmGetList()is called, it is possible that the size returned by the first
                // RmGetList()call is not sufficient to hold the results discovered by the second RmGetList() call. Therefore,
                // it is recommended that the caller follows the following practice to handle this race condition:
                //
                //    Use a loop to call RmGetList() in case the buffer allocated according to the size returned in previous
                //    call is not enough.
                //
                uint pnProcInfo = 0;
                NativeMethods.RM_PROCESS_INFO[] rgAffectedApps = null;
                int retry = 0;
                do
                {
                    uint lpdwRebootReasons = (uint)NativeMethods.RM_REBOOT_REASON.RmRebootReasonNone;
                    uint pnProcInfoNeeded;
                    res = NativeMethods.RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, rgAffectedApps, ref lpdwRebootReasons);
                    if (res == 0)
                    {
                        // If pnProcInfo == 0, then there is simply no locking process (found), in this case rgAffectedApps is "null".
                        if (pnProcInfo == 0)
                        {
                            return(Enumerable.Empty <ProcessInfo>());
                        }

                        Debug.Assert(rgAffectedApps != null, "rgAffectedApps != null");
                        var lockInfos = new List <ProcessInfo>((int)pnProcInfo);
                        for (int i = 0; i < pnProcInfo; i++)
                        {
                            lockInfos.Add(new ProcessInfo(rgAffectedApps[i]));
                        }
                        return(lockInfos);
                    }

                    if (res != NativeMethods.ERROR_MORE_DATA)
                    {
                        throw GetException(res, "RmGetList", string.Format("Failed to get entries (retry {0}).", retry));
                    }

                    pnProcInfo     = pnProcInfoNeeded;
                    rgAffectedApps = new NativeMethods.RM_PROCESS_INFO[pnProcInfo];
                } while ((res == NativeMethods.ERROR_MORE_DATA) && (retry++ < maxRetries));
            }
            finally
            {
                res = NativeMethods.RmEndSession(handle);
                if (res != 0)
                {
                    throw GetException(res, "RmEndSession", "Failed to end the restart manager session.");
                }
            }

            return(Enumerable.Empty <ProcessInfo>());
        }