文章标题

终止进程/窗口的几种方式

  1. TerminateProcess()
    函数功能: 终止指定进程及其所有线程。
    (由于会关闭整个进程,所以不是特别推荐使用)
函数原型:
BOOL TerminateProcess(
    HANDLE hProcess,    //需要终止的进程句柄
    UINT uExitCode     //进程终止码
);

参数:

    hProcess
    [in] 指定要中断进程的句柄. 该句柄可以由 OpenProcess()得到.
    DWORD uExitCode
    [in] 进程和其所有线程的退出代码

返回值:
    返回非零值代表成功。0代表失败。想要得到更多错误信息,请调用GetLastError()

OpenProcess();

函数功能: 用来打开一个已存在的进程对象,并返回进程的句柄。
OpenProcess函数执行成功将根据传入参数的PID返回该PID进程的句柄.执行失败返回0.执行失败的错误信息请使用GetLastError 函数.

PID: ProcessID

函数原型:


HANDLE OpenProcess(
    DWORD dwDesiredAccess,    //渴望得到的访问权限(标志)
    BOOL bInheritHandle,      // 是否继承句柄
    DWORD dwProcessId         // 进程标示符
);

参数说明(通常使用PROCESS_ALL_ACCESS即可):

dwDesiredAccess:
// 指定打开后,该进程的访问权限

PROCESS_ALL_ACCESS
//给予进程所有可能允许的权限.

PROCESS_DUP_HANDLE
//允许使用DuplicateHandle函数进行进程句柄的复制操作.

PROCESS_QUERY_INFORMATION
//允许函数GetExitCodeProcess 或函数GetPriorityClass functions查询进程的信息时使用该句柄.

PROCESS_SET_INFORMATION//允许函数SetPriorityClass使用此句柄进行优先级设置.

PROCESS_TERMINATE//允许函数TerminateProcess 使用此句柄关闭进程.

PROCESS_VM_OPERATION //允许函数VirtualProtectEx使用此句柄修改进程的虚拟内存.

PROCESS_VM_READ or PROCESS_VM_WRITE //允许函数访问和写入权限

SYNCHRONIZE Windows NT //专用: 允许同步函数使用此句柄.

bInheritHandle: //指定返回的句柄是继承dwProcessId指定的进程..

dwProcessId://指定打开需要打开的进程的PID.

特别注明:对于自己创造的进程可以使用已有的句柄,对于该程序中未出现的句柄,可以使用进程快照来获得句柄

进程快照函数:

  • CreateToolhelp32Snapshot()
  • Process32First()
  • Process32Next()
  • CloseHandle()//在此仅仅是提醒不要忘记关闭已用的句柄

列表内容
1. CreateToolhelp32Snapshot()
函数功能:
函数通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照.说到底,可以获取系统中正在运行的进程信息,线程信息,等

HANDLE WINAPI CreateToolhelp32Snapshot(
    DWORD dwFlags,
    //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
    DWORD th32ProcessID
    //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0
);

dwFlags
指定快照中包含的系统内容,这个参数能够使用下列数值(常量)中的一个或多个。
TH32CS_INHERIT - 声明快照句柄是可继承的。
TH32CS_SNAPALL - 在快照中包含系统中所有的进程和线程。
TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的进程的所有的堆。
TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的进程的所有的模块。
TH32CS_SNAPPROCESS - 在快照中包含系统中所有的进程。
TH32CS_SNAPTHREAD - 在快照中包含系统中所有的线程。
Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
th32ProcessID
指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST或者TH32CS_SNAPMODULE后才有效,在其他情况下该参数被忽略,所有的进程都会被快照。
返回值:
调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE 。
备注:
使用GetLastError函数查找该函数产生的错误状态码。
注意,在Win NT中,要删除快照,使用CloseHandle函数;在Win CE中,要删除快照,使用CloseToolhelp32Snapshot函数。

Process32First()
函数功能:
一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,我们可以利用process32First函数来获得第一个进程的句柄

BOOL WINAPI Process32First(
    HANDLE hSnapshot,//_in
    LPPROCESSENTRY32 lppe//_out
);
//其中PROCESSENTRY32结构为:
//PROCESSENTRY32 结构如下:

typedef struct tagPROCESSENTRY32 {
    DWORD dwSize; // 结构大小;
    DWORD cntUsage; // 此进程的引用计数;
    DWORD th32ProcessID; // 进程ID;
    DWORD th32DefaultHeapID; // 进程默认堆ID;
    DWORD th32ModuleID; // 进程模块ID;
    DWORD cntThreads; // 此进程开启的线程计数;
    DWORD th32ParentProcessID;// 父进程ID;
    LONG pcPriClassBase; // 线程优先权;
    DWORD dwFlags; // 保留;
    char szExeFile[MAX_PATH]; // 进程全名;
} PROCESSENTRY32;

Process32Next()
函数功能:
获得下一个进程的句柄

BOOLWINAPIProcess32Next(
__inHANDLEhSnapshot,
__outLPPROCESSENTRY32lppe
);

