1 using System;
2 using System.Collections.Generic;
3 using System.Runtime.InteropServices;
4 using System.Text;
5 using System.ComponentModel;
6
7 namespace Upgrade
8 {
9 /// <summary>
10 /// Contains information about a process.
11 /// This information is collected by ProcessCE.GetProcesses().
12 /// </summary>
13 public class ProcessInfo
14 {
15 [DllImport("coredll.dll", SetLastError = true)]
16 private static extern int GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize);
17
18 private const int INVALID_HANDLE_VALUE = -1;
19
20 private IntPtr _pid;
21 private int _threadCount;
22 private int _baseAddress;
23 private int _parentProcessID;
24 private string _fullPath;
25
26 internal ProcessInfo(IntPtr pid, int threadcount, int baseaddress, int parentid)
27 {
28 _pid = pid;
29 _threadCount = threadcount;
30 _baseAddress = baseaddress;
31 _parentProcessID = parentid;
32
33 StringBuilder sb = new StringBuilder(1024);
34 GetModuleFileName(_pid, sb, sb.Capacity);
35 _fullPath = sb.ToString();
36 }
37
38 /// <summary>
39 /// Returns the full path to the process .EXE file.
40 /// </summary>
41 /// <example>"\Program Files\Acme\main.exe"</example>
42 public override string ToString()
43 {
44 return _fullPath;
45 }
46
47 public int BaseAddress
48 {
49 get { return _baseAddress; }
50 }
51
52 public int ThreadCount
53 {
54 get { return _threadCount; }
55 }
56
57 /// <summary>
58 /// Returns the Process Id.
59 /// </summary>
60 public IntPtr Pid
61 {
62 get { return _pid; }
63 }
64
65 /// <summary>
66 /// Returns the full path to the process .EXE file.
67 /// </summary>
68 /// <example>"\Program Files\Acme\main.exe"</example>
69 public string FullPath
70 {
71 get { return _fullPath; }
72 }
73
74 public int ParentProcessID
75 {
76 get { return _parentProcessID; }
77 }
78
79 /// <summary>
80 /// Kills the process.
81 /// </summary>
82 /// <exception cref="Win32Exception">Thrown when killing the process fails.</exception>
83 public void Kill()
84 {
85 ProcessCE.Kill(_pid);
86 }
87
88 }
89
90 /// <summary>
91 /// Static class that provides Windows CE process information and manipulation.
92 /// The biggest difference with the Compact Framework's Process class is that this
93 /// class works with the full path to the .EXE file. And not the pathless .EXE file name.
94 /// </summary>
95 public static class ProcessCE
96 {
97 private const int MAX_PATH = 260;
98 private const int TH32CS_SNAPPROCESS = 0x00000002;
99 private const int TH32CS_SNAPNOHEAPS = 0x40000000;
100 private const int INVALID_HANDLE_VALUE = -1;
101 private const int PROCESS_TERMINATE = 1;
102
103 /// <summary>
104 /// Returns an array with information about running processes.
105 /// </summary>
106 ///<exception cref="Win32Exception">Thrown when enumerating the processes fails.</exception>
107 public static ProcessInfo[] GetProcesses()
108 {
109 List<ProcessInfo> procList = new List<ProcessInfo>();
110
111 IntPtr handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0);
112
113 if ((Int32)handle == INVALID_HANDLE_VALUE)
114 throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateToolhelp32Snapshot error.");
115
116 try
117 {
118 PROCESSENTRY processentry = new PROCESSENTRY();
119 processentry.dwSize = (uint)Marshal.SizeOf(processentry);
120
121 //Get the first process
122 int retval = Process32First(handle, ref processentry);
123
124 while (retval == 1)
125 {
126 procList.Add(new ProcessInfo(new IntPtr((int)processentry.th32ProcessID), (int)processentry.cntThreads, (int)processentry.th32MemoryBase, (int)processentry.th32ParentProcessID));
127 retval = Process32Next(handle, ref processentry);
128 }
129 }
130 finally
131 {
132 CloseToolhelp32Snapshot(handle);
133 }
134
135 return procList.ToArray();
136 }
137
138 /// <summary>
139 /// Checks if the specified .EXE is running.
140 /// </summary>
141 /// <param name="fullpath">The full path to an .EXE file.</param>
142 /// <returns>Returns true is the process is running.</returns>
143 /// <exception cref="Win32Exception">Thrown when taking a system snapshot fails.</exception>
144 public static bool IsRunning(string fullpath)
145 {
146 return (FindProcessPID(fullpath) != IntPtr.Zero);
147 }
148
149 /// <summary>
150 /// Finds and kills if the process for the specified .EXE file is running.
151 /// </summary>
152 /// <param name="fullpath">The full path to an .EXE file.</param>
153 /// <returns>True if the process was terminated. False if the process was not found.</returns>
154 /// <exception cref="Win32Exception">Thrown when opening or killing the process fails.</exception>
155 public static bool FindAndKill(string fullpath)
156 {
157 IntPtr pid = FindProcessPID(fullpath);
158
159 if (pid == IntPtr.Zero)
160 return false;
161
162 Kill(pid);
163
164 return true;
165 }
166
167 /// <summary>
168 /// Terminates the process with the specified Process Id.
169 /// </summary>
170 /// <param name="pid">The Process Id of the process to kill.</param>
171 /// <exception cref="Win32Exception">Thrown when opening or killing the process fails.</exception>
172 internal static void Kill(IntPtr pid)
173 {
174
175 IntPtr process_handle = OpenProcess(PROCESS_TERMINATE, false, (int)pid);
176
177 if (process_handle == (IntPtr)INVALID_HANDLE_VALUE)
178 throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcess failed.");
179
180 try
181 {
182 bool result = TerminateProcess(process_handle, 0);
183
184 if (result == false)
185 throw new Win32Exception(Marshal.GetLastWin32Error(), "TerminateProcess failed.");
186
187 }
188 finally
189 {
190 CloseHandle(process_handle);
191 }
192 }
193
194 /// <summary>
195 /// Finds the Process Id of the specified .EXE file.
196 /// </summary>
197 /// <param name="fullpath">The full path to an .EXE file.</param>
198 /// <returns>The Process Id to the process found. Return IntPtr.Zero if the process is not running.</returns>
199 ///<exception cref="Win32Exception">Thrown when taking a system snapshot fails.</exception>
200 public static IntPtr FindProcessPID(string fullpath)
201 {
202 fullpath = fullpath.ToLower();
203
204 IntPtr snapshot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0);
205
206 if ((Int32)snapshot_handle == INVALID_HANDLE_VALUE)
207 throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateToolhelp32Snapshot failed.");
208
209 try
210 {
211 PROCESSENTRY processentry = new PROCESSENTRY();
212 processentry.dwSize = (uint)Marshal.SizeOf(processentry);
213 StringBuilder fullexepath = new StringBuilder(1024);
214
215 int retval = Process32First(snapshot_handle, ref processentry);
216
217 while (retval == 1)
218 {
219 IntPtr pid = new IntPtr((int)processentry.th32ProcessID);
220
221 // Writes the full path to the process into a StringBuilder object.
222 // Note: If first parameter is IntPtr.Zero it returns the path to the current process.
223 GetModuleFileName(pid, fullexepath, fullexepath.Capacity);
224
225 if (fullexepath.ToString().ToLower() == fullpath)
226 return pid;
227
228 retval = Process32Next(snapshot_handle, ref processentry);
229 }
230 }
231 finally
232 {
233 CloseToolhelp32Snapshot(snapshot_handle);
234 }
235
236 return IntPtr.Zero;
237 }
238
239 [DllImport("coredll.Dll", EntryPoint = "CreateProcess", SetLastError = true)]
240 public extern static int CreateProcess(string strImageName, string strCmdLine, IntPtr pProcessAttributes,
241 IntPtr pThreadAttributes, int bInheritsHandle, int dwCreationFlags,
242 IntPtr pEnvironment, IntPtr pCurrentDir, IntPtr bArray, ProcessContext oProc);
243
244 [DllImport("toolhelp.dll", SetLastError = true)]
245 private static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processID);
246
247 [DllImport("toolhelp.dll")]
248 private static extern int CloseToolhelp32Snapshot(IntPtr snapshot);
249
250 [DllImport("toolhelp.dll")]
251 private static extern int Process32First(IntPtr snapshot, ref PROCESSENTRY processEntry);
252
253 [DllImport("toolhelp.dll")]
254 private static extern int Process32Next(IntPtr snapshot, ref PROCESSENTRY processEntry);
255
256 [DllImport("coredll.dll", SetLastError = true)]
257 private static extern int GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize);
258
259 [DllImport("coredll.dll", SetLastError = true)]
260 private static extern bool TerminateProcess(IntPtr hProcess, uint ExitCode);
261
262 [DllImport("coredll.dll", SetLastError = true)]
263 private static extern IntPtr OpenProcess(int flags, bool fInherit, int PID);
264
265 [DllImport("coredll.dll")]
266 private static extern bool CloseHandle(IntPtr handle);
267
268 private struct PROCESSENTRY
269 {
270 public uint dwSize;
271 public uint cntUsage;
272 public uint th32ProcessID;
273 public uint th32DefaultHeapID;
274 public uint th32ModuleID;
275 public uint cntThreads;
276 public uint th32ParentProcessID;
277 public int pcPriClassBase;
278 public uint dwFlags;
279 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
280 public string szExeFile;
281 public uint th32MemoryBase;
282 public uint th32AccessKey;
283 }
284
285 } // end of class
286
287 public class ProcessContext
288 {
289 public Int32 hProcess;
290 public Int32 hThread;
291 public Int32 ProcessID;
292 public Int32 ThreadID;
293 }
294 }