admin 管理员组

文章数量: 887007

前言

整理常用的windows系统下API接口。

头文件声明
#include <Windows.h>
#include <tlhelp32.h>
#include <ShellAPI.h>

1. ShellExecute
  ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。
  有几个API函数都可以实现这些功能,但是在大多数情况下ShellExecute是更多的被使用的,同时它并不是太复杂。
  ShellExecute函数原型及参数含义如下:
  
ShellExecute(
  HWND hwnd, //父窗口句柄 (如:NULL,Handle等)
  LPCSTR lpOperation, //操作类型 (如:“open”)*要加英文双引号
  LPCSTR lpFile, //要进行操作的文件或路径
  LPCSTR lpParameters, //当lpOperation为“explore”时指定要传递的参数,通常设为NULL
  LPCSTR lpDirectory, //指定默认目录,通常设为NULL
  INT nShowCmd //文件打开的方式,以通常方式还是最大化或最小化显示,一般为SW_SHOWNORMAL
  )
参数说明:

●hWnd:用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句柄,即Application.Handle,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。
  ●Operation:用于指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参数设为nil时,表示执行默认操作“open”。
  ●FileName:用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。
  ●Parameters:若FileName参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为nil或PChar(0)。
  ●Directory:用于指定默认目录。
  ●ShowCmd:若FileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。
  若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。
  上述仅仅是ShellExecute函数的标准用法,下面将介绍它的特殊用法。
例子如下:
  //调用记事本
  ShellExecute(NULL,“open”,“NOTEPAD.EXE”,NULL,NULL,SW_SHOWNORMAL);

网址:
https://blog.csdn/qq_24127015/article/details/83342641
https://wwwblogs/tianqiang/p/9971225.html

2. WinExec()
第二个参数是控制程序主窗口的显示方式
第二个参数可能的取值为 :
SW_HIDE //程序启动后隐藏主窗口
SW_MAXIMIZE //最大化运行
SW_MINIMIZE //最小化运行
SW_RESTORE //将最大化或最小化的窗口恢复正常
SW_SHOW //以当前位置和大小显示主窗口
SW_SHOWMAXIMIZED //激活窗口并以最大化运行
SW_SHOWMINIMIZED //激活窗口并以最小化运行
SW_SHOWMINNOACTIVE //最小化运行,但不激活
SW_SHOWNOACTIVATE //以上一次的窗口大小运行,但不激活
SW_SHOWNORMAL //普通方式,一般运行时采用这个
一般情况下,第二个参数取SW_SHOWNORMAL即可,这样就是无参数运行one.exe
WinExec(“one.exe”, SW_SHOWNORMAL);第二个参数只是WinExec函数的参数,不是one.exe的参数。
网址:
https://www.csdn/gather_2c/NtTaEg1sNDktYmxvZwO0O0OO0O0O.html

3. 获取句柄

1.1 FindWindow()
事例:通过窗口类名,窗口名称获取窗口句柄。

FindWindow(LPCSTR lpClassName ,LPCSTR lpWindowName) 

利用句柄操作窗口: https://blog.csdn/weiwei_baby/article/details/69942648

1.2 通过进程名

HANDLE GetProcessHandle(LPCWSTR lpName)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot) 
	{
		return NULL;
	}
	PROCESSENTRY32 pe = { sizeof(pe) };
	BOOL fOk;
	for (fOk = Process32First(hSnapshot, &pe); fOk; fOk = Process32Next(hSnapshot, &pe)) 
	{
		if (!_tcscmp(pe.szExeFile, lpName)) 
		{
			CloseHandle(hSnapshot);
			return GetProcessHandle(pe.th32ProcessID);
		}
	}
	return NULL;
}

bool CbCommonLineEdit::_win32FindHandle(const QString &proName)
{
    HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32* processInfo = new PROCESSENTRY32;
    processInfo->dwSize = sizeof(PROCESSENTRY32);
    int index = 0;
    while(Process32Next(hSnapShot, processInfo) != FALSE) {
        index++;
        int size = WideCharToMultiByte(CP_ACP, 0, processInfo->szExeFile, -1, NULL, 0, NULL, NULL);
        char *ch = new char[size+1];
        if(WideCharToMultiByte(CP_ACP, 0, processInfo->szExeFile, -1, ch, size, NULL, NULL)){
            if(strstr(ch, proName.toUtf8())) {//进程还在
                delete[] ch;
                CloseHandle(hSnapShot);
                delete processInfo;
                return true;
            }
        }
        delete[] ch;
    }
    CloseHandle(hSnapShot);
    delete processInfo;
    return false;
}

1.3 通过进程ID
//通过进程ID获取进程句柄

HANDLE GetProcessHandle(int nID)
{
	return OpenProcess(PROCESS_TERMINATE, FALSE, nID);
}

网址:https://blog.csdn/fzuim/article/details/60954959

程序名获取PID

DWORD GetProcessIDByName(const char* pName)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot) {
		return NULL;
	}
	PROCESSENTRY32 pe = { sizeof(pe) };
	for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) {
		if (strcmp(pe.szExeFile, pName) == 0) {
			CloseHandle(hSnapshot);
			return pe.th32ProcessID;
		}
		//printf("%-6d %s\n", pe.th32ProcessID, pe.szExeFile);
	}
	CloseHandle(hSnapshot);
	return 0;
}

注意: 关闭进程时或者其他一定要释放句柄资源。 同时HANDLE 与 HWND不一样,HANDLE (句柄)包含 HWND (窗口句柄)。
HWND也是一种HANDLE, 不过它只是用来代表一个窗口。
HANDLE这个类型不代表一个窗口,但是他可以代表其他的一些资源。
比如,进程句柄,文件句柄,还有一些用于进程/线程同步用的对象,
还有其他的。一句话,HWND只用来代表一个窗口,是访问窗口用的Handle.
https://blog.csdn/howard_liu1314/article/details/7993552
网址参考:https://bbs.csdn/topics/40280544

查找句柄方法网址:
https://wwwblogs/zjutlitao/p/3889900.html
https://blog.csdn/vevenlcf/article/details/80206457

4. 进程相关操作

线程

关闭:
ExitThread(); TerminateThread();
创建:
CreateThread();

网址:
https://blog.csdn/anye3000/article/details/7470674

进程
https://blog.csdn/jfkidear/article/details/27057861
https://blog.csdn/weixin_34148456/article/details/85919682

关闭
TerminateProcess() (第二个参数为退出码0,1,4)
ExitProcess()

创建
CreateProcess ()
https://wwwblogs/fancing/p/6477918.html

5. 关闭窗口句柄
这个主要是针对于当时关闭系统的osk.exej键盘, 之前是因为想着关掉其句柄,就行了。但是,这样是不妥的,句柄拥有很多资源,当我们试着通过TerminateProcess()去终止时,那种做法时不值得提倡的,因为其句柄中拥有的资源可能被其他窗口在使用,或者其被保护。当我们试着去关闭其句柄(进程)资源是行不通的,网上说通过提升进程权限其实也是不行,然后在MSDN上询问了相关问题,如图是他给出思路:

只不过他这种说法我尝试了也不行,但是思路可以借鉴,最终代码如下。

//找到osk的窗口句柄,并发送关闭信息
    HWND  hwnd = FindWindow(L"OSKMainClass", 0);
    if (hwnd)
    {
        SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
    }

提升进程权限:
https://blog.csdn/tifentan/article/details/79317089
https://wwwblogs/MaxWoods/p/4132297.html

https://blog.csdn/bcbobo21cn/article/details/52217745 win32 API总结

本文标签: 接口 系统 Windows