// 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;
}
C/C++ Windows API——执行进程
最新推荐文章于 2024-03-16 21:23:12 发布