[Mwinapi-commits] SF.net SVN: mwinapi:[90] trunk
Status: Beta
Brought to you by:
schierlm
From: <sch...@us...> - 2010-01-02 19:04:27
|
Revision: 90 http://mwinapi.svn.sourceforge.net/mwinapi/?rev=90&view=rev Author: schierlm Date: 2010-01-02 19:04:16 +0000 (Sat, 02 Jan 2010) Log Message: ----------- - Update copyright (it's a new year again) - Using PerformanceCounters for determining the parent process does not work properly when there is more than one process with the same process name. Therefore add a new class ProcessTree that uses toolhelp snapshots to determine process parents. - WinternalExplorer: * Update copyright (it's a new year again) * Update WinternalExplorer to use the ProcessTree class. * Handle InvalidOperationExceptions when showing thread details Modified Paths: -------------- trunk/ManagedWinapi/ManagedWinapi.csproj trunk/ManagedWinapi/Properties/AssemblyInfo.cs trunk/Tools/WinternalExplorer/MainForm.cs trunk/Tools/WinternalExplorer/Properties/AssemblyInfo.cs trunk/Tools/WinternalExplorer/ThreadControl.cs trunk/Tools/WinternalExplorer/WindowCache.cs Added Paths: ----------- trunk/ManagedWinapi/ProcessTree.cs Modified: trunk/ManagedWinapi/ManagedWinapi.csproj =================================================================== --- trunk/ManagedWinapi/ManagedWinapi.csproj 2009-11-27 21:36:27 UTC (rev 89) +++ trunk/ManagedWinapi/ManagedWinapi.csproj 2010-01-02 19:04:16 UTC (rev 90) @@ -61,6 +61,7 @@ </Compile> <Compile Include="MachineIdentifiers.cs" /> <Compile Include="ProcessMemoryChunk.cs" /> + <Compile Include="ProcessTree.cs" /> <Compile Include="ShortcutBox.cs"> <SubType>Component</SubType> </Compile> Added: trunk/ManagedWinapi/ProcessTree.cs =================================================================== --- trunk/ManagedWinapi/ProcessTree.cs (rev 0) +++ trunk/ManagedWinapi/ProcessTree.cs 2010-01-02 19:04:16 UTC (rev 90) @@ -0,0 +1,142 @@ +/* + * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to + * access native API by managed code. http://mwinapi.sourceforge.net/ + * Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Schierl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; see the file COPYING. if not, visit + * http://www.gnu.org/licenses/lgpl.html or write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace ManagedWinapi +{ + /// <summary> + /// Class for finding the parent and children of a <see cref="Process"/>. + /// </summary> + public class ProcessTree + { + + private IDictionary<int, int> parents = new Dictionary<int, int>(); + + /// <summary> + /// Create a new process tree. This process tree stores all parent/child + /// process relationships of the time when this process tree was created. + /// </summary> + public ProcessTree() + { + PROCESSENTRY32 procEntry = new PROCESSENTRY32(); + procEntry.dwSize = (UInt32)Marshal.SizeOf(typeof(PROCESSENTRY32)); + + IntPtr handleToSnapshot = CreateToolhelp32Snapshot((uint)SnapshotFlags.Process, 0); + if (!Process32First(handleToSnapshot, ref procEntry)) + throw new Win32Exception(); + + do + { + parents.Add(procEntry.th32ProcessID, procEntry.th32ParentProcessID); + } + while (Process32Next(handleToSnapshot, ref procEntry)); + + CloseHandle(handleToSnapshot); + } + + /// <summary> + /// Find the parent process of a process, or <code>null</code> if no such + /// process exists. + /// </summary> + /// <param name="process">Process to find parent of</param> + public Process FindParent(Process process) + { + if (parents.ContainsKey(process.Id)) + { + try + { + return Process.GetProcessById((int)parents[process.Id]); + } + catch (ArgumentException) { } // process has terminated + } + return null; + } + + /// <summary> + /// Find the child processes of a process, i. e. those processes + /// started by this process. + /// </summary> + /// <param name="process">Process to find children of</param> + public IList<Process> FindChildren(Process process) + { + List<Process> childProcs = new List<Process>(); + + foreach (KeyValuePair<int, int> pids in parents) + { + if (pids.Value == process.Id) + { + try + { + childProcs.Add(Process.GetProcessById(pids.Key)); + } + catch (ArgumentException) { } // process has terminated + } + } + return childProcs; + } + + #region PInvoke Declarations + [Flags] + private enum SnapshotFlags : uint + { + HeapList = 0x00000001, + Process = 0x00000002, + Thread = 0x00000004, + Module = 0x00000008, + Module32 = 0x00000010, + Inherit = 0x80000000, + All = 0x0000001F + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + private struct PROCESSENTRY32 + { + const int MAX_PATH = 260; + internal uint dwSize; + internal uint cntUsage; + internal int th32ProcessID; + internal IntPtr th32DefaultHeapID; + internal uint th32ModuleID; + internal uint cntThreads; + internal int th32ParentProcessID; + internal uint pcPriClassBase; + internal uint dwFlags; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] + internal string szExeFile; + } + + [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] + private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID); + + [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] + private static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe); + + [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] + private static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern int CloseHandle(IntPtr hObject); + #endregion + } +} Modified: trunk/ManagedWinapi/Properties/AssemblyInfo.cs =================================================================== --- trunk/ManagedWinapi/Properties/AssemblyInfo.cs 2009-11-27 21:36:27 UTC (rev 89) +++ trunk/ManagedWinapi/Properties/AssemblyInfo.cs 2010-01-02 19:04:16 UTC (rev 90) @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ManagedWinapi")] -[assembly: AssemblyCopyright("Copyright © 2005, 2006, 2007, 2008 Michael Schierl")] +[assembly: AssemblyCopyright("Copyright © 2005, 2006, 2007, 2008, 2009, 2010 Michael Schierl")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -31,5 +31,5 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.3")] -[assembly: AssemblyFileVersion("0.3")] +[assembly: AssemblyVersion("0.3.0.1")] +[assembly: AssemblyFileVersion("0.3.0.1")] Modified: trunk/Tools/WinternalExplorer/MainForm.cs =================================================================== --- trunk/Tools/WinternalExplorer/MainForm.cs 2009-11-27 21:36:27 UTC (rev 89) +++ trunk/Tools/WinternalExplorer/MainForm.cs 2010-01-02 19:04:16 UTC (rev 90) @@ -120,17 +120,6 @@ private static Dictionary<int, int> parentId = new Dictionary<int, int>(); - // not used - internal static int __UNUSED__GetParentID(Process proc) - { - if (!parentId.ContainsKey(proc.Id)) - { - PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", proc.ProcessName); - parentId[proc.Id] = (int)pc.RawValue; - } - return parentId[proc.Id]; - } - internal int DisplayProcesses { get Modified: trunk/Tools/WinternalExplorer/Properties/AssemblyInfo.cs =================================================================== --- trunk/Tools/WinternalExplorer/Properties/AssemblyInfo.cs 2009-11-27 21:36:27 UTC (rev 89) +++ trunk/Tools/WinternalExplorer/Properties/AssemblyInfo.cs 2010-01-02 19:04:16 UTC (rev 90) @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("WinternalExplorer")] -[assembly: AssemblyCopyright("Copyright © 2007, 2008 Michael Schierl")] +[assembly: AssemblyCopyright("Copyright © 2007, 2008, 2010 Michael Schierl")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -29,5 +29,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("0.3")] -[assembly: AssemblyFileVersion("0.3")] +[assembly: AssemblyVersion("0.3.0.1")] +[assembly: AssemblyFileVersion("0.3.0.1")] Modified: trunk/Tools/WinternalExplorer/ThreadControl.cs =================================================================== --- trunk/Tools/WinternalExplorer/ThreadControl.cs 2009-11-27 21:36:27 UTC (rev 89) +++ trunk/Tools/WinternalExplorer/ThreadControl.cs 2010-01-02 19:04:16 UTC (rev 90) @@ -35,6 +35,10 @@ { startTime.Text = currentThread.StartTime.ToString(); } + catch (InvalidOperationException ex) + { + startTime.Text = ex.Message; + } catch (Win32Exception) { startTime.Text = "Access denied"; @@ -50,6 +54,10 @@ { priorityLevel.Text = currentThread.PriorityLevel.ToString(); } + catch (InvalidOperationException ex) + { + startTime.Text = ex.Message; + } catch (Win32Exception) { startTime.Text = "Access denied"; @@ -64,6 +72,13 @@ userTime.Text = currentThread.UserProcessorTime.ToString(); totalTime.Text = currentThread.TotalProcessorTime.ToString(); } + catch (InvalidOperationException ex) + { + priorityBoost.Text = ex.Message; + privTime.Text = ex.Message; + userTime.Text = ex.Message; + totalTime.Text = ex.Message; + } catch (Win32Exception) { priorityBoost.Text = "Access denied"; Modified: trunk/Tools/WinternalExplorer/WindowCache.cs =================================================================== --- trunk/Tools/WinternalExplorer/WindowCache.cs 2009-11-27 21:36:27 UTC (rev 89) +++ trunk/Tools/WinternalExplorer/WindowCache.cs 2010-01-02 19:04:16 UTC (rev 90) @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using System.Diagnostics; +using ManagedWinapi; using ManagedWinapi.Windows; namespace WinternalExplorer @@ -120,18 +121,14 @@ private void LoadChildProcesses() { childProcesses = new Dictionary<int, List<Process>>(); + ProcessTree tree = new ProcessTree(); foreach (Process proc in Process.GetProcesses()) { - AddToList(childProcesses, ParentID(proc), proc); + Process parent = tree.FindParent(proc); + AddToList(childProcesses, parent == null ? 0 : parent.Id, proc); } } - public static int ParentID(Process proc) - { - PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", proc.ProcessName); - return (int)pc.RawValue; - } - internal bool IsProcessVisible(Process p) { return WindowsByProcess(p, true).Count > 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |