첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 특정 파일을 사용하는 프로세스 리스트 구하기

------------------------------------------------------------------------------------------------------------------------

TestProject.zip


ProcessHelper.cs

 

 

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Runtime.InteropServices;

 

namespace TestProject

{

    /// <summary>

    /// 프로세스 헬퍼

    /// </summary>

    public static class ProcessHelper

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// RM_REBBOT_REASON_NONE

        /// </summary>

        private const int RM_REBBOT_REASON_NONE = 0;

 

        /// <summary>

        /// CCH_RM_MAX_APP_NAME

        /// </summary>

        private const int CCH_RM_MAX_APP_NAME = 255;

 

        /// <summary>

        /// CCH_RM_MAX_SVC_NAME

        /// </summary>

        private const int CCH_RM_MAX_SVC_NAME = 63;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region RESTART MANAGER 애플리케이션 타입 - RM_APP_TYPE

 

        /// <summary>

        /// RESTART MANAGER 애플리케이션 타입

        /// </summary>

        private enum RM_APP_TYPE

        {

            /// <summary>

            /// UNKNOWN_APPLICATION

            /// </summary>

            UNKNOWN_APPLICATION = 0,

 

            /// <summary>

            /// MAIN_WINDOW

            /// </summary>

            MAIN_WINDOW = 1,

 

            /// <summary>

            /// OTHER_WINDOW

            /// </summary>

            OTHER_WINDOW = 2,

 

            /// <summary>

            /// SERVICE

            /// </summary>

            SERVICE = 3,

 

            /// <summary>

            /// EXPLORER

            /// </summary>

            EXPLORER = 4,

 

            /// <summary>

            /// CONSOLE

            /// </summary>

            CONSOLE = 5,

 

            /// <summary>

            /// CRITICAL

            /// </summary>

            CRITICAL = 1000

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Structure

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region RESTART MANAGER 유일 프로세스 - RM_UNIQUE_PROCESS

 

        /// <summary>

        /// RESTART MANAGER 유일 프로세스

        /// </summary>

        [StructLayout(LayoutKind.Sequential)]

        private struct RM_UNIQUE_PROCESS

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 프로세스 ID

            /// </summary>

            public int ProcessID;

 

            /// <summary>

            /// 프로세스 시작 시간

            /// </summary>

            public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;

 

            #endregion

        }

 

        #endregion

        #region RESTART MANAGER 프로세스 정보 - RM_PROCESS_INFO

 

        /// <summary>

        /// RESTART MANAGER 프로세스 정보

        /// </summary>

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

        private struct RM_PROCESS_INFO

        {

            /// <summary>

            /// 프로세스

            /// </summary>

            public RM_UNIQUE_PROCESS Process;

 

            /// <summary>

            /// 애플리케이션명

            /// </summary>

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]

            public string ApplicationName;

 

            /// <summary>

            /// 서비스 단축명

