728x90
728x170
▶ 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", 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", 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")]
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")]
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
}
}
728x90
▶ 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
}
}
728x90
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] 깊이 우선 탐색하기 (Depth-First Search) (0) | 2018.04.28 |
---|---|
[C#/COMMON] 런타임에서 코드로 C# 코드 생성하기 (0) | 2018.04.26 |
[C#/COMMON] CodeDomProvider 클래스 : 런타임에서 C# 코드를 동적으로 컴파일하고 DLL 파일 생성하기 (0) | 2018.04.26 |
[C#/COMMON] CSharpCompilation 클래스 : 런타임에서 C# 코드를 동적으로 컴파일하기 (0) | 2018.04.26 |
[C#/COMMON] Stream 클래스 : 스로틀(Throttle) 스트림 만들기 (0) | 2018.04.09 |
[C#/COMMON] 사용자 계정 변경하기 (0) | 2018.03.24 |
[C#/COMMON] 콘솔(Console) 닫기 버튼 비활성화 하기 (0) | 2018.03.22 |
[C#/COMMON] 디버그 모드에서 프로세스 참조 구하기 (0) | 2018.03.15 |
[C#/COMMON] ITypedList 인터페이스 : TypedCollection<T> 만들기 (0) | 2018.03.11 |
[C#/COMMON] BitConverter : ToString 정적 메소드를 사용해 바이트 배열에서 문자열 구하기 (0) | 2018.03.04 |