C/C++ Windows API——执行进程
2023-09-11 14:22:54 时间
// ProcessDemo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#pragma comment(lib, "urlmon.lib")//URLDownloadToFile
int main()
{
BOOL ret;
/*
简单地执行程序
__drv_preferredFunction("CreateProcess","Deprecated. See MSDN for details")
WINBASEAPI UINT WINAPI WinExec(
_In_ LPCTSTR lpCmdLine, //指向一个可执行的文件
_In_ UINT uCmdShow //窗口的初始显示方式,如果是SW_HIDE就不会显示直接在后台运行
);
uCmdShow可以是如下参数
#define SW_HIDE 0
#define SW_SHOWNORMAL 1 与SW_RESTORE相同
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4 用最近的大小和位置显示一个窗口,同时不改变活动窗口
#define SW_SHOW 5 用当前的大小和位置显示一个窗口,同时令其进入活动状态
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8 用当前的大小和位置显示一个窗口,不改变活动窗口
#define SW_RESTORE 9 用原来的大小和位置显示一个窗口,同时令其进入活动状态
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11
若函数调用成功,则返回值大于31。若函数调用失败,则常见的返回值为下列之一:
等于 0 {内存不足. 系统内存或资源已耗尽}
ERROR_FILE_NOT_FOUND = 2; {文件名错误}
ERROR_PATH_NOT_FOUND = 3; {路径名错误}
ERROR_BAD_FORMAT = 11; {EXE 文件无效(非Win32.EXE或.EXE影像错误)}
*/
LPCSTR lpCmdLine = "notepad.exe";
UINT uCmdShow = SW_SHOW;
UINT winExecRet = WinExec(lpCmdLine, uCmdShow);
if (winExecRet > 31) {
printf("WinExec -> succ, ret=%d\n", winExecRet);
}
else {
printf("WinExec -> fail(%d), ret=%ld\n", GetLastError(), winExecRet);
}
/*
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
STDAPI URLDownloadToFileW(
_In_opt_ LPUNKNOWN pCaller, //控件的接口,如果不是控件则为0.
_In_ LPCTSTR szURL, //要下载的url地址,不能为空.
_In_opt_ LPCTSTR szFileName, //下载后保存的文件名.
DWORD dwReserved, //保留字段,必需为0
_In_opt_ LPBINDSTATUSCALLBACK lpfnCB //下载进度状态回调
);
//小心!URLDownloadToFile不支持gzip压缩,如果网站使用了gzip压缩,你会很惨的。
return
#define S_OK ((HRESULT)0L)
#define S_FALSE ((HRESULT)1L)
*/
LPUNKNOWN pCaller = NULL;
LPCTSTR szURL = _T("http://www.baidu.com");
LPCTSTR szFileName = _T("C:\\Users\\chenjia2014\\Desktop\\process_demo.html");
DWORD dwReserved = 0;
LPBINDSTATUSCALLBACK lpfnCB = NULL;
/*
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol _URLDownloadToFileW@20 referenced in function _main ProcessDemo C : \Users\chenjia2014\Desktop\temp\vc\ProcessDemo\ProcessDemo\ProcessDemo.obj 1
2019错误是找到头文件但没有找到实现的lib文件
*/
HRESULT hResult = URLDownloadToFile(pCaller, szURL, szFileName, dwReserved, lpfnCB);
if (hResult == S_OK) {
printf("URLDownloadToFile -> %d -> S_OK\n", hResult);
}
else {
printf("URLDownloadToFile -> %d -> not S_OK\n", hResult);
}
//这两种判断方式都是一样的
if (SUCCEEDED(hResult)) {
printf("URLDownloadToFile -> %d -> SUCCEEDED\n");
}
else if (FAILED(hResult)) {
printf("URLDownloadToFile -> %d -> FAILED\n");
}
else {
printf("URLDownloadToFile -> %d -> UNKNOWN\n");
}
/*
WINBASEAPI BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName, //注意:这里的文件名一定要是路径全程,光用path中定义目录下的程序名是找不到的
_Inout_opt_ LPTSTR lpCommandLine, //指的是传递给程序的参数
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。如果lpThreadAttributes参数为空(NULL),那么句柄不能被继承。
_In_ BOOL bInheritHandles, //指示新进程是否从调用进程处继承了句柄。如果参数的值为真,调用进程中的每一个可继承的打开句柄都将被子进程继承。被继承的句柄与原进程拥有完全相同的值和访问权限。
_In_ DWORD dwCreationFlags, //指定附加的、用来控制优先类和进程的创建的标志。
_In_opt_ LPVOID lpEnvironment, //指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境。其间的每个字符都是name=value的形式
//注意一个ANSI环境块是由两个零字节结束的:一个是字符串的结尾,另一个用来结束这个快。一个Unicode环境块石油四个零字节结束的:两个代表字符串结束,另两个用来结束块。
_In_opt_ LPCTSTR lpCurrentDirectory, //这个字符串用来指定子进程的工作路径。这个字符串必须是一个包含驱动器名的绝对路径。如果这个参数为空,新进程将使用与调用进程相同的驱动器和目录。
_In_ LPSTARTUPINFOW lpStartupInfo, //指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体。
_Out_ LPPROCESS_INFORMATION lpProcessInformation //成功返回非0,失败返回0。使用GetLastError函数获得错误的附加信息。
);
lpStartupInfo的dwFlags可以是如下参数
// Dual Mode API below this line. Dual Mode Structures also included.
#define STARTF_USESHOWWINDOW 0x00000001
#define STARTF_USESIZE 0x00000002
#define STARTF_USEPOSITION 0x00000004
#define STARTF_USECOUNTCHARS 0x00000008
#define STARTF_USEFILLATTRIBUTE 0x00000010
#define STARTF_RUNFULLSCREEN 0x00000020 // ignored for non-x86 platforms
#define STARTF_FORCEONFEEDBACK 0x00000040
#define STARTF_FORCEOFFFEEDBACK 0x00000080
#define STARTF_USESTDHANDLES 0x00000100
#if(WINVER >= 0x0400)
#define STARTF_USEHOTKEY 0x00000200
#define STARTF_TITLEISLINKNAME 0x00000800
#define STARTF_TITLEISAPPID 0x00001000
#define STARTF_PREVENTPINNING 0x00002000
*/
LPCTSTR lpApplicationName = _T("C:\\Windows\\system32\\calc.exe");
LPTSTR lpCommandLine = NULL;
LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
BOOL bInheritHandles = FALSE;
DWORD dwCreationFlags = 0;
LPVOID lpEnvironment = NULL;
LPCTSTR lpCurrentDirectory = NULL;
STARTUPINFOW startupInfo = { 0 };
startupInfo.cb = sizeof(STARTUPINFO);
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
PROCESS_INFORMATION processInformation = { 0 };
ret = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, &startupInfo, &processInformation);
if(ret) {
printf("CreateProcess -> %d -> succ\n", ret);
ret = CloseHandle(processInformation.hThread);
if (ret) {
printf("CloseHandle processInformation.hProcess -> %d -> succ\n", ret);
}
else {
printf("CloseHandle processInformation.hProcess -> %d -> fail(%ld)\n", ret, GetLastError());
}
ret = CloseHandle(processInformation.hProcess);
if (ret) {
printf("CloseHandle processInformation.hProcess -> %d -> succ\n", ret);
}
else {
printf("CloseHandle processInformation.hProcess -> %d -> fail(%ld)\n", ret, GetLastError());
}
}
else {
printf("CreateProcess -> %d -> fail(%ld)\n", ret, GetLastError());
}
/*
ShellExecute解析系统注册表HKEY_CLASSES_ROOT中所有的内容,判断启动那一个执行程序,并且启动一个新的实例或使用DDE将文件名连到一打开的实例。然后,ShellExecute 返回打开文件的应用的实例句柄。
SHSTDAPI_(HINSTANCE) ShellExecute(
_In_opt_ HWND hwnd, //用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口,可以为NULL
_In_opt_ LPCTSTR lpOperation, //用于指定要进行的操作(open:打开程序或文件或文件夹、print:打印文件、explore:浏览文件夹),当参数为NULL时,默认执行open
_In_ LPCTSTR lpFile, //用于指定要打开的文件名,要执行程序的文件名,或要浏览的文件夹名,或网址,或邮件链接
_In_opt_ LPCTSTR lpParameters, //若lpFile参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为NULL
_In_opt_ LPCTSTR lpDirectory, //用于指定默认目录
_In_ INT nShowCmd //若lpFile参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0
);
*/
HWND hwnd = NULL;
LPCTSTR lpOperation = _T("open");
LPCTSTR lpFile = _T("http://www.baidu.com");
//LPCTSTR lpFile = _T("mailto:1543289981@qq.com");
LPCTSTR lpParameters = NULL;
LPCTSTR lpDirectory = NULL;
int nShowCmd = SW_SHOWNORMAL;
/*
程序的实例是一个正在运行的程序的信息,这样的信息很多,需要有一个代表
早期windows没有完整的进程支持,所有任务共用地址空间,此时程序映像基地址就是一个不错的代表实例的东西
现在windows有了完整的进程,地址空间隔离了,于是映像基地址就不再具有代表实例的价值,但hinstance这个名字还是传了下来,现在一般用pid代表实例
*/
HINSTANCE hInstance = ShellExecute(NULL, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
printf("ShellExecute -> %d\n", hInstance);
/*
_Check_return_ WINOLEAPI CoInitializeEx(
_In_opt_ LPVOID pvReserved,
_In_ DWORD dwCoInit
);
*/
LPVOID pvReserved = NULL;
DWORD dwCoInit = COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE;
hResult = CoInitializeEx(pvReserved, dwCoInit);
printf("CoInitializeEx -> %d\n", hResult);
/*
typedef struct _SHELLEXECUTEINFOW
{
DWORD cbSize; // in, required, sizeof of this structure
ULONG fMask; // in, SEE_MASK_XXX values
HWND hwnd; // in, optional
LPCWSTR lpVerb; // in, optional when unspecified the default verb is choosen
LPCWSTR lpFile; // in, either this value or lpIDList must be specified
LPCWSTR lpParameters; // in, optional
LPCWSTR lpDirectory; // in, optional
int nShow; // in, required
HINSTANCE hInstApp; // out when SEE_MASK_NOCLOSEPROCESS is specified
void *lpIDList; // in, valid when SEE_MASK_IDLIST is specified, PCIDLIST_ABSOLUTE, for use with SEE_MASK_IDLIST & SEE_MASK_INVOKEIDLIST
LPCWSTR lpClass; // in, valid when SEE_MASK_CLASSNAME is specified
HKEY hkeyClass; // in, valid when SEE_MASK_CLASSKEY is specified
DWORD dwHotKey; // in, valid when SEE_MASK_HOTKEY is specified
union
{
HANDLE hIcon; // not used
#if (NTDDI_VERSION >= NTDDI_WIN2K)
HANDLE hMonitor; // in, valid when SEE_MASK_HMONITOR specified
#endif // (NTDDI_VERSION >= NTDDI_WIN2K)
} DUMMYUNIONNAME;
HANDLE hProcess; // out, valid when SEE_MASK_NOCLOSEPROCESS specified
} SHELLEXECUTEINFOW, *LPSHELLEXECUTEINFOW;
*/
SHELLEXECUTEINFO shellExecuteInfo = { 0 };
shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shellExecuteInfo.lpFile = _T("mspaint.exe");
shellExecuteInfo.lpParameters = NULL;
shellExecuteInfo.lpDirectory = NULL;
shellExecuteInfo.nShow = SW_SHOW;
/*
SHSTDAPI_(BOOL) ShellExecuteExW(_Inout_ SHELLEXECUTEINFOW *pExecInfo);
如果函数成功执行就返回TRUE,否则返回 FALSE 。可调用 GetLastError 获取错误信息。
由于ShellExecuteEx 能够将执行委托给那些由组件对象模型COM激活的Shell 扩展(数据源,上下文菜单句柄,动词实现),因此在调用ShellExecuteEx 之前要先初始化 COM。某些Shell 扩展要求单线程单元模型的COM
在某些情况下 ShellExecuteEx 并没有使用这种类型的Shell 扩展,这时就无需初始化COM。虽然如此,总是在使用这个函数之前初始化COM是个不错的举措。
*/
hResult = ShellExecuteEx(&shellExecuteInfo);
if (hResult) {
printf("ShellExecuteEx -> succ\n");
HANDLE hProcess = shellExecuteInfo.hProcess;
if (hProcess != 0) {
WORD wEvent = WaitForSingleObject(hProcess, INFINITE);
printf("WaitForSingleObject -> event=%d\n", wEvent);
ret = CloseHandle(hProcess);
printf("CloseHandle -> %d\n", ret);
}
}
else {
printf("ShellExecuteEx -> fail(%ld)\n", GetLastError());
}
CoUninitialize();
system("pause");
return 0;
}
相关文章
- qt实现web服务器加载vue应用进行C++和html混合编程-连载【6】-企业级系统开发实战连载系列 -技术栈(vue、element-ui、qt、c++、sqlite)
- C++ 函数调用
- C# 编写Windows Service(windows服务程序)
- [c++菜鸟]《Accelerate C++》习题解答
- 【侯捷】C++内存管理机制
- 84 C++ - 内建函数对象
- 纯C++创建Windows窗体(理解WinMain()与WndProc())
- 开源免费的C/C++网络库(c/c++ sockets library)补充
- [C++]:万字超详细讲解多态以及多态的实现原理(面试的必考的c++考点)
- 使用c++filt命令还原C++编译后的函数名
- windows环境下C++代码打印函数堆栈调用情况
- 《易学C++(第2版)》——导读
- 《21天学通C++(第7版)》——12.6 总结
- Windows 开发之VC++垃圾清理程序软件
- 将C++对象暴露给QML
- 安装SQL Server 2012过程中出现“启用windows功能NetFx3时出错”(错误原因、详细分析及解决方法)以及在Windows Server2012上安装.NET Framework 3
- 【C++:STL之栈和队列 | 模拟实现 | 优先级队列 】
- 让自己的C++程序(非服务程序)运行为一个windows service
- C++ LinuxWebServer项目(6)压力测试与优化思考
- 201、【数组】leetcode ——面试题 17.05. 字母与数字(C++版本)
- 数据结构与算法——AVL树类的C++实现
- C++反汇编第一讲,不同作用域下的构造和析构的识别
- Windows使用WxWidgets开发界面(c++)环境搭建
- C/C++程序员必须熟练应用的开源项目
- C/C++教程 第九章 —— windows编程入门
- C/C++ 从零实现一个windows窗口(非常详细)
- C/C++网络编程详解(Windows版)
- Windows下C++软件调试——检测内存泄露
- C/C++ Windows API——Udp
- C/C++ Windows API——获取磁盘信息