在Windows Mobile和Wince(Windows Embedded CE)下如何使用.NET Compact Framework开发进程管理程序...

在.NET Compact Framework 的进程管理需要调用win32的API,也就是P/Invoke,在msnd上提供了这一P/Invoke的源代码, Creating a Microsoft .NET Compact Framework-based Process Manager Application,由于在技术交流群里有不同的人问同样的问题,因此打算写一下。

Win32 API

关键的API 如下:

   private   const   int  TH32CS_SNAPPROCESS  =   0x00000002 ;
        [DllImport(
" toolhelp.dll " )]
        
public   static   extern  IntPtr CreateToolhelp32Snapshot( uint  flags,  uint  processid);
        [DllImport(
" toolhelp.dll " )]
        
public   static   extern   int  CloseToolhelp32Snapshot(IntPtr handle);
        [DllImport(
" toolhelp.dll " )]
        
public   static   extern   int  Process32First(IntPtr handle,  byte [] pe);
        [DllImport(
" toolhelp.dll " )]
        
public   static   extern   int  Process32Next(IntPtr handle,  byte [] pe);
        [DllImport(
" coredll.dll " )]
        
private   static   extern  IntPtr OpenProcess( int  flags,  bool  fInherit,  int  PID);
        
private   const   int  PROCESS_TERMINATE  =   1 ;
        [DllImport(
" coredll.dll " )]
        
private   static   extern   bool  TerminateProcess(IntPtr hProcess,  uint  ExitCode);
        [DllImport(
" coredll.dll " )]
        
private   static   extern   bool  CloseHandle(IntPtr handle);
        
private   const   int  INVALID_HANDLE_VALUE  =   - 1 ;

调用上面的API就能就能轮询出所有的进程,可以杀死指定进程了。

 

Structures

调用这些API需要下面的结构体 PROCESSENTRY32,结构体的转换是P/Invoke里面最难的部分,我曾经写过一篇这样的文章(.NET Compact Framework 下Win32 API P/Invoke 的使用),还是有很多需要学习和改进的地方,欢迎指教。

 

ContractedBlock.gif ExpandedBlockStart.gif PROCESSENTRY32 implementation
#region PROCESSENTRY32 implementation

//        typedef struct tagPROCESSENTRY32 
//        { 
//            DWORD dwSize; 
//            DWORD cntUsage; 
//            DWORD th32ProcessID; 
//            DWORD th32DefaultHeapID; 
//            DWORD th32ModuleID; 
//            DWORD cntThreads; 
//            DWORD th32ParentProcessID; 
//            LONG pcPriClassBase; 
//            DWORD dwFlags; 
//            TCHAR szExeFile[MAX_PATH]; 
//            DWORD th32MemoryBase;
//            DWORD th32AccessKey;
//        } PROCESSENTRY32;

        
private class PROCESSENTRY32
        {
            
// constants for structure definition
            private const int SizeOffset = 0;
            
private const int UsageOffset = 4;
            
private const int ProcessIDOffset=8;
            
private const int DefaultHeapIDOffset = 12;
            
private const int ModuleIDOffset = 16;
            
private const int ThreadsOffset = 20;
            
private const int ParentProcessIDOffset = 24;
            
private const int PriClassBaseOffset = 28;
            
private const int dwFlagsOffset = 32;
            
private const int ExeFileOffset = 36;
            
private const int MemoryBaseOffset = 556;
            
private const int AccessKeyOffset = 560;
            
private const int Size = 564;
            
private const int MAX_PATH = 260;

            
// data members
            public uint dwSize; 
            
public uint cntUsage; 
            
public uint th32ProcessID; 
            
public uint th32DefaultHeapID; 
            
public uint th32ModuleID; 
            
public uint cntThreads; 
            
public uint th32ParentProcessID; 
            
public long pcPriClassBase; 
            
public uint dwFlags; 
            
public string szExeFile;
            
public uint th32MemoryBase;
            
public uint th32AccessKey;
        
            
//Default constructor
            public PROCESSENTRY32()
            {


            }

            
// create a PROCESSENTRY instance based on a byte array        
            public PROCESSENTRY32(byte[] aData)
            {
                dwSize 
= GetUInt(aData, SizeOffset);
                cntUsage 
= GetUInt(aData, UsageOffset);
                th32ProcessID 
= GetUInt(aData, ProcessIDOffset);
                th32DefaultHeapID 
= GetUInt(aData, DefaultHeapIDOffset);
                th32ModuleID 
= GetUInt(aData, ModuleIDOffset);
                cntThreads 
= GetUInt(aData, ThreadsOffset);
                th32ParentProcessID 
= GetUInt(aData, ParentProcessIDOffset);
                pcPriClassBase 
= (long) GetUInt(aData, PriClassBaseOffset);
                dwFlags 
= GetUInt(aData, dwFlagsOffset);
                szExeFile 
= GetString(aData, ExeFileOffset, MAX_PATH);
                th32MemoryBase 
= GetUInt(aData, MemoryBaseOffset);
                th32AccessKey 
= GetUInt(aData, AccessKeyOffset);
            }

            
#region Helper conversion functions
            
// utility:  get a uint from the byte array
            private static uint GetUInt(byte[] aData, int Offset)
            {
                
return BitConverter.ToUInt32(aData, Offset);
            }
        
            
// utility:  set a uint int the byte array
            private static void SetUInt(byte[] aData, int Offset, int Value)
            {
                
byte[] buint = BitConverter.GetBytes(Value);
                Buffer.BlockCopy(buint, 
0, aData, Offset, buint.Length);
            }

            
// utility:  get a ushort from the byte array
            private static ushort GetUShort(byte[] aData, int Offset)
            {
                
return BitConverter.ToUInt16(aData, Offset);
            }
        
            
// utility:  set a ushort int the byte array
            private static void SetUShort(byte[] aData, int Offset, int Value)
            {
                
byte[] bushort = BitConverter.GetBytes((short)Value);
                Buffer.BlockCopy(bushort, 
0, aData, Offset, bushort.Length);
            }
        
            
// utility:  get a unicode string from the byte array
            private static string GetString(byte[] aData, int Offset, int Length)
            {
                String sReturn 
=  Encoding.Unicode.GetString(aData, Offset, Length);
                
return sReturn;
            }
        
            
// utility:  set a unicode string in the byte array
            private static void SetString(byte[] aData, int Offset, string Value)
            {
                
byte[] arr = Encoding.ASCII.GetBytes(Value);
                Buffer.BlockCopy(arr, 
0, aData, Offset, arr.Length);
            }
            
#endregion

            
// create an initialized data array
            public byte[] ToByteArray()
            {
                
byte[] aData;
                aData 
= new byte[Size];
                
//set the Size member
                SetUInt(aData, SizeOffset, Size);
                
return aData;
            }

            
public string Name
            {
                
get
                {
                    
return szExeFile.Substring(0, szExeFile.IndexOf('\0'));
                }
            }

            
public ulong PID
            {
                
get
                {
                    
return th32ProcessID;
                }
            }

            
public ulong BaseAddress
            {
                
get
                {
                    
return th32MemoryBase;
                }
            }

            
public ulong ThreadCount
            {
                
get
                {
                    
return cntThreads;
                }
            }
        }
        