            /// </summary>

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]

            public string ServiceShortName;

 

            /// <summary>

            /// 애플리케이션 타입

            /// </summary>

            public RM_APP_TYPE ApplicationType;

 

            /// <summary>

            /// 애플리케이션 상태

            /// </summary>

            public uint ApplicationStatus;

 

            /// <summary>

            /// 터미널 서비스 세션 ID

            /// </summary>

            public uint TerminalServiceSessionID;

 

            /// <summary>

            /// 재시작 가능 여부

            /// </summary>

            [MarshalAs(UnmanagedType.Bool)]

            public bool bRestartable;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region RESTART MANAGER 리소스 등록하기 - RmRegisterResources(sessionHandle, fileCount, fileNameArray, processCount, processArray,

            serviceCount, serviceNameArray)

 

        /// <summary>

        /// RESTART MANAGER 리소스 등록하기

        /// </summary>

        /// <param name="sessionHandle">세션 핸들</param>

        /// <param name="fileCount">파일 카운트</param>

        /// <param name="fileNameArray">파일명 배열</param>

        /// <param name="processCount">프로세스 카운트</param>

        /// <param name="processArray">프로세스 배열</param>

        /// <param name="serviceCount">서비스 카운트</param>

        /// <param name="serviceNameArray">서비스명 배열</param>

        /// <returns>처리 결과</returns>

        [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]

        private static extern int RmRegisterResources(uint sessionHandle, uint fileCount, string[] fileNameArray, uint processCount,

            [In] RM_UNIQUE_PROCESS[] processArray, uint serviceCount, string[] serviceNameArray);

 

        #endregion

        #region RESTART MANAGER 세션 시작하기 - RmStartSession(sessionHandle, sessionFlag, sessionKey)

 

        /// <summary>

        /// RESTART MANAGER 세션 시작하기

        /// </summary>

        /// <param name="sessionHandle">세션 핸들</param>

        /// <param name="sessionFlag">세션 플래그</param>

        /// <param name="sessionKey">세션 키</param>

        /// <returns>처리 결과</returns>

        [DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]

        private static extern int RmStartSession(out uint sessionHandle, int sessionFlag, string sessionKey);

 

        #endregion

        #region RESTART MANAGER 세션 끝내기 - RmEndSession(sessionHandle)

 

        /// <summary>

        /// RESTART MANAGER 세션 끝내기

        /// </summary>

        /// <param name="sessionHandle">세션 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("rstrtmgr.dll")]

        private static extern int RmEndSession(uint sessionHandle);

 

        #endregion

        #region RESTART MANAGER 리스트 구하기 - RmGetList(sessionHandle, processCountNeeded, processCount, processArray, rebootReason)

 

        /// <summary>

        /// RESTART MANAGER 리스트 구하기

        /// </summary>

        /// <param name="sessionHandle">세션 핸들</param>

        /// <param name="processCountNeeded">필요 프로세스 카운트</param>

        /// <param name="processCount">프로세스 카운트</param>

        /// <param name="processArray">프로세스 배열</param>

        /// <param name="rebootReason">리부팅 사유</param>

        /// <returns>처리 결과</returns>

        [DllImport("rstrtmgr.dll")]

        private static extern int RmGetList(uint sessionHandle, out uint processCountNeeded, ref uint processCount,

            [In, Out] RM_PROCESS_INFO[] processArray, ref uint rebootReason);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 잠금 프로세스 리스트 구하기 - GetLockingProcessList(filePath)

 

        /// <summary>

        /// 잠금 프로세스 리스트 구하기

        /// </summary>

        /// <param name="filePath">파일명</param>

        /// <returns>잠금 프로세스 리스트</returns>

        public static List<Process> GetLockingProcessList(string filePath)

        {

            uint handle;

 

            string key = Guid.NewGuid().ToString();

 

            List<Process> processeList = new List<Process>();

 

            int result = RmStartSession(out handle, 0, key);

 

            if(result != 0)

            {

                throw new Exception("Could not begin restart session.\nUnable to determine file locker.");

            }

 

            try

            {

                const int ERROR_MORE_DATA = 234;

 

                uint processCountNeeded = 0;

                uint processCount       = 0;

                uint rebootReason       = RM_REBBOT_REASON_NONE;

 

                string[] fileNameArray = new string[] { filePath };

 

                result = RmRegisterResources(handle, (uint)fileNameArray.Length, fileNameArray, 0, null, 0, null);

 

                if(result != 0)

                {

                    throw new Exception("Could not register resource.");

                }

 

                result = RmGetList(handle, out processCountNeeded, ref processCount, null, ref rebootReason);

 

                if(result == ERROR_MORE_DATA)

                {

                    RM_PROCESS_INFO[] processArray = new RM_PROCESS_INFO[processCountNeeded];

 

                    processCount = processCountNeeded;

 

                    result = RmGetList(handle, out processCountNeeded, ref processCount, processArray, ref rebootReason);

 

                    if(result == 0)

                    {

                        processeList = new List<Process>((int)processCount);

 

                        for(int i = 0; i < processCount; i++)

                        {

                            try

                            {

                                processeList.Add(Process.GetProcessById(processArray[i].Process.ProcessID));

                            }

                            catch(ArgumentException)

                            {

                            }

                        }

                    }

                    else

                    {

                        throw new Exception("Could not list processes locking resource.");

                    }

                }

                else if(result != 0)

                {

                    throw new Exception("Could not list processes locking resource. Failed to get size of result.");

                }

            }

            finally

            {

                RmEndSession(handle);

            }

 

            return processeList;

        }

 

        #endregion

    }

}

 

 

Program.cs

 

 

using System;

using System.Collections.Generic;

using System.Diagnostics;

 

namespace TestProject

{

    /// <summary>

    /// 프로그램

    /// </summary>

    class Program

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 프로그램 시작하기 - Main()

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

        private static void Main()

        {

            List<Process> processList = ProcessHelper.GetLockingProcessList(@"c:\windows\system32\notepad.exe");

 

            foreach(Process process in processList)

            {

                Console.WriteLine(process.ProcessName);

            }

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요