现用installshield 做一个打包
第三方驱动程序的安装程序,要求整个
过程自动完成,本来是很easy的事情,
但这个驱动程序的安装win98要求指定.cat文件的路径
我把.cat copy到对应目录没用,win98还是要指定目录。
98寻找的目录时,有的机器是找系统安装时的目录,有的是
要求放入软盘或驱动光盘。不知道有没有类似2000下的SetupCopyOEMInf
一样的api可以指定这个.cat的寻找路径请赐教!
第三方驱动程序的安装程序,要求整个
过程自动完成,本来是很easy的事情,
但这个驱动程序的安装win98要求指定.cat文件的路径
我把.cat copy到对应目录没用,win98还是要指定目录。
98寻找的目录时,有的机器是找系统安装时的目录,有的是
要求放入软盘或驱动光盘。不知道有没有类似2000下的SetupCopyOEMInf
一样的api可以指定这个.cat的寻找路径请赐教!
解决方案 »
- MFC的对话框工程没有OnDraw,如果想留“界面痕迹”,怎么办?
- CFile的二进制文件读取问题,CFile::modeReadWrite标记和CFile::modeRead标记
- CListCtrl 项刷新问题
- 帮忙看一段程序
- 用vc编写com访问ejb的疑问,高手们请指点,谢谢
- CTreeCtrl问题
- 为什么简单的一行代码就可让WindowsXP/2000 崩溃?
- 在ATL的Service类型的COM中调用MFC的类库CString问什么总是出错?(在线等待,到明天结贴)
- 推者有分
- onsize()如何用?
- 在那里可以找ADO返回的ErrorCode的定义?
- 请问,如何能做出想QQ那样能让用户改变大小的窗口(就是能把它拉长和拉宽)?
将Inf文件拷贝到 windows\inf\下,在写一次注册表如下,然后重启动。
HKEY hPath;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,REG_KEY,0,NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hPath,
NULL) != ERROR_SUCCESS)
return FI_FAILURE;
RegSetValueEx(hPath,"SourcePath",0,REG_SZ,(CONST BYTE*)sourcePath,strlen(sourcePath));
RegCloseKey(hPath);
这种方法要重新启动两次,如果要只想重新启动一次就在写完注册表后调用以下函数(二次启动中的第一次启动也就是让系统调用这个函数,二者用途一样):
DEVINST devInst;
if (CM_Locate_DevNode(&devInst,
NULL,
CM_LOCATE_DEVNODE_NORMAL
) == CR_SUCCESS ){
CM_Reenumerate_DevNode(devInst,0);
Sleep(5000);
}如果系统已经为设备安装了“未知设备”,那么CM_Reenumerate_DevNode或第一启动就不会发现新设备,从而安装是不会成功的。所以在安装前必须先清除已经安装的“未知设备”:
这段函数就是发现HARDWARE ID = sHardwareID的设备。如果是9x则将其删除,即使已经安装了正确驱动。
BOOL Find_Installed(LPCSTR sHardwareID){
HDEVINFO hIntDevInfo = INVALID_HANDLE_VALUE;
LPGUID lpGuid = (LPGUID)&GUID_DEVCLASS_SCSIADAPTER;
for(int i = 0; i< 2; i++){
BOOL isDriverInstalled = false;
if(i == 1) lpGuid = (LPGUID)&GUID_DEVCLASS_UNKNOWN;
hIntDevInfo = SetupDiGetClassDevs(
lpGuid,
NULL,
NULL,
DIGCF_PRESENT);
if( hIntDevInfo != INVALID_HANDLE_VALUE ) {
SP_DEVINFO_DATA devInfo;
HARDWARE_ID srchid;
strcpy(srchid.hardwareID ,sHardwareID);
ParseHIDStr(&srchid);
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
int index = 0;
while (SetupDiEnumDeviceInfo(hIntDevInfo,index++,&devInfo)) {
char buf[256];
if(CM_Get_Device_ID(devInfo.DevInst,buf,256,0) == CR_SUCCESS){
HARDWARE_ID hid;
strcpy(hid.hardwareID ,buf);
ParseHIDStr(&hid);
//MessageBox(NULL,buf,"Found a scsi adapter.",MB_OK);
if( CompHardwareID(&srchid,&hid) ){
//MessageBox(NULL,buf,"The is the scsi adapter to be installed.",MB_OK);
isDriverInstalled = true;
if(IsWin9x() == 1 ){
SetupDiRemoveDevice(hIntDevInfo,&devInfo);
}else {
return true;
}
}
}
}
}
}
return false;
}
将Inf文件拷贝到 windows\inf\下,在写一次注册表如下,然后重启动。
HKEY hPath;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,REG_KEY,0,NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hPath,
NULL) != ERROR_SUCCESS)
return FI_FAILURE;
RegSetValueEx(hPath,"SourcePath",0,REG_SZ,(CONST BYTE*)sourcePath,strlen(sourcePath));
RegCloseKey(hPath);
这种方法要重新启动两次,如果要只想重新启动一次就在写完注册表后调用以下函数(二次启动中的第一次启动也就是让系统调用这个函数,二者用途一样):
DEVINST devInst;
if (CM_Locate_DevNode(&devInst,
NULL,
CM_LOCATE_DEVNODE_NORMAL
) == CR_SUCCESS ){
CM_Reenumerate_DevNode(devInst,0);
Sleep(5000);
}如果系统已经为设备安装了“未知设备”,那么CM_Reenumerate_DevNode或第一启动就不会发现新设备,从而安装是不会成功的。所以在安装前必须先清除已经安装的“未知设备”:
这段函数就是发现HARDWARE ID = sHardwareID的设备。如果是9x则将其删除,即使已经安装了正确驱动。
BOOL Find_Installed(LPCSTR sHardwareID){
HDEVINFO hIntDevInfo = INVALID_HANDLE_VALUE;
LPGUID lpGuid = (LPGUID)&GUID_DEVCLASS_SCSIADAPTER;
for(int i = 0; i< 2; i++){
BOOL isDriverInstalled = false;
if(i == 1) lpGuid = (LPGUID)&GUID_DEVCLASS_UNKNOWN;
hIntDevInfo = SetupDiGetClassDevs(
lpGuid,
NULL,
NULL,
DIGCF_PRESENT);
if( hIntDevInfo != INVALID_HANDLE_VALUE ) {
SP_DEVINFO_DATA devInfo;
HARDWARE_ID srchid;
strcpy(srchid.hardwareID ,sHardwareID);
ParseHIDStr(&srchid);
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
int index = 0;
while (SetupDiEnumDeviceInfo(hIntDevInfo,index++,&devInfo)) {
char buf[256];
if(CM_Get_Device_ID(devInfo.DevInst,buf,256,0) == CR_SUCCESS){
HARDWARE_ID hid;
strcpy(hid.hardwareID ,buf);
ParseHIDStr(&hid);
//MessageBox(NULL,buf,"Found a scsi adapter.",MB_OK);
if( CompHardwareID(&srchid,&hid) ){
//MessageBox(NULL,buf,"The is the scsi adapter to be installed.",MB_OK);
isDriverInstalled = true;
if(IsWin9x() == 1 ){
SetupDiRemoveDevice(hIntDevInfo,&devInfo);
}else {
return true;
}
}
}
}
}
}
return false;
}
win98好象是根据system 下的一些.dat文件找到以前的OS安装目录
然后到那里去找文件了,现在希望这个目录能由我自己指定,类似
2000下安装驱动用的SetupCopyOEMInf,在script里直接用api还是调dll无所谓。help...
//////////////////////////////////////////////////////////////////
iamltq(小强):
我用的是professional 6.3版本
你只要指定两个package 分别放inf 和 system文件 指定好路径和OS版本
然后在OnEnd中调用
kernel32.DeleteFileA(WINDIR^"Inf\\Drvidx.bin");// winapi 需要声明prototype
//BOOL kernel32.DeleteFileA( BYVAL STRING );
kernel32.DeleteFileA(WINDIR^"Inf\\Drvdata.bin");
LaunchAppAndWait("rundll.exe", "setupx.dll,DiBuildDriverIndex 0", WAIT);
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup中的SourcePath值看看能否成功找到你所需要的文件?另外问问:“本来是很easy的事情”,请问你是通过什么函数来实现自动安装的。是否是setupx.dll中16为函数?
我up up回复都有写
LaunchAppAndWait("rundll.exe", "setupx.dll,DiBuildDriverIndex 0", WAIT);我现在的问题是比一般的驱动安装文件多了.cat文件,没这个整个过程就都自动了
现在就是要解决在找.cat时的默认路径问题。
另外98下这个路径不是从注册表得到的,可能是从windir下的.dat文件得到的(我猜想)
之后才会在注册表反映出来