在.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 的使用),还是有很多需要学习和改进的地方,欢迎指教。

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

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的源代码

转载于:https://www.cnblogs.com/procoder/archive/2009/01/13/Windows-Mobile-Compact-Framework-Process.html

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

  1. 在Windows Mobile和Wince(Windows Embedded CE)下进行Native C++开发,如何取出当前执行文件的路径和调用模块的路径...

    在Windows Mobile和Wince(Windows Embedded CE)下进行Native C++开发,有时候需要取出当前执行文件的路径,或者调用模块的路径信息,例如在相对路径下存放了配置 ...

  2. Windows Mobile和Wince(Windows Embedded CE)的字符集问题

    背景 开发过Windows Mobile和Wince(Windows Embedded CE)的开发者,特别是Native C++开发者,或多或少都遇到过ANSI字符集和Unicode字符集的转换问题 ...

  3. 开发Windows Mobile和Wince(Windows Embedded CE)的部署项目(Deploy Project)时,如何修改注册表...

    由于fele问我一个问题:在进行Windows Mobile部署项目的开发,也就是打安装包,如何修改注册表?我把自己的经验blog下来. 1.打开Deploy项目的注册表编辑器,如下图 2.根据需求修 ...

  4. 在Windows Mobile和Wince(Windows Embedded CE)下进行WTL开发,如何加入超链接(HyperLink)

    本文讲述在Windows Mobile和Wince(Windows Embedded CE)下进行WTL开发,如何加入超链接(HyperLink)的支持. 步骤如下: 1.#include <a ...

  5. 一文讲清楚Windows Mobile和Wince(Windows Embedded CE)的字符集问题

    背景 开发过Windows Mobile和Wince(Windows Embedded CE)的开发者,特别是Native C++开发者,或多或少都遇到过ANSI字符集和Unicode字符集的转换问题 ...

  6. Windows Mobile和Wince(Windows Embedded CE )下使用.NET Compact Framework下注册表导出工具的开发...

    简介 本文讲述了.NET Compact Framework下的注册表开发的基本概念,介绍在Windows Mobile和Wince下操作注册表的工具,同时使用C#实现了一个注册表导出工具. 背景 W ...

  7. Windows Mobile和Wince下使用TinyXML进行Native C++的开发

    背景 继续讲述Mobile Radio项目的开发,上回讲到如何把自于 www.1radio.com.au 网站的电台数据从JSON转换成XML.这回讲述使用tinyXML在windows mobile ...

  8. Mircosoft 正式把Windows Mobile改名为Windows Phone,你会因此而购买Windows Phone吗?

    简介 本文讲述Windows Phone改名事件,以及Windows Phone发展历史和今后发展策略的想法. 事件 今天下班的时候看报纸,有一段新闻关于昨天(2009年10月6日)Mircosoft ...

  9. Windows Mobile】认识Windows Mobile

    Windows Mobile 开发简介: Windows Mobile 开发基于 .NET Compact Framework,简称 .NET CF: 1. .NET CF 开发有别于 .NET Fr ...

最新文章

  1. 【Python】数据提取xpath和lxml模块(豆瓣电影排行榜的爬虫)
  2. 中国顶级互联网公司的技术组织架构调整预示着什么?【强烈推荐行业人士阅读】
  3. 使用自定义卫语句写出更简洁的代码
  4. java界面化二叉排序树_层次序创建二叉树(图形界面和控制台输入实现)
  5. git版本库的创建和yaf框架环境的部署
  6. 卸载mysql数据库命令,值得推荐!
  7. Atitit mysql 存储kv 以及php js接口目录kv_mysql.js 1Set.php 1Get.php 2CREATE TABLE `cfg` ( `k`
  8. java的addattribute_Java AttributeSet.addAttributeListener方法代码示例
  9. 微信小程序开发的基本流程
  10. 咪咕音乐客户端免费版
  11. 【C语言练习——打印空心下三角及其变形】
  12. 基于线程池实现多线程任务
  13. 世界上第一台电子计算机的研制目的,最初研制电子计算机的目的
  14. 计算机一级标题底纹,2017年计算机一级考试MSOffice考点解析:幻灯片背景的设置...
  15. CG CTF RE Py交易
  16. 如何带好一支团队,持续更新
  17. 数学笔记11——微分和不定积分
  18. 参加口碑最好的广州传智播客Java就业培训班吧
  19. Latex数学公式方程格式总结
  20. [OHIF-Viewers]医疗数字阅片-医学影像-cornerstone-core-Cornerstone.js提供了一个完整的基于Web的医学成像平台。...

热门文章

  1. 增强.net开发的5个非常有用的Visual Studio 2012扩展
  2. AJAX+JQUERRY实现分页
  3. python是高级动态编程语言-python是一种跨平台、开源、免费的高级动态编程语言,对么...
  4. 关于python语言、下列说法不正确的是-下列语句中,___________是不正确的Python语句...
  5. 在python中、下列代码的输出是什么-关于下列python多线程代码输出效果的疑问?...
  6. python好用-Python有哪些常见的、好用的爬虫框架?
  7. python网页爬虫-python网页爬虫浅析
  8. 关于python的一些好的书籍推荐-推荐几本关于的Python好书
  9. python装饰器实例-Python装饰器实用例子
  10. python学成需要多久-小白学python怎么快速入门?多久能完成一个项目?