C++调用windows系统接口

前言

整理常用的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.net/qq_24127015/article/details/83342641
https://www.cnblogs.com/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.net/gather_2c/NtTaEg1sNDktYmxvZwO0O0OO0O0O.html

3. 获取句柄

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

FindWindow(LPCSTR lpClassName ,LPCSTR lpWindowName) 

利用句柄操作窗口: https://blog.csdn.net/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.net/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.net/howard_liu1314/article/details/7993552
网址参考:https://bbs.csdn.net/topics/40280544

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

4. 进程相关操作

线程

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

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

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

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

创建
CreateProcess ()
https://www.cnblogs.com/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.net/tifentan/article/details/79317089
https://www.cnblogs.com/MaxWoods/p/4132297.html

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

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在 C++调用 Windows 系统的定时任务,可以使用 Windows API 中的相关函数。以下是一个示例代码: ```cpp #include <iostream> #include <windows.h> int main() { // 创建一个定时任务 const wchar_t* taskName = L"MyTask"; const wchar_t* taskPath = L"C:\\path\\to\\my\\task.exe"; const wchar_t* taskArgs = L"arg1 arg2"; ITaskService* pService = NULL; CoInitialize(NULL); CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService); pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); ITaskFolder* pRootFolder = NULL; pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); ITaskDefinition* pTask = NULL; pService->NewTask(0, &pTask); pTask->put_Name(_bstr_t(taskName)); ITriggerCollection* pTriggerCollection = NULL; pTask->get_Triggers(&pTriggerCollection); ITrigger* pTrigger = NULL; pTriggerCollection->Create(TASK_TRIGGER_TIME, &pTrigger); ITimeTrigger* pTimeTrigger = NULL; pTrigger->QueryInterface(IID_ITimeTrigger, (void**)&pTimeTrigger); SYSTEMTIME st; GetLocalTime(&st); st.wHour = 12; // 设置定时任务的触发时间 st.wMinute = 0; VARIANT vtStartTime; VariantInit(&vtStartTime); vtStartTime.vt = VT_DATE; SystemTimeToVariantTime(&st, &(vtStartTime.date)); pTimeTrigger->put_StartBoundary(vtStartTime); pTrigger->put_Enabled(VARIANT_TRUE); pTriggerCollection->Add(pTrigger); pTrigger->Release(); IActionCollection* pActionCollection = NULL; pTask->get_Actions(&pActionCollection); IAction* pAction = NULL; pActionCollection->Create(TASK_ACTION_EXEC, &pAction); IExecAction* pExecAction = NULL; pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction); pExecAction->put_Path(_bstr_t(taskPath)); pExecAction->put_Arguments(_bstr_t(taskArgs)); pActionCollection->Add(pAction); pAction->Release(); IRegisteredTask* pRegisteredTask = NULL; pRootFolder->RegisterTaskDefinition( _bstr_t(taskName), pTask, TASK_CREATE_OR_UPDATE, _variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &pRegisteredTask ); std::cout << "定时任务已创建" << std::endl; // 释放资源 pRegisteredTask->Release(); pTask->Release(); pRootFolder->Release(); pService->Release(); CoUninitialize(); return 0; } ``` 这段代码使用了 `ITaskService` 接口和其他相关接口来创建和注册一个定时任务。你需要将 `taskPath` 设置为你要定时执行的程序的路径,`taskArgs` 设置为程序的参数,`st.wHour` 和 `st.wMinute` 设置为触发时间。编译运行代码后,就会创建一个名为 `MyTask` 的定时任务,每天的 12:00 执行。 请注意,这段代码使用了 COM 接口,需要在代码中调用 `CoInitialize` 和 `CoUninitialize` 来初始化和释放 COM 组件。另外,还需要链接 `taskschd.lib` 库文件。 希望这可以帮助到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道阻且长,行则降至

无聊,打赏求刺激而已

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值