#endregion

Wrapped Class

 

ContractedBlock.gif ExpandedBlockStart.gif Process class
#region Process class
    
/// <summary>
    
/// Summary description for Process.
    
/// </summary>
    public class Process
    {
        
private string processName;
        
private IntPtr handle;
        
private int threadCount;
        
private int baseAddress;

        
        
//default constructor
        public Process()
        {
            
        }

        
private Process(IntPtr id, string procname, int threadcount, int baseaddress)
        {    
            handle 
= id;
            processName 
= procname;
            threadCount 
= threadcount;
            baseAddress 
= baseaddress;
        }

        
//ToString implementation for ListBox binding
        public override string ToString()
        {
            
return processName;
        }

        
public int BaseAddress
        {
            
get
            {
                
return baseAddress;
            }
        }

        
public int ThreadCount
        {
            
get
            {
                
return threadCount;
            }
        }

        
public IntPtr Handle
        {
            
get
            {
                
return handle;
            }
        }

        
public string ProcessName
        {
            
get
            {
                
return processName;
            }
        }

        
public int BaseAddess
        {
            
get
            {
                
return baseAddress;
            }
        }


        
public void Kill()
        {
            IntPtr hProcess;
        
            hProcess 
= OpenProcess(PROCESS_TERMINATE, false, (int) handle);

            
if(hProcess != (IntPtr) INVALID_HANDLE_VALUE) 
            {
                
bool bRet;
                bRet 
= TerminateProcess(hProcess, 0);
                CloseHandle(hProcess);
            }
            

        }

        
public static Process[] GetProcesses()
        {
            ArrayList procList 
= new ArrayList();

            IntPtr handle 
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

            
if ((int)handle > 0)
            {
                
try
                {
                    PROCESSENTRY32 peCurrent;
                    PROCESSENTRY32 pe32 
= new PROCESSENTRY32();
                    
//Get byte array to pass to the API calls
                    byte[] peBytes = pe32.ToByteArray();
                    
//Get the first process
                    int retval = Process32First(handle, peBytes);

                    
while(retval == 1)
                    {
                        
//Convert bytes to the class
                        peCurrent = new PROCESSENTRY32(peBytes);
                        
//New instance
                        Process proc = new Process(new IntPtr((int)peCurrent.PID), peCurrent.Name, (int)peCurrent.ThreadCount, (int)peCurrent.BaseAddress);
            
                        procList.Add(proc);

                        retval 
= Process32Next(handle, peBytes);
                    }
                }
                
catch(Exception ex)
                {
                    
throw new Exception("Exception: " + ex.Message);
                }
                
                
//Close handle
                CloseToolhelp32Snapshot(handle); 
                
                
return (Process[])procList.ToArray(typeof(Process));

            }
            
else
            {
                
throw new Exception("Unable to create snapshot");
            }


        }

        
#endregion

 

Client

 

static   void  Main( string [] args)
        {
            
if  (args.Length  ==   0 )
            {
                Console.WriteLine(
" Please enter the process name. " );
                
return ;
            }
            
string  processName  =  args[ 0 ].ToUpper()  +   " .EXE " ;
            
            Process[] processes 
=  Process.GetProcesses();
            
foreach  (Process proc  in  processes)
            {
                
if  (proc.ProcessName.ToUpper()  ==  processName)
                {
                    proc.Kill();
                    Console.WriteLine(
" {0} was killed. " , processName);
                    
break ;
                }
            }
        }

这是一个简单的杀进程例子,要取出进程信息,读Process 的attribute就可以了,十分简单。

 

参考文献

Creating a Microsoft .NET Compact Framework-based Process Manager Application

上述代码来源于msnd,msnd的源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值