Delphi如何利用Setup API实现驱动程序自动安装

时间:2021-11-23 05:52:23
现在在做GPRS MODEM,用了一根USB数据线连接手机,在PC机上虚拟了一个串口,现在软件编写完成,可是MODEM的添加却仍然需要用户手动添加,非常麻烦。我们自己做了一个MODEM的inf文件,不知道怎么在setup过程中就把MODEM添加到USB数据线虚拟的那个串口上去。也就是如何利用Setup API实现驱动程序自动安装

5 个解决方案

#1


如果你用installshield,wise等做安装程序的话,都可自己加入脚本或定义安装后再运行指定程序或调用dll啊;

#2


问题是Setup API函数可以实现Modem的自动安装

#3


用SetupApi我不清楚
不过你可以试试另外一种方法

procedure InstallPortTalkDriver;
var
    SchSCManager:SC_HANDLE;
    schService:SC_HANDLE;
    err:DWORD;
    DriverFileName:array[0..79]of CHAR;
begin
    if (GetSystemDirectory(DriverFileName, 55)=0) then
    begin
       showmessage('PortTalk: 取System目录出错');
       exit;
    end;

    {加入驱动程序文件名}
    lstrcat(DriverFileName,'\Drivers\PortTalk.sys');
    showmessagefmt('PortTalk: 拷贝驱动程序到%s',[DriverFileName]);

    {拷贝驱动程序到System32/drivers目录,如果出错,一般是因为文件不存在。}

    if (not CopyFile('PortTalk.sys', DriverFileName, FALSE)) then
    begin
         showmessagefmt('PortTalk: 拷贝驱动程序到以下位置出错:%s'+#$D#$A+
                        '请手工拷贝到system32/driver目录',
                        [DriverFileName]);
         exit;
    end;

    {打开Service Control Manager}
    SchSCManager := OpenSCManager (nil,                   { 机器 (nil = 本机) }
                                  nil,                    { 数据库 (nil = 默认 }
                                  SC_MANAGER_ALL_ACCESS); { 访问权 }
{
SC_HANDLE OpenSCManager(
  LPCTSTR lpMachineName,   // computer name
  LPCTSTR lpDatabaseName,  // SCM database name
  DWORD dwDesiredAccess    // access type
);
}

    schService := CreateService (SchSCManager,                     { SCManager数据库 }
                                'PortTalk',                        { 服务个数 }
                                'PortTalk',                        { 显示名 }
                                SERVICE_ALL_ACCESS,                { 权限 }
                                SERVICE_KERNEL_DRIVER,             { 服务类别 }
                                SERVICE_DEMAND_START,              { 启动类别 }
                                SERVICE_ERROR_NORMAL,              { 出错控件类别 }
                                'System32\Drivers\PortTalk.sys',   { 服务二进制文件 }
                                nil,                               { 加入的组 }
                                nil,                               { 标识 }
                                nil,                               { 隶属 }
                                nil,                               { 本地帐户 }
                                nil                                { 密码 }
                                );
    {
    SC_HANDLE CreateService(
  SC_HANDLE hSCManager,       // handle to SCM database 
  LPCTSTR lpServiceName,      // name of service to start
  LPCTSTR lpDisplayName,      // display name
  DWORD dwDesiredAccess,      // type of access to service
  DWORD dwServiceType,        // type of service
  DWORD dwStartType,          // when to start service
  DWORD dwErrorControl,       // severity of service failure
  LPCTSTR lpBinaryPathName,   // name of binary file
  LPCTSTR lpLoadOrderGroup,   // name of load ordering group
  LPDWORD lpdwTagId,          // tag identifier
  LPCTSTR lpDependencies,     // array of dependency names
  LPCTSTR lpServiceStartName, // account name 
  LPCTSTR lpPassword          // account password
);
    }

    if (schService = 0) then
    begin
         err := GetLastError;
         if (err = ERROR_SERVICE_EXISTS) then
               showmessage('PortTalk: 驱动程序不存在。')
         else  showmessage('PortTalk:建立服务时发生未知的错误。');
    end
    else showmessage('PortTalk: 成功安装!');

    { 关闭Service Control Manager }
    CloseServiceHandle (schService);
end;

这是一个例程,安装完驱动以后,要启动服务

#4


多谢naughtyboy,请问SC_HANDLE为何种类型,安装驱动是否支持Modem

#5


驱动我用SetupAPI已经可以,但不知如何绑定端口,请各位多多帮忙,分数不够,可以再加

#1


如果你用installshield,wise等做安装程序的话,都可自己加入脚本或定义安装后再运行指定程序或调用dll啊;

#2


问题是Setup API函数可以实现Modem的自动安装

#3


用SetupApi我不清楚
不过你可以试试另外一种方法

procedure InstallPortTalkDriver;
var
    SchSCManager:SC_HANDLE;
    schService:SC_HANDLE;
    err:DWORD;
    DriverFileName:array[0..79]of CHAR;
begin
    if (GetSystemDirectory(DriverFileName, 55)=0) then
    begin
       showmessage('PortTalk: 取System目录出错');
       exit;
    end;

    {加入驱动程序文件名}
    lstrcat(DriverFileName,'\Drivers\PortTalk.sys');
    showmessagefmt('PortTalk: 拷贝驱动程序到%s',[DriverFileName]);

    {拷贝驱动程序到System32/drivers目录,如果出错,一般是因为文件不存在。}

    if (not CopyFile('PortTalk.sys', DriverFileName, FALSE)) then
    begin
         showmessagefmt('PortTalk: 拷贝驱动程序到以下位置出错:%s'+#$D#$A+
                        '请手工拷贝到system32/driver目录',
                        [DriverFileName]);
         exit;
    end;

    {打开Service Control Manager}
    SchSCManager := OpenSCManager (nil,                   { 机器 (nil = 本机) }
                                  nil,                    { 数据库 (nil = 默认 }
                                  SC_MANAGER_ALL_ACCESS); { 访问权 }
{
SC_HANDLE OpenSCManager(
  LPCTSTR lpMachineName,   // computer name
  LPCTSTR lpDatabaseName,  // SCM database name
  DWORD dwDesiredAccess    // access type
);
}

    schService := CreateService (SchSCManager,                     { SCManager数据库 }
                                'PortTalk',                        { 服务个数 }
                                'PortTalk',                        { 显示名 }
                                SERVICE_ALL_ACCESS,                { 权限 }
                                SERVICE_KERNEL_DRIVER,             { 服务类别 }
                                SERVICE_DEMAND_START,              { 启动类别 }
                                SERVICE_ERROR_NORMAL,              { 出错控件类别 }
                                'System32\Drivers\PortTalk.sys',   { 服务二进制文件 }
                                nil,                               { 加入的组 }
                                nil,                               { 标识 }
                                nil,                               { 隶属 }
                                nil,                               { 本地帐户 }
                                nil                                { 密码 }
                                );
    {
    SC_HANDLE CreateService(
  SC_HANDLE hSCManager,       // handle to SCM database 
  LPCTSTR lpServiceName,      // name of service to start
  LPCTSTR lpDisplayName,      // display name
  DWORD dwDesiredAccess,      // type of access to service
  DWORD dwServiceType,        // type of service
  DWORD dwStartType,          // when to start service
  DWORD dwErrorControl,       // severity of service failure
  LPCTSTR lpBinaryPathName,   // name of binary file
  LPCTSTR lpLoadOrderGroup,   // name of load ordering group
  LPDWORD lpdwTagId,          // tag identifier
  LPCTSTR lpDependencies,     // array of dependency names
  LPCTSTR lpServiceStartName, // account name 
  LPCTSTR lpPassword          // account password
);
    }

    if (schService = 0) then
    begin
         err := GetLastError;
         if (err = ERROR_SERVICE_EXISTS) then
               showmessage('PortTalk: 驱动程序不存在。')
         else  showmessage('PortTalk:建立服务时发生未知的错误。');
    end
    else showmessage('PortTalk: 成功安装!');

    { 关闭Service Control Manager }
    CloseServiceHandle (schService);
end;

这是一个例程,安装完驱动以后,要启动服务

#4


多谢naughtyboy,请问SC_HANDLE为何种类型,安装驱动是否支持Modem

#5


驱动我用SetupAPI已经可以,但不知如何绑定端口,请各位多多帮忙,分数不够,可以再加