Bootstrap

Windows程序设计4:API函数URLDownloadToFile和ShellExecuteEx


前言

Windows程序设计4:API函数URLDownloadToFile和ShellExecuteEx。


一、URLDownloadToFile

大家平时经常下载文件,那么如何使用C/C++实现文件的下载,就需要使用API函数URLDownloadToFile。需要注意的是,这个函数已经被很多安全厂商视为敏感函数了,如果程序中使用了这个函数,360,火绒之类的安全软件可能会产生提示。

1.URLDownloadToFile简介

指从指定URL地址读取内容,并将读取到的内容保存到特定的文件里。具体的函数语法如下

HRESULT URLDownloadToFile( 
    LPUNKNOWN pCaller,
    LPCTSTR szURL,
    LPCTSTR szFileName,
    DWORD dwReserved,
    LPBINDSTATUSCALLBACK lpfnCB
);

返回值为HRESULT类型,实际上就是long类型;返回s_OK表示下载成功;E_OUTOFMEMORY表示缓冲区长度不够,或者没有足够的内存来完成下载操作;INET_E_DOWNLOAD_FAILURE表示限定的资源或者回调窗口有问题。
在这里插入图片描述
共有5个参数。
第一个参数LPUNKNOWN pCaller为ActiveX控件的接口指针,如果当前程序不是ActiveX控件时写NULL即可;
第二个参数LPCTSTR szURL比较重要,是一个字符指针,传入一个字符串,表示要下载的url地址,不能为空;
第三个参数LPCTSTR szFileName是一个字符指针,传入一个字符串,表示下载文件后,保存的文件名字,包含具体的路径信息;
第四个参数DWORD dwReserved为保留字段,是微软为以后功能扩展考虑的,必须为0;
第五个参数LPBINDSTATUSCALLBACK lpfnCB,一般情况下作为下载进度状态回调接口的指针,如果要实时监控下载文件的状态那么就要用到这个参数。

2.URLDownloadToFile使用

使用函数URLDownloadToFile时要注意该函数使用时需要包含一些文件,具体如下
在这里插入图片描述
则源文件中的代码如下。注意,这里使用了预编译头,因此还要include"pch.h"。

// Win_4.cpp : 定义应用程序的入口点。
//
#include "pch.h"
#include <windows.h>
#include <tchar.h>
#include <Urlmon.h>
#pragma comment(lib,"Urlmon.lib")




int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    
	HRESULT hret = URLDownloadToFile(NULL,_T("https://search-operate.cdn.bcebos.com/4466f881476a1ee804b4a32aee790675.gif"), _T("D:\\111.gif"), 0, NULL);
	if (hret == S_OK) // 下载成功
	{
		MessageBox(NULL, _T("下载成功"), _T("提示"), MB_OK);
	}
	else // 下载失败
	{
		MessageBox(NULL, _T("下载失败"), _T("提示"), MB_OK);
	}
	return 0;
}


这里下载的是百度页面的图片,如下图
在这里插入图片描述
右键点击复制图片地址即可得到该图片的地址https://search-operate.cdn.bcebos.com/4466f881476a1ee804b4a32aee790675.gif

可以看到在设定的D盘目录下下载成功了文件111.gif
在这里插入图片描述
同时MessageBox弹窗提示下载成功

在这里插入图片描述

二、ShellExecuteEx

1.ShellExecuteEx简介

对于电脑中的文件,我们肯定要执行它,就是双击文件。如果是图片或视频,我们要打开看;如果是.exe可执行文件,我们就要执行。利用C\C++执行文件就要用到函数ShellExecuteEx。准确来说该函数是一个Shell API,不是Windows系统的标准API,是经过微软封装了一层,这样我们使用起来更加方便。具体语法如下

BOOL ShellExecuteEx(SHELLEXECUTEINFO *pExecInfo)

返回值为布尔类型,执行成功返回TRUE;执行失败返回FALSE。
参数 pExecInfo 是一个指向 SHELLEXECUTEINFO 结构的指针,该结构包含并接收有关正在执行的应用程序的信息。SHELLEXECUTEINFO 结构体的主要成员包括:

cbSize:DWORD类型,结构的大小,sizeof(SHELLEXECUTEINFO )。
fMask:ULONG类型,指定结构成员的有效性,表示想干什么。
hwnd:HWND类型,表示调用该函数要以哪个窗口为父窗口,父窗口句柄或出错时显示错误父窗口的句柄,可以为NULL。
lpVerb:LPCTSTR类型,指定该函数的执行动作(如打开open、编辑edit等)。
lpFile:LPCTSTR类型,操作对象路径。
lpParameters:LPCTSTR类型,执行对象程序时需要传入的参数,可以为NULL。
lpDirectory:LPCTSTR类型,工作目录,可以为NULL。
nShow:int类型,显示方式。

!!!!!!!下面的参数不经常使用

hInstApp:HINSTANCE类型,如果设置了 SEE_MASK_NOCLOSEPROCESS,并且调用成功则该值大于32,调用失败则被设置错误值。
lpIDList:LPVOID类型,ITEMIDLIST结构的地址,存储成员的特别标识符。
lpClass:LPCTSTR类型,指明文件类别的名字或GUID。
hkeyClass:HKEY类型,获得已在系统注册的文件类型的Handle。
dwHotKey:DWORD类型,程序的热键关联。
hIcon:HANDLE类型,取得对应文件类型的图标的Handle。
hMonitor:HANDLE类型,将文档显示在显示器上的Handle‌
hProcess: HANDLE类型,指向新启动的程序句柄,若fMask不为SEE_MASK_NOCLOSEPROCESS则为NULL;但若程序没有启动,即便fMask为SEE_MASK_NOCLOSEPROCESS,该值仍为NULL;如果没有创建新进程,也为NULL。

2.ShellExecuteEx使用

以打开刚刚下载的111.gif为例。
首先需要定义一个SHELLEXECUTEINFO类型的实例

SHELLEXECUTEINFO ShellInfo = {0};//定义一个SHELLEXECUTEINFO类型实例便于函数ShellExecuteEx使用,并将所有成员初始化为0

然后需要给一些成员赋值

	ShellInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	ShellInfo.lpVerb = _T("open"); //动作为打开
	ShellInfo.lpFile = _T("D:\\111.gif"); // 要打开文件的路径
	ShellInfo.nShow = SW_SHOW; //采用默认的显示方式即可

然后就可以调用函数ShellExecuteEx

BOOL bRet= ShellExecuteEx(&ShellInfo); // 调用函数ShellExecuteEx

可以看到图片已被打开
在这里插入图片描述
同时由于这台计算机安装了火绒,正如前面所说,火绒进行了报警,并将生成的.exe可执行文件进行了隔离
在这里插入图片描述


总结

Windows程序设计4:API函数URLDownloadToFile和ShellExecuteEx。

;