打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
关于Windows下面的如何自动安装驱动
userphoto

2011.09.12

关注
问题:
Hi,
小弟目前做的项目需要在Windows下安装一个简单的USB驱动,驱动程序由第三方提供(没有经过MS认证),包含DLL、INF、SYS等等文件。
一般情况下,当即插即用设备连上PC后,如果PC中没有该设备的驱动,会弹出安装驱动的提示,用户根据提示来一步步安装就可以了。
现在这个项目需要事先就把驱动安装到PC中去,也就是把安装驱动这件事放在安装软件(项目最终的发布软件)的过程中完成。那么应该怎么去安装驱动呢?
并且由于软件最终会运行在XP、VISTA和Windows7下面,那么这三个系统下的自动安装的过程有多大的区别呢?


PS:请教过一个高手,写个精简DOS程序即可,但还是没有弄清楚。正在看《Windows驱动开发技术详解》,由于不是写驱动,只是安装驱动,这本书中也没有找到可行的办法。

-----------------------------------------------------------------------
答案1[推荐答案]
安装驱动,直接写批处理test.bat,直接安装test.inf
rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 test.inf

对于不同的系统,在批处理里用ver判断即可

-----------------------------------------------------------------------
答案2:
楼上能更详细一些么?
直接安装test.inf是否就是通过下面的rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 test.inf 这一行命令实现的?

另外能给系统标识给小弟么,即ver判断的值是?

谢谢啦!

-----------------------------------------------------------------------
答案3:
加载驱动可以采用1楼的方法,也可以自己写一个加载驱动的程序(网上类似代码很多),在程序中判断操作系统的版本即可。加载程序打包进安装包里,在安装的时候运行就大功告成了。

-----------------------------------------------------------------------
答案4[推荐答案]
前天安装 Windows 7,发现它里面自带了 自动安装驱动的功能。
建议楼主参考一下。

-----------------------------------------------------------------------
答案5:
比如:setup.exe中调用test.bat,有各个版本驱动
BatchFile code
@echo offecho 判断系统版本ver|find "5.0">nul&&goto :win2kver|find "5.1">nul&&goto :winxpver|find "5.2">nul&&goto :win2k3ver|find "6.1">nul&&goto :win7goto :end:win2kset inf=win2k\test.infgoto :install:winxpset inf=winxp\test.infgoto :install:win2k3set inf=win2k3\test.infgoto :install:win7set inf=win7\test.infgoto :install:installecho 安装驱动rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 %inf%echo 安装完成goto :endpause>nul:end

-----------------------------------------------------------------------
答案6:
回chenhao1988: 小弟我在网上搜了一天,没有搜到合适的,由于我之前没有碰过Windows驱动这一块,所以盲目啊,简直不知道该搜什么关键字好了。能提供个好的链接么?
另外,关于操作系统的版本的获取是调用什么库函数?还是通过别的途径获取?
不胜感激啊。


回DiaoNianYu: 我装了Windows7,没找到“自动安装驱动”的功能。。。


另外请教一下: 在Windows7和在xp以及VISTA下面安装驱动有什么不同?
也就是说1楼提供的方法,在vista和WIN7下能安装么?(话说这个应该是我有了代码后优先测试的)


-----------------------------------------------------------------------
答案7[推荐答案]
win7和xp、vista下安装驱动一样的呀,要么是提供的setup.exe程序,要么是自动搜索光盘里的.inf,要么手工搜索指定的.inf

vista和win7的驱动一般都是公用的,要不为什么说win7是在vista版本上的改进呢

-----------------------------------------------------------------------
答案8:
回just4:
谢谢提供源码啊!
驱动只有一个版本(XP/VISTA/WINDOWS7下都是这一个驱动,不过有32位和64位之分。。)。
一、请教一下这一行“rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 %inf%
”,因为我没写过批处理程序(=.=!够菜的),所以不免很多问题啊(高抬贵手,请不要“不解释”啊~~)。这一行中按照说明应当就是安装驱动的,呃,InstallHinfSection的职责是什么呢?我都是一个一个关键字去搜索的。
二、还有就是这里面怎么设置inf文件的路径呢?
三、是否只要安装INF文件就可以了,那么直接右击INF文件选择“安装”是表示什么意思呢?(这样子我试过,不能安装)

-----------------------------------------------------------------------
答案9:
我刚找了一篇讲批处理的文章,正在看,发现跟不上回帖的高手的步伐了。。。
抓紧时间!!!

-----------------------------------------------------------------------
答案10:
请教just4:

我刚刚试了一下。
批处理代码如下:
@echo off
echo 判断系统版本
set inf=D:\XP\DRIVER\CH341WDM.INF
echo 安装驱动
rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 %inf%
echo 安装完成

发现没有安装上去,请问是怎么一回事呢? 问题出在哪里了呢?




-----------------------------------------------------------------------
答案11:
C++加载驱动代码,具体你再研究一下,我从程序里粘出来的。
//加载驱动文件
//DriverName为驱动文件名
//DeviceName为设备名
//
//----------------------------------------------------------------------
bool LoadDriver(char* DriverName,char* DeviceName)
{
SC_HANDLE hServiceMgr=NULL;
SC_HANDLE hServiceCre=NULL;
SC_HANDLE hServiceOpen=NULL;
HANDLE hDevice=NULL;
char Device[64]={0};
char Driver[32]={0};
int i=0;
hServiceMgr=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hServiceMgr==NULL)
{
return false;
}
lstrcpy(Device,DeviceName);

lstrcpy(Driver,DriverName);
lstrcat(Driver,".sys");
TCHAR dirpath[MAX_PATH]={0};


GetFullPathName(Driver, MAX_PATH, dirpath, NULL);
//创建服务
if((hServiceCre=CreateService( hServiceMgr, 
DriverName, //SYSTEM\CurrentControlSet\Services 驱动程序的在注册表中的名字 
DriverName, // 注册表驱动程序的 DisplayName 值 
SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限 
SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序 
SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值 
SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值 
dirpath, // 注册表驱动程序的 ImagePath 值 
NULL,
NULL,
NULL, 
NULL, 
NULL))!=NULL)
{
CloseServiceHandle(hServiceCre);
hServiceOpen=OpenService(hServiceMgr, DriverName, SERVICE_ALL_ACCESS);
StartService(hServiceOpen,0,NULL);
CloseServiceHandle(hServiceOpen);
hServiceOpen=NULL;
hServiceCre=NULL;
}
else

DWORD dwRtn=0;
dwRtn = GetLastError(); 
if( dwRtn == ERROR_SERVICE_EXISTS || dwRtn==ERROR_SERVICE_MARKED_FOR_DELETE) 
{
if ((hServiceOpen = OpenService(hServiceMgr, DriverName, SERVICE_ALL_ACCESS)) != NULL)
{
StartService(hServiceOpen,0,NULL);
CloseServiceHandle(hServiceOpen);
hServiceOpen=NULL;
}

}
if ((hDevice = CreateFile(Device, GENERIC_READ|GENERIC_WRITE, \
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
{
CloseHandle(hDevice);
}
else
{
hServiceOpen = OpenService(hServiceMgr, DriverName, SERVICE_ALL_ACCESS);
DWORD dw=0;
dw=DeleteService(hServiceOpen);
CloseServiceHandle(hServiceMgr);
return false;
}
CloseServiceHandle(hServiceMgr);
return true;
}
//----------------------------------------------------------------------
//
//卸载驱动文件
//DriverName为驱动文件名
//
//----------------------------------------------------------------------
bool UnLoadDriver(char* DriverName)
{
SC_HANDLE hServiceMgr=NULL;
SC_HANDLE hServiceOpen=NULL;
int i=0;
hServiceMgr=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hServiceMgr==NULL)
{
return false;
}
if ((hServiceOpen=OpenService(hServiceMgr,DriverName,SERVICE_ALL_ACCESS)) == NULL) 
{
CloseServiceHandle(hServiceMgr);
return false;
}
SERVICE_STATUS serviceStatus;
//关闭启动的服务
if (!ControlService(hServiceOpen,
SERVICE_CONTROL_STOP,
&serviceStatus)) // pointer to arguments 
{
DWORD err=0;
err = GetLastError();
if (err == ERROR_SERVICE_NOT_ACTIVE) 
{
DeleteService(hServiceOpen);
CloseServiceHandle(hServiceOpen);
hServiceOpen=NULL;

}
while(serviceStatus.dwCurrentState == SERVICE_STOP_PENDING && i++ <80)
{
QueryServiceStatus(hServiceOpen, &serviceStatus);
Sleep(50);
}
if(serviceStatus.dwCurrentState == SERVICE_STOPPED)
{
DeleteService(hServiceOpen);
CloseServiceHandle(hServiceOpen);
hServiceOpen=NULL;
}
CloseServiceHandle(hServiceMgr);
return true;
}

-----------------------------------------------------------------------
答案12[推荐答案]
关于获取操作系统版本,可用Windows API
GetVersionEx  
VerifyVersionInfo用法见MSDN。

-----------------------------------------------------------------------
答案13:
回chenhao1988:
非常感谢你提供源代码,在《Windows驱动开发技术详解》中的第三章附的源码中看到过类似的代码。
这种解决方案是采用NT方式加载驱动的。
要安装的驱动是要采用WDM方式的。
不过我对这两种方式还不是太熟悉(从没做过驱动=.=!),我不清楚通过NT方式能否加载。我只知道WDM对应的驱动程序有INF、SYS、VXD等等文件,需要把这些文件COPY到系统文件夹下,并修改注册表。而NT方式我从源代码中看到只有复制SYS文件,其他的似乎并没有复制。

我昨天晚上参照just4的源码通过批处理程序来做,但是发现只把SYS复制过去了,DLL文件并没有复制过去。关于注册表有没有修改,我还没有看。。。

chenhao1988能解答一下么?上面说的有点啰嗦啊~~ 就是NT方式能够加载WDM驱动么?还有就是为什么我参照just4的方法没有成功(现象是插上硬件后还是会弹出提示)?

-----------------------------------------------------------------------
答案14:
内部原理 倒没有考虑过,学习了

-----------------------------------------------------------------------
答案15[推荐答案]
对了,将inf文件中的驱动加载方式StartType = 0 ;SERVICE_BOOT_START可以吗?系统启动自动加载。
我对驱动认识也很肤浅。

-----------------------------------------------------------------------
答案16:
回chenhao1988:
将驱动加载方式改为StartType = 0;运行批处理程序后,会提示重启机器,这应该是正确的提示。
这个INF文件里面没有SERVICE_BOOT_START这个设置。

我有一个疑问:就是
“rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 %inf% ”这一行中的DefaultInstall 这个应当为INF文件中的默认安装节。

那么这个的作用应当是 COPY DLL和SYS文件到系统文件夹当中并且修改注册表,这两样事情我测试过了,都是正确的。但是还是会有提示。那么是不是还需要加载服务什么的呢?

在INF文件当中有个
[CH341.Install.NT.Services]
AddService = CH341, 2, CH341.Service

[CH341.Service]
DisplayName = "CH341WDM"
ServiceType = 1
StartType = 0
ErrorControl = 1
ServiceBinary = %10%\System32\Drivers\CH341WDM.SYS
这样子的两个段。 而在上面的批处理程序中似乎没有涉及到服务。请问是不是需要加载服务啊? 应该如何加载呢? 调用什么库函数呢?


高手指点一下啊



-----------------------------------------------------------------------
答案17:
楼主有解决这个问题吗?我最近也在做windows下USB驱动的安装包,实现自动安装。。。学习ing。。。

-----------------------------------------------------------------------
答案18:
楼主这个问题解决了吗,我也碰到一样的问题,
Filename:"RUNDLL32.exe"; Parameters: "setupapi.dll, InstallHinfSectionDefaultInstall 132 {win}\inf\fpga.inf";WorkingDir:{win}\inf;Flags:runhidden


提示安装失败

-----------------------------------------------------------------------
答案19:
我也想知道呢,也不出来总结一下心得.真是的.

-----------------------------------------------------------------------
答案20:
我也想知道,也是这句批处理 但好像没安装成功啊 连小白都算不上的小白求教

-----------------------------------------------------------------------
答案21:
我最近也遇到相似的问题,后来发现如果没有通过微软徽标认证的程序在Windows XP用 rundll32.exesetupapi.dll,InstallHinfSection DefaultInstall 128 test.inf这一行命令是不能实现自动安装的,只有通过微软的徽标认证的驱动才能自动安装。好像是这么回事。我换了有微软数字签名的驱动程序后在XP下能实现自动安装并达到预期的效果。可是在Windows 7下就不能实现自动安装了,对了一下文件是没有修改注册表中的枚举的部分。不知道这是为什么。各位有没有什么好的解决方法?
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
windows7 声卡驱动无法安装的解决方案
提示“未找到调制解调器"解决
Windows7系统USB安装驱动出现“系统找不到指定的文件'解决方案
如何为PE添加SCSI驱动
CAS RESTful API 开发文档
如何实现两台电脑连接共享打印机?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服