CloseHandle()
函数功能:关闭CreateToolhelp32Snapshot()产生的句柄

BOOL CloseHandle(
HANDLE hObject
);

详细功能:
关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。
若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。

关于内核对象,请查看《windows核心编程中》(《windows via c/c++》)相应章节

具体实例代码

DWORD ID;
DWORD ProcessID = GetCurrentProcessId();

//必要的置位
PROCESSENTRY32 pe;
memset(&pe, 0x00, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);

//取全局函数,对于MFC而言,加了是调用WIN API,不加是调用MFC的库
HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
BOOL result = Process32First(hSnapshot, &pe);
while (result)
{
    ID = pe.th32ProcessID;
    if (ID == ProcessID)
    {
        result = Process32Next(hSnapshot, &pe);
        continue;
    }
    //字符串比较,检查记事本程序(notepad.exe)
    if (_tcsicmp(pe.szExeFile, _T("notepad.exe")) == 0)
    {
        MessageBox((NULL), TEXT("找到该进程"), TEXT("tips"), MB_OK);
        //打开已存在的进程
        HANDLE  Process = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE, pe.th32ProcessID);        
        ::TerminateProcess(Process, 0);
        MessageBox(NULL, TEXT("已杀死该进程"), TEXT("Tips"), MB_OK);
        CloseHandle(Process);
    }
  1. SendMessage()
  2. PostMessage()

总结:
SendMessage()函数与PostMessage()函数功能类似,都是给窗口发消息,来实现窗口或线程的关闭,难点在与如何抓到窗口,这里介绍个函数FindWindows()

FindWindows()
函数功能:
如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
如果函数执行失败,则返回值为 NULL 。可以通过调用GetLastError函数获得更加详细的错误信息。

HWND FindWindow(
    LPCSTR lpClassName,
    LPCSTR lpWindowName
);

lpClassName
指向一个以null结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。
如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。
lpWindowName
指向一个以null结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。

此处的重难点是不知道窗口的类名

解决方案:VS2013在内部整合了一个工具叫做SPY++,用其可以轻易地监测窗口的类名(在所有电脑上窗口类名一致)

具体代码实例

HWND myHwnd = FindWindow(NULL,TEXT("pujifanqiang.txt - 记事本"));
if (!myHwnd)
{
    if (!GetProcessId(NULL))
        ErrorExit(TEXT("GetProcessId"));
}
PostMessage(myHwnd, WM_CLOSE, 0, 0);
CloseHandle(myHwnd);

但是SendMessage()函数与PostMessage()函数的功能并不仅限制于给窗口发送WM_CLOSE消息,好好使用,必有大用

最后介绍下GetLastError()
函数功能:GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置。函数并无必要设置上一次错误信息,所以即使一次GetLastError调用返回的是零值,也不能担保函数已成功执行。只有在函数调用返回一个错误结果时,这个函数指出的错误结果才是有效的。通常,只有在函数返回一个错误结果,而且已知函数会设置GetLastError变量的前提下,才应访问GetLastError;这时能保证获得有效的结果。SetLastError函数主要在对api函数进行模拟的dll函数中使用,所以对vb应用程序来说是没有意义的

DWORD GetLastError(VOID);

可以讲GetLastError()函数整合到MessageBox(),以下代码借鉴于网上其他人答案
具体代码实例

if (!GetProcessId(NULL))
    ErrorExit(TEXT("GetProcessId"));
void ErrorExit(LPTSTR lpszFunction)
{
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL);

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
        //需要头文件<strsafe.h>,该头文件必须在windows.h之后包括
        StringCchPrintf((LPTSTR)lpDisplayBuf,
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw);
}
本项目采用C++编程语言结合ROS框架构建了完整的双机械臂控制系统,实现了Gazebo仿真环境下的协同运动模拟,并完成了两台实体UR10工业机器人的联动控制。该毕业设计在答辩环节获得98分的优异成绩,所有程序代码均通过系统性调试验证,保证可直接部署运行。 系统架构包含三个核心模块:基于ROS通信架构的双臂协调控制器、Gazebo物理引擎下的动力学仿真环境、以及真实UR10机器人的硬件接口层。在仿真验证阶段,开发了双臂碰撞检测算法和轨迹规划模块,通过ROS控制包实现了末端执行器的同步轨迹跟踪。硬件集成方面,建立了基于TCP/IP协议的实时通信链路,解决了双机数据同步和运动指令分发等关键技术问题。 本资源适用于自动化、机械电子、人工智能等专业方向的课程实践,可作为高年级课程设计、毕业课题的重要参考案例。系统采用模块化设计理念,控制核心与硬件接口分离架构便于功能扩展,具备工程实践能力的学习者可在现有框架基础上进行二次开发,例如集成视觉感知模块或优化运动规划算法。 项目文档详细记录了环境配置流程、参数调试方法和实验验证数据,特别说明了双机协同作业时的时序同步解决方案。所有功能模块均提供完整的API接口说明,便于使用者快速理解系统架构并进行定制化修改。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值