[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.
|