怎么使用delphi实现电脑硬件驱动安装??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么使用delphi实现电脑硬件驱动安装??相关的知识,希望对你有一定的参考价值。

1、我先把声卡驱动备份 一个inf文件 、两个sys文件

2、现在把声卡驱动卸载掉并去系统目录把这几个文件清除掉

如果是通过系统的更新驱动找到我备份的目录 进行更新 会发现系统显示把我备份目录下的文件拷贝到了系统的驱动文件对应目录 进行安装驱动的

我想通过delphi来实现通过备份文件进行驱动安装,我是否需要根据文件类型的不同将文件拷贝到对应的目录呢? 或者是通过delphi调用inf文件 ,让inf文件来自己安装呢??
1.copyfile中的.bat文件是从哪里来的??
2、shellexecute 理论上来说是可以使用inf文件 最好能给出实际代码
3、我在这之前已经将声卡的驱动备份到C:\aa文件夹中,共3个文件 1个inf文件2个sys文件
4、我使用dos代码加载inf文件屏幕只是闪了一下,我查看设备管理器发现声卡驱动还是黄色问号
疑问:
1、为啥通过系统更新驱动同样指定了C:\aa文件夹就可以正确安装驱动,而我通过cmd运行
rundll32 syssetup,SetupInfObjectInstallAction DefaultInstall 128 .\xxx.inf
就不可以 只是屏幕闪了下 ,这时查看inf文件夹没有发现驱动的inf文件 ,2个sys文件也没有复制到drivers文件夹中。
2、再有在安装inf文件时是不是得先把驱动文件都拷贝到系统目录里 然后在执行inf文件呢?
3、安装inf文件是不是会自动的将同目录下的驱动文件自动拷贝到系统目录呢??安装inf文件会不会自动填写注册表呢??

参考技术A 我之前写过一个安装虚拟键盘的驱动程序,代码发你参考下

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrlsSetupApi;

const
HardwareIDs = 'VKeyboard';
DeviceName = 'Virtual Keyboard';
MAX_CLASS_NAME_LEN = 128;
DIF_REMOVE = $00000005;
INSTALLFLAG_FORCE = $00000001;
SPDRP_HARDWAREID = $00000001;
DIF_REGISTERDEVICE = $00000019;
DIGCF_PRESENT = $0002;
DIGCF_ALLCLASSES = $0004;
DIGCF_PROFILE = $00000008;
DICD_GENERATE_ID = $00000001;
type
ULONG_PTR = DWORD;
DI_FUNCTION = UINT;

HDEVINFO = Pointer;
PSPDevInfoData = ^TSPDevInfoData;
SP_DEVINFO_DATA = packed record
cbSize: DWORD;
ClassGUID: TGUID;
DevInst: DWORD;
Reserved: ULONG_PTR;
end;
$EXTERNALSYM SP_DEVINFO_DATA
TSPDetsigCmpProc = function (DeviceInfoSet: HDEVINFO; NewDeviceData,
ExistingDeviceData: PSPDevInfoData; CompareContext: Pointer): DWORD; stdcall;
TSPDevInfoData = SP_DEVINFO_DATA;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
Private declarations
public
Public declarations
end;

var
Form1: TForm1;

implementation

$R *.dfm

var
KeyboardClass:TGUID='4D36E96B-E325-11CE-BFC1-08002BE10318';

