×

安装驱动程序的API,SetupCopyOEMInfW 和 UpdateDriverForPlugAndPlayDevices

hqy hqy 发表于2025-01-22 15:56:56 浏览2 评论0

抢沙发发表评论

mportant;">Windows下安装驱动程序的api特别的多,反正有一堆。这里介绍2个我用过的,供人参考。



	BOOL b;
	int result=0;

	result = UpdateDriverForPlugAndPlayDevices(0,
		L"USB\\Class_ff&SubClass_42&Prot_01",//L"USB\\VID_04E8&PID_6860&MI_01",
		L"D:/mgyun_driver_32_4/android_winusb.inf",
		INSTALLFLAG_FORCE,
		&b);
		cout<<result<<endl;
		cout<<hex<<GetLastError()<<endl;



第一个参数窗口句柄,可以为0,

第二个参数 设备的HID,可以使用通用ID;

第三个参数,inf文件的路径

第四个参数,标志符,强制安装等选项

第五个参数,用来传出一个BOOL值,指示是否需要重启电脑,然后由程序决定是否重启电脑。

详细请参见:windows/hardware/ff553534%28v=vs.85%29.aspx" rel="nofollow noopener noreferrer" style="box-sizing: border-box; outline: none; margin: 0px; padding: 0px; text-decoration-line: none; cursor: pointer; color: rgb(78, 161, 219); font-synthesis-style: auto; overflow-wrap: break-word; font-size: 12px;">http://msdn.microsoft.com/en-us/library/windows/hardware/ff553534(v=vs.85).aspx


这个函数在设备没有连接电脑的情况下会出错,错误号码为:ERROR_NO_SUCH_DEVINST

对于64位还是32位程序有要求,也就是必须在64位平台上生成64位的程序。否则会出错ERROR_IN_WOW64。


好处是,执行完成后,设备的驱动就会被加载,启用。因此有些时候,这个函数的执行时间会有一点长。如果驱动签名没有验证,还会弹一个框提示用户进行选择。

-------------------------------------------------------------------------------


	BOOL setupResult;
		setupResult = SetupCopyOEMInf(
						infFile, //L"D:\\NB_Driver\\usb_driver\\android_winusb.inf",
						L"",
						SPOST_NONE, //忽略 OEMSourceMediaLocation的内容
						SP_COPY_NEWER_OR_SAME, //SP_COPY_REPLACEONLY,替换,一般是升级时用。SP_COPY_NOOVERWRITE
						NULL,
						0,
						NULL,
						NULL);
		if(setupResult == TRUE)
			cout<<"sucess"<<endl;
		else
		{
			DWORD d1 = GetLastError();
			std::cout<<hex<<d1<<std::endl;
		}


这个函数实现的是无设备安装,即设备没有插入也可以安装驱动。


那么当设备插入电脑的时候,系统就可以自动安装驱动。 


BOOL WINAPI SetupCopyOEMInf(
  __in       PCTSTR SourceInfFileName,
  __in       PCTSTR OEMSourceMediaLocation,
  __in       DWORD OEMSourceMediaType,
  __in       DWORD CopyStyle,
  __out_opt  PTSTR DestinationInfFileName,
  __in       DWORD DestinationInfFileNameSize,
  __out_opt  PDWORD RequiredSize,
  __out_opt  PTSTR DestinationInfFileNameComponent
);



第一个参数inf的路径

第二个参数源媒体的路径

第三个参数指示源媒体的类型。OEMSourceMediaType。SPOST_NONE:忽略OEMSourceMediaLocation的内容。SPOST_PATH:代表OEMSourceMediaLocation为真正驱动文件的地址,一般为驱动文件sys的地址。(如果你的sys文件跟inf在一个地方,那么OEMSourceMediaLocation可以为NULL),SPOST_URL,这个代表OEMSourceMediaLocation为一个网址,即驱动在internet上。 

第四个参数 复制类型。一般我们用到的就SP_COPY_REPLACEONLY,替换,一般是升级时用。SP_COPY_NOOVERWRITE,系统是否已经预存了inf文件。SP_COPY_NEWER_OR_SAME,inf文件比系统的inf新或者一样时进行更新。

后面的参数,好像全用不上啊。具体请参见 http://msdn.microsoft.com/en-us/library/aa376990.aspx

反正我这样是成功了。


上代码吧:


// driverInstall.cpp : 定义控制台应用程序的入口点。
//
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <fstream>

#include <Windows.h>
#include <SetupAPI.h>

#include <newdev.h>

//#pragma comment( linker, "/subsystem:windows /entry:wmainCRTStartup " )  

//在release 模式下不显示黑窗口
//同时不显示任何输出
#ifdef NDEBUG
#pragma comment( linker, "/subsystem:windows /entry:wmainCRTStartup" )
#endif


using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

	_TCHAR * infFile = NULL;

	bool fileExists = false;
	if(argc > 1)
	{
		infFile = argv[1];
		fstream _file;
		_file.open(infFile, ios::in);
		if(!_file)
		{
			cout<<"file not exist"<<endl;
			return 0;//文件不存在
		}
		else
		{
			fileExists = true;//文件存在
		}
	}
	else //无参数
		return -1;

	BOOL setupResult;
	if(fileExists == true)
	{

		BOOL b;
		BOOL result=FALSE;

		result = UpdateDriverForPlugAndPlayDevices(0,
			L"USB\\VID_04E8&PID_6860&MI_01",
			infFile,
			INSTALLFLAG_FORCE,
			&b);
		cout<<result<<endl;
		cout<<hex<<GetLastError()<<endl;
		getchar();



		setupResult = SetupCopyOEMInfW(
			infFile, 
			L"",
			SPOST_NONE, //忽略 OEMSourceMediaLocation的内容
			SP_COPY_NEWER_OR_SAME, //SP_COPY_REPLACEONLY,替换,一般是升级时用。SP_COPY_NOOVERWRITE
			NULL,
			0,
			NULL,
			NULL);
		if(setupResult == TRUE)
			cout<<"sucess"<<endl;
		else
		{
			DWORD d1 = GetLastError();
			std::cout<<hex<<d1<<std::endl;
		}
	}


	getchar();

	return 0;
}


打赏

本文链接:https://www.kinber.cn/post/4721.html 转载需授权!

分享到:


推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

 您阅读本篇文章共花了: 

群贤毕至

访客