C++代码

pch.h

// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头
#include "framework.h"
#include "tchar.h"


// 调整访问权限 返回 0 成功 1 失败(动态库加载时会自动调用)
extern "C" __declspec(dllexport)
int __stdcall  Dog_AdjustPrivileges();

// 查询进程数据 返回值是进程总数 返回-1调用异常, 该接口与接口Dog_GetNextProcessInfo配合使用 
extern "C" __declspec(dllexport)
int __stdcall Dog_QueryProcess();

// 获取进程数据 在调用了Dog_QueryProcess后,获取进程详细数据, 返回 0 成功 1 失败 -1 调用异常
// Pid        进程ID(输出参数)
// lpPName    进程名称(输出参数)
// lpFullPath 进程程序物理全路径(输出参数)
// lpRes1     备用(输出参数)
// lpRes2     备用(输出参数)
extern "C" __declspec(dllexport)
int __stdcall  Dog_GetNextProcessInfo(DWORD &Pid, LPTSTR lpPName, LPTSTR lpFullPath, LPTSTR lpRes1, LPTSTR lpRes2);

#endif //PCH_H

dllmain.cpp

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
	{
		// 提升访问权限
		if (!Dog_AdjustPrivileges())
		{
			//提升权限失败
			int Error = -1;
		}
		
	}
		break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

pch.cpp

// pch.cpp: 与预编译标头对应的源文件

#include "pch.h"

// 当使用预编译的头时,需要使用此源文件,编译才能成功。
#include <Psapi.h>
#pragma comment (lib,"Psapi.lib")
#include <TlHelp32.h>

//#include <afxtempl.h>
// 进程数据
struct PROCESS_ITME
{
	PROCESS_ITME()
	{
		IsValid   = 0;
		SortIndex = -1;
		ProcessID = 0;
		memset(ProcessName, 0, 260);
		memset(ProcessFullPath, 0, 756);
	}

	void INIT()
	{
		IsValid   = 0;
		SortIndex =-1;
		ProcessID = 0;
		memset(ProcessName, 0, 260);
		memset(ProcessFullPath, 0, 756);
	}
	unsigned char IsValid;
	short SortIndex;
	DWORD ProcessID;
	TCHAR ProcessName[260];
	TCHAR ProcessFullPath[756];
};

#define MAX_PROCEES 1024
struct PROCESS_INFO
{
	PROCESS_INFO()
	{
		ProcessNum = 0;
	}
	short         ProcessNum; //数量
	PROCESS_ITME  ProcessData[MAX_PROCEES];
};
PROCESS_INFO  ProcessInfo;

//提升访问权限
BOOL AdjustPrivileges()
{
	HANDLE hToken = NULL;
	TOKEN_PRIVILEGES tp = { 0 };
	TOKEN_PRIVILEGES oldtp = { 0 };
	DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
	LUID luid = { 0 };

	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
		if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
			return TRUE;
		else
			return FALSE;
	}
	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
		CloseHandle(hToken);
		return FALSE;
	}

	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
		CloseHandle(hToken);
		return FALSE;
	}

	CloseHandle(hToken);
	return TRUE;
}

BOOL GetProcessList()
{
	try
	{
		ProcessInfo.ProcessNum = 0;
		int nCount = 0;

		BOOL bResult = FALSE;
		HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hSnap == INVALID_HANDLE_VALUE)
			return FALSE;

		HANDLE hProcess = NULL;
		PROCESSENTRY32 info = { 0 };
		info.dwSize = sizeof(PROCESSENTRY32);

		TCHAR processBaseName[512] = _T("");
		DWORD nameBufferSize = 510;

		BOOL bRet = Process32First(hSnap, &info);
		while (bRet) 
		{
			memset(processBaseName, 0, 512);
			nameBufferSize = 510;
			hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info.th32ProcessID);
			if (hProcess)
			{
				GetModuleFileNameEx(hProcess, NULL, processBaseName , nameBufferSize );
			}
			else
			{
				hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, info.th32ProcessID);
				if (hProcess)
				{
					QueryFullProcessImageName(hProcess, NULL, processBaseName, &nameBufferSize);
				}
				else
				{

				}
			}
			CloseHandle(hProcess);

			// 赋值数据
			ProcessInfo.ProcessData[nCount].INIT();
			ProcessInfo.ProcessData[nCount].IsValid   = 1;
			//ProcessInfo.ProcessData[nCount].SortIndex = info.th32ProcessID;
			ProcessInfo.ProcessData[nCount].ProcessID = info.th32ProcessID;
			_stprintf(ProcessInfo.ProcessData[nCount].ProcessName , _T("%s"), info.szExeFile);
			_stprintf(ProcessInfo.ProcessData[nCount].ProcessFullPath , _T("%s"), processBaseName);
			nCount++;

			bRet = Process32Next(hSnap, &info);
		}

		CloseHandle(hSnap);
		ProcessInfo.ProcessNum = nCount;

		return TRUE;
	}
	catch (...)
	{
		
	}
	return FALSE;
}


// 查询进程数据 返回进程数量
extern "C" __declspec(dllexport)
int __stdcall Dog_QueryProcess()
{
	try
	{
		if (GetProcessList())
		{
			return ProcessInfo.ProcessNum;
		}
	}
	catch (...)
	{
		return -1;
	}
	return 0;
}

// 获取进程数据 在调用了QueryProcess后,获取进程详细数据
extern "C" __declspec(dllexport) 
int __stdcall  Dog_GetNextProcessInfo(DWORD &Pid, LPTSTR lpPName, LPTSTR lpFullPath , LPTSTR lpRes1, LPTSTR lpRes2 )
{
	try
	{
		if ( ProcessInfo.ProcessNum > 0)
		{
			int nCount = ProcessInfo.ProcessNum;

			int tSort = -1;
			int minIndex = -1;
			int isHaved = 0;
			for (int i = 0; i < nCount; i++)
			{
				if (ProcessInfo.ProcessData[i].IsValid == 1)
				{
					if (tSort == -1)
					{
						tSort = ProcessInfo.ProcessData[i].ProcessID;
						minIndex = i;
					}
					else
					{
						if (ProcessInfo.ProcessData[i].ProcessID <= tSort)
						{
							tSort = ProcessInfo.ProcessData[i].ProcessID;
							minIndex = i;
						}
					}
					isHaved = 1; 
				}
			}

			if (isHaved && minIndex >= 0 )
			{
				Pid = ProcessInfo.ProcessData[minIndex].ProcessID;
				if (lpPName != NULL)
				{
					_stprintf(lpPName, _T("%s"), ProcessInfo.ProcessData[minIndex].ProcessName);
				}
				if (lpFullPath != NULL)
				{
					_stprintf(lpFullPath, _T("%s"), ProcessInfo.ProcessData[minIndex].ProcessFullPath);
				}
				
				ProcessInfo.ProcessData[minIndex].INIT();

				return 1;
			}
			else
				ProcessInfo.ProcessNum = 0;

		}
	}
	catch (...)
	{
		return -1;
	}
	return 0;
}

// 调整访问权限
extern "C" __declspec(dllexport)
int __stdcall  Dog_AdjustPrivileges( )
{
	if (AdjustPrivileges())
		return 1;
	return 0;
}

C#调用代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WinDog_dll_test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("WinDog.dll", EntryPoint = "Dog_QueryProcess", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        private static extern int Dog_QueryProcess();

        [DllImport("WinDog.dll", EntryPoint = "Dog_GetNextProcessInfo", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        private static extern int Dog_GetNextProcessInfo_byte(ref int Pid, ref  byte lpPName, ref byte lpFullPath, ref byte lpRes1, ref byte lpRes2);

        [DllImport("WinDog.dll", EntryPoint = "Dog_GetNextProcessInfo", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        private static extern int Dog_GetNextProcessInfo_StringBuilder(ref int Pid, StringBuilder lpPName, StringBuilder lpFullPath, StringBuilder lpRes1, StringBuilder lpRes2);

        /// <summary>
        /// 获取进程详细信息(byte)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {

            int nProcessNum = Dog_QueryProcess();

            int pid = 0;
            StringBuilder pName = new StringBuilder(1024);
            StringBuilder fullPath = new StringBuilder(1024);
            StringBuilder res1 = new StringBuilder(1024);
            StringBuilder res2 = new StringBuilder(1024);

            while (Dog_GetNextProcessInfo_StringBuilder(ref pid, pName, fullPath, res1, res2) > 0)
            {
                Console.WriteLine(string.Format("pid:{0}, pName:{1}, fullPath:{2}", pid, pName, fullPath));
            }

        }

        /// <summary>
        /// 获取进程详细信息(StringBuilder)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            int nProcessNum = Dog_QueryProcess();

            int pid = 0;
            byte[] sName = new byte[1024];
            byte[] sFullPath = new byte[1024];
            byte[] sRes1 = new byte[1024];
            byte[] sRes2 = new byte[1024];

            while (Dog_GetNextProcessInfo_byte(ref pid, ref sName[0], ref sFullPath[0], ref sRes1[0], ref sRes2[0]) > 0)
            {
                string NameString = ByteToString(sName, 1024);
                string FullPathString = ByteToString(sFullPath, 1024);
                Console.WriteLine(string.Format("pid:{0}, pName:{1}, fullPath:{2}", pid, NameString, FullPathString, sRes1, sRes2));
            }
        }

        public String ByteToString(byte[] bytes, int Lenth)
        {
            string temp = System.Text.Encoding.Unicode.GetString(bytes).ToString();
            int i = 0;
            for (i = 0; i < Lenth; i++)
            {
                if (temp[i] == '\0')
                {
                    break;
                }
            }
            return temp.Substring(0, i);
        }

    }
}

效果

C++获取任务管理器信息,封装成DLL,C#调用例子_System