function SetupDiGetClassDevs(ClassGuid: PGUID; const Enumerator: PAnsiChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall;external 'Setupapi.dll' name 'SetupDiGetClassDevsA';
function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; var DeviceInfoData: TSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiEnumDeviceInfo';
function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO; const DeviceInfoData: TSPDevInfoData; Property_: DWORD; var PropertyRegDataType: DWORD; PropertyBuffer: PBYTE; PropertyBufferSize: DWORD; var RequiredSize: DWORD): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiGetDeviceRegistryPropertyA';
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiDestroyDeviceInfoList';
function SetupDiGetINFClass(const InfName: PAnsiChar; var ClassGuid: TGUID; ClassName: PAnsiChar; ClassNameSize: DWORD; RequiredSize: PDWORD): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiGetINFClassA';
function SetupDiCreateDeviceInfoList(ClassGuid: PGUID; hwndParent: HWND): HDEVINFO; stdcall;external 'Setupapi.dll' name 'SetupDiCreateDeviceInfoList';
function SetupDiCreateDeviceInfo(DeviceInfoSet: HDEVINFO; const DeviceName: PAnsiChar; var ClassGuid: TGUID; const DeviceDescription: PAnsiChar; hwndParent: HWND; CreationFlags: DWORD; DeviceInfoData: PSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiCreateDeviceInfoA';
function SetupDiSetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO; var DeviceInfoData: TSPDevInfoData; Property_: DWORD; const PropertyBuffer: PBYTE; PropertyBufferSize: DWORD): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiSetDeviceRegistryPropertyA';
function SetupDiCallClassInstaller(InstallFunction: DI_FUNCTION; DeviceInfoSet: HDEVINFO; DeviceInfoData: PSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiCallClassInstaller';
function UpdateDriverForPlugAndPlayDevices(hwndParent: THandle; HardwareId: Pchar; FullInfPath: Pchar; InstallFlags: DWORD; bRebootRequired: PBOOL ): BOOL; stdcall;external 'newdev.dll' name 'UpdateDriverForPlugAndPlayDevicesA';
function SetupDiClassNameFromGuid(ClassGuid: PGUID; ClassName: PChar;ClassNameSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall;external 'Setupapi.dll' name 'SetupDiClassNameFromGuidA';
function SetupDiRegisterDeviceInfo(DeviceInfoSet: HDEVINFO;var DeviceInfoData: TSPDevInfoData; Flags: DWORD; CompareProc: TSPDetSigCmpProc;CompareContext: Pointer; DupDeviceInfoData: PSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiRegisterDeviceInfo';

function DisplayMsg(msg:string):integer;
begin
result := MessageBox(0,pchar(msg),'message',MB_OK);
end;

function FindExistingDevice():boolean;
var
DeviceInfoSet:HDEVINFO;
Found:boolean;
DeviceInfoData:SP_DEVINFO_DATA;
i:DWord;
DataT:DWord;
buf:pchar;
buffsize:integer;
begin
DeviceInfoSet := SetupDiGetClassDevs(nil,0,0,(DIGCF_ALLCLASSES or DIGCF_PRESENT
or DIGCF_PROFILE));
if DeviceInfoSet = nil then
exit;

Found := false;
DeviceInfoData.cbSize := sizeof(SP_DEVINFO_DATA);

i := 0;
buffsize := 10240;
getmem(buf,buffsize);
while SetupDiEnumDeviceInfo(DeviceInfoSet,i,DeviceInfoData) do
begin
inc(i);
DataT := 0;
if not SetupDiGetDeviceRegistryProperty(DeviceInfoSet,DeviceInfoData,
SPDRP_HARDWAREID,
DataT,
PByte(buf),
buffsize,
DataT) then
begin
continue;
end;

if HardwareIDs = strpas(buf) then
begin
found := true;
break;
end;
end;

if buf <> nil then
freemem(buf);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
result := found;

end;

procedure TForm1.Button1Click(Sender: TObject);
var
FileName,Drive,Path,infile,sysfile:string;
DeviceInfoSet: HDEVINFO;
ClassGUID: TGUID;
dev:SP_DEVINFO_DATA;
status:Longbool;
RebootRequired :Longbool;
err:DWord;
begin
if FindExistingDevice then
begin
DisplayMsg('Virtual Keyboard already installed');
exit;
end;

FileName := application.ExeName;
Path := ExtractFilePath(FileName);
infile := path + 'keyfdo.inf';
sysfile := path + 'VKeyFdo.sys';
if not fileexists(infile) then
begin
DisplayMsg('Can''t find .INF file');
exit;
end;
if not FileExists(sysfile) then
begin
DisplayMsg('Can''t find .sys file');
exit;
end;
DeviceInfoSet := SetupDiCreateDeviceInfoList(@KeyboardClass,0);
if (DWORD(DeviceInfoSet) = INVALID_HANDLE_VALUE) then
begin
DisplayMsg('Can''t get device infolist');
exit;
end;
dev.cbSize := sizeof(SP_DEVINFO_DATA);

status := SetupDiCreateDeviceInfo
(DeviceInfoSet,pchar(DeviceName),
KeyboardClass,pchar(DeviceName),0,DICD_GENERATE_ID,@dev);
if not status then
begin
DisplayMsg('Can''t create device');
exit;
end;

status := SetupDiRegisterDeviceInfo(DeviceInfoSet,dev,0,nil,nil,nil);
if not status then
begin
DisplayMsg('Can''t register device');
exit;
end;

status := SetupDiSetDeviceRegistryProperty
(DeviceInfoSet,dev,SPDRP_HARDWAREID,Pbyte(PChar(HardwareIds)),
(lstrlen(HardwareIds)+1+1)*sizeof(char));
if not status then
begin
err := GetLastError();
DisplayMsg('Can''t set device HardwareID'+ inttostr(err));
exit;
end;

SetupDiDestroyDeviceInfoList(DeviceInfoSet);

status := UpdateDriverForPlugAndPlayDevices(0,
HardwareIDs,pchar(infile),0,@RebootRequired);
if not status then
begin
err := GetLastError();
DisplayMsg('Can''t update device HardwareID'+ inttostr(err));
status := SetupDiCallClassInstaller(DIF_REMOVE,DeviceInfoSet,@dev);
if not status then
begin
DisplayMsg('Can''t install device HardwareID');
exit;
end;
end;

end;

end.
参考技术B 1, 用copyFile复制文件,
CopyFile('C:\\Autoexec.bat', 'A:\\Backup\\Autoexec.bat', False);

2. 可以用shellExecute加载已有的exe文件(应该也可以调用inf文件),比如运行记事本:
uses ShellApi; // 加在开头units 中
ShellExecute(Handle, 'open', 'c:\Windows\notepad.exe', nil, nil, SW_SHOWNORMAL) ;追问

1.copyfile中的.bat文件是从哪里来的??
2、shellexecute 理论上来说是可以使用inf文件 最好能给出实际代码
3、我在这之前已经将声卡的驱动备份到C:\aa文件夹中,共3个文件 1个inf文件2个sys文件
4、我使用dos代码加载inf文件屏幕只是闪了一下,我查看设备管理器发现声卡驱动还是黄色问号

追答

1。我只是举个复制文件的例子,你应该用自己需要复制的文件名,xxx.inf, yyy.sys, zzz.sys
eg. CopyFile('C:\\Program\\xxx.inf', 'C:\\xxx.inf', False);
2。实际代码已经给出了,就是
ShellExecute(Handle, 'open', 'C:\\xxx.inf', nil, nil, SW_SHOWNORMAL) ;
3,4。你自己可以试一下

追问

1、你的意思是说先复制我备份过的驱动文件到对应的系统目录然后在执行我刚复制到inf文件夹下的inf文件,这样就可以了对吗??
2、我在网上找到了些代码说只要把驱动备份的文件放到同一个文件夹中,然后通过ShellExecute()函数就可以安装 不过这个函数使用的参数有些问题,里面需要inf的入口函数。我仔细查看过系统硬件驱动的大部分inf文件 其中基本都没有‘入口节’这点让我很疑惑。

追答

shellExecute如果不行的话,试下这个,肯定可以用:

uses ShellAPI;
function InstallINF(const PathName: string; hParent: HWND): Boolean; // 建立一个方法
var
instance: HINST;
begin
instance := ShellExecute(hParent,
PChar('open'),
PChar('rundll32.exe'),
PChar('setupapi,InstallHinfSection
DefaultInstall 132 ' + PathName),
nil,
SW_HIDE) ;
Result := instance > 32;
end;

==》用法:
InstallINF('C:\XYZ.inf', 0) ;

追问

这个方法不管用
这个函数
ShellExecute(hParent,
PChar('open'),
PChar('rundll32.exe'),
PChar('setupapi,InstallHinfSection
DefaultInstall 132 ' + PathName),
nil,
SW_HIDE) ;
中的defaultinstall参数是inf文件的入口节 ,我看过几个xp系统备份出来的硬件inf驱动发现其中没有这个入口节!
不过这个函数网上很多的 ,应该有很多人用到过。

以上是关于怎么使用delphi实现电脑硬件驱动安装??的主要内容,如果未能解决你的问题,请参考以下文章

【DELPHI】如何在两台电脑间传送文件?

爱快硬路由和软路由系统有啥区别

在电脑上下载安卓驱动,怎样安装到手机里?

电脑声卡驱动怎么安装

Delphi实现电脑端微信图片文件解密

笔记本电脑没声音该怎么办