inno setup 打包相关技术要点

来源:互联网 发布:c语言中进制转换 编辑:程序博客网 时间:2024/06/06 09:54

(1)关于软件版本信息修改,通过修改注册表来实现 具体代码如下:

  //***************版本信息*******************//


// 升级包通过修改注册表,更改控制面板中已安装软件的版本信息
// added by houqd 2013/12/18
function updateVersion():Boolean;
var
   ResultStr:String;
   nDisplayName:String;
   nVersion:String;
begin


   Result:=true;
   nDisplayName:='{#PreDisplayName}'+'{#MyAppVersion}';
   nVersion:='{#MyAppVersion}';


   // 修改版本信息
   if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EF28CF10-3990-4A7C-9B06-C0D4F9FB190E}_is1','DisplayName',ResultStr) then
   begin
      if nDisplayName <> ResultStr then
      begin
          RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EF28CF10-3990-4A7C-9B06-C0D4F9FB190E}_is1', 'DisplayName', nDisplayName);
      end;
   end;
   
   if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EF28CF10-3990-4A7C-9B06-C0D4F9FB190E}_is1','DisplayVersion',ResultStr) then
   begin
      if nVersion <> ResultStr then
      begin
          RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EF28CF10-3990-4A7C-9B06-C0D4F9FB190E}_is1', 'DisplayVersion', nVersion)
      end;
   end;
end;

//***********************************************//

(2)安装服务,是通过调用相关系统函数,即innosetup 相关函数,代码如下:

  /////////////////////////////////////////////////////////////////////////
type  
_SERVICE_STATUS = record  
dwServiceType: Longword;  
dwCurrentState: Longword;  
dwControlsAccepted: Longword;  
dwWin32ExitCode: Longword;  
dwServiceSpecificExitCode: Longword;  
dwCheckPoint: Longword;  
dwWaitHint: Longword;  
end;  
const  
NO_ERROR = 0;  
STANDARD_RIGHTS_REQUIRED = $F0000;  
//  
// Service Control Manager object specific access types  
//  
SC_MANAGER_CONNECT = $0001;  
SC_MANAGER_CREATE_SERVICE = $0002;  
SC_MANAGER_ENUMERATE_SERVICE = $0004;  
SC_MANAGER_LOCK = $0008;  
SC_MANAGER_QUERY_LOCK_STATUS = $0010;  
SC_MANAGER_MODIFY_BOOT_CONFIG = $0020;  
SC_MANAGER_ALL_ACCESS =  
(STANDARD_RIGHTS_REQUIRED +  
SC_MANAGER_CONNECT +  
SC_MANAGER_CREATE_SERVICE +  
SC_MANAGER_ENUMERATE_SERVICE +  
SC_MANAGER_LOCK +  
SC_MANAGER_QUERY_LOCK_STATUS +  
SC_MANAGER_MODIFY_BOOT_CONFIG);  
//  
// No change constant  
//  
SERVICE_NO_CHANGE = $FFFFFFFF;  
//  
// Service Types (Bit Mask)  
//  
SERVICE_KERNEL_DRIVER = $00000001;  
SERVICE_FILE_SYSTEM_DRIVER = $00000002;  
SERVICE_ADAPTER = $00000004;  
SERVICE_RECOGNIZER_DRIVER = $00000008;  
SERVICE_DRIVER =  
(SERVICE_KERNEL_DRIVER +  
SERVICE_FILE_SYSTEM_DRIVER +  
SERVICE_RECOGNIZER_DRIVER);  
SERVICE_WIN32_OWN_PROCESS = $00000010;  
SERVICE_WIN32_SHARE_PROCESS = $00000020;  
SERVICE_WIN32 =  
(SERVICE_WIN32_OWN_PROCESS +  
SERVICE_WIN32_SHARE_PROCESS);  
SERVICE_INTERACTIVE_PROCESS = $00000100;  
SERVICE_TYPE_ALL =  
(SERVICE_WIN32 +  
SERVICE_ADAPTER +  
SERVICE_DRIVER +  
SERVICE_INTERACTIVE_PROCESS);  
//  
// Start Type  
//  
SERVICE_BOOT_START = $00000000;  
SERVICE_SYSTEM_START = $00000001;  
SERVICE_AUTO_START = $00000002;  
SERVICE_DEMAND_START = $00000003;  
SERVICE_DISABLED = $00000004;  
//  
// Error control type  
//  
SERVICE_ERROR_IGNORE = $00000000;  
SERVICE_ERROR_NORMAL = $00000001;  
SERVICE_ERROR_SEVERE = $00000002;  
SERVICE_ERROR_CRITICAL = $00000003;  
//  
// Service object specific access type  
//  
SERVICE_QUERY_CONFIG = $0001;  
SERVICE_CHANGE_CONFIG = $0002;  
SERVICE_QUERY_STATUS = $0004;  
SERVICE_ENUMERATE_DEPENDENTS = $0008;  
SERVICE_START= $0010;  
SERVICE_STOP= $0020;  
SERVICE_PAUSE_CONTINUE = $0040;  
SERVICE_INTERROGATE = $0080;  
SERVICE_USER_DEFINED_CONTROL = $0100;  
SERVICE_ALL_ACCESS =  
(STANDARD_RIGHTS_REQUIRED +  
SERVICE_QUERY_CONFIG +  
SERVICE_CHANGE_CONFIG +  
SERVICE_QUERY_STATUS +  
SERVICE_ENUMERATE_DEPENDENTS +  
SERVICE_START +  
SERVICE_STOP +  
SERVICE_PAUSE_CONTINUE +  
SERVICE_INTERROGATE +  
SERVICE_USER_DEFINED_CONTROL);  
//  
// Controls  
//  
SERVICE_CONTROL_STOP = $00000001;  
SERVICE_CONTROL_PAUSE = $00000002;  
SERVICE_CONTROL_CONTINUE = $00000003;  
SERVICE_CONTROL_INTERROGATE = $00000004;  
//  
// Status  
//  
SERVICE_CONTINUE_PENDING = $00000005;  
SERVICE_PAUSE_PENDING = $00000006;  
SERVICE_PAUSED = $00000007;  
SERVICE_RUNNING = $00000004;  
SERVICE_START_PENDING = $00000002;  
SERVICE_STOP_PENDING = $00000003;  
SERVICE_STOPPED = $00000001;  
//  
// Error codes  
//  
ERROR_DEPENDENT_SERVICES_RUNNING = 1051;  
ERROR_INVALID_SERVICE_CONTROL = 1052;  
ERROR_SERVICE_REQUEST_TIMEOUT = 1053;  
ERROR_SERVICE_NO_THREAD = 1054;  
ERROR_SERVICE_DATABASE_LOCKED = 1055;  
ERROR_SERVICE_ALREADY_RUNNING = 1056;  
ERROR_INVALID_SERVICE_ACCOUNT = 1057;  
ERROR_SERVICE_DISABLED = 1058;  
ERROR_CIRCULAR_DEPENDENCY = 1059;  
ERROR_SERVICE_DOES_NOT_EXIST = 1060;  
ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061;  
ERROR_SERVICE_NOT_ACTIVE = 1062;  
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = 1063;  
ERROR_EXCEPTION_IN_SERVICE = 1064;  
ERROR_DATABASE_DOES_NOT_EXIST = 1065;  
ERROR_SERVICE_SPECIFIC_ERROR = 1066;  
ERROR_PROCESS_ABORTED = 1067;  
ERROR_SERVICE_DEPENDENCY_FAIL = 1068;  
ERROR_SERVICE_LOGON_FAILED = 1069;  
ERROR_SERVICE_START_HANG = 1070;  
ERROR_INVALID_SERVICE_LOCK = 1071;  
ERROR_SERVICE_MARKED_FOR_DELETE = 1072;  
ERROR_SERVICE_EXISTS = 1073;  
function OpenSCManager(  
lpMachineName: string;   
lpDatabaseName: string;   
dwDesiredAccess: Longword): Longword;  
external 'OpenSCManagerA@advapi32.dll stdcall';  
//  
// lpServiceName is the service name, not the service display name  
//  
function OpenService(  
hSCManager: Longword;   
lpServiceName: string;   
dwDesiredAccess: Longword): Longword;  
external 'OpenServiceA@advapi32.dll stdcall';  
function StartService(  
hService: Longword;  
dwNumServiceArgs: Longword;   
lpServiceArgVectors: PChar): Longword;  
external 'StartServiceA@advapi32.dll stdcall';  
function CloseServiceHandle(hSCObject: Longword): Longword;  
external 'CloseServiceHandle@advapi32.dll stdcall';  
function ControlService(  
hService: Longword;  
dwControl: Longword;   
var lpServiceStatus: _SERVICE_STATUS): Longword;  
external 'ControlService@advapi32.dll stdcall';  
function CreateService(hSCManager: Longword;  
lpServiceName: string;  
lpDisplayName: string;  
dwDesiredAccess: Longword;  
dwServiceType: Longword;  
dwStartType: Longword;  
dwErrorControl: Longword;  
lpBinaryPathName: string;  
lpLoadOrderGroup: string;  
lpdwTagId: Longword;  
lpDependencies: string;  
lpServiceStartName: string;  
lpPassword: string): Longword;  
external 'CreateServiceA@advapi32.dll stdcall';  
function DeleteService(hService: Longword): Longword;  
external 'DeleteService@advapi32.dll stdcall';  
function ChangeServiceConfig(  
hService: Longword;  
dwServiceType: Longword;  
dwStartType: Longword;  
dwErrorControl: Longword;  
lpBinaryPathName: PChar;  
lpLoadOrderGroup: PChar;  
lpdwTagId: Longword;  
lpDependencies: PChar;  
lpServiceStartName: PChar;  
lpPassword: PChar;  
lpDisplayName: PChar): Longword;  
external 'ChangeServiceConfigA@advapi32.dll stdcall';  
function LockServiceDatabase(hSCManager: Longword): Longword;  
external 'LockServiceDatabase@advapi32.dll stdcall';  
function UnlockServiceDatabase(ScLock: Longword): Longword;  
external 'UnlockServiceDatabase@advapi32.dll stdcall';  


function SimpleCreateService(  
AServiceName,  
ADisplayName,   
AFileName: string;  
AStartType: Longword;  
AUser, APassword: string;   
Interactive: Boolean;   
IgnoreExisting: Boolean): Boolean;  
var  
SCMHandle: Longword;  
ServiceHandle: Longword;  
ServiceType: Longword;  
Error: Integer;  
begin  
Result := False;  
ServiceType := SERVICE_WIN32_OWN_PROCESS;  
try  
SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
if SCMHandle = 0 then  
RaiseException('OpenSCManager@SimpleCreateService: ' + AServiceName + ' ' +   
SysErrorMessage(DLLGetLastError));  
try  
if AUser = '' then  
begin  
if Interactive then  
ServiceType := ServiceType + SERVICE_INTERACTIVE_PROCESS;  
APassword := '';  
end;  
ServiceHandle := CreateService(SCMHandle, AServiceName, ADisplayName,   
SERVICE_ALL_ACCESS, ServiceType, AStartType, SERVICE_ERROR_NORMAL,   
AFileName, '', 0, '', AUser, APassword);  
if ServiceHandle = 0 then  
begin  
Error := DLLGetLastError;  
if IgnoreExisting and (Error = ERROR_SERVICE_EXISTS) then  
Exit  
else  
RaiseException('CreateService@SimpleCreateService: ' + AServiceName +   
' ' + SysErrorMessage(Error));  
end;  
Result := True;  
finally  
if ServiceHandle <> 0 then  
CloseServiceHandle(ServiceHandle);  
end;  
finally  
if SCMHandle <> 0 then  
CloseServiceHandle(SCMHandle);  
end;  
end; 






function WaitForService(ServiceHandle: Longword; AStatus: Longword): Boolean;  
var  
   PendingStatus: Longword;  
   ServiceStatus: _SERVICE_STATUS;  
   Error: Integer;     begin  
    Result := False;  
    case AStatus of  
    SERVICE_RUNNING: PendingStatus := SERVICE_START_PENDING;  
    SERVICE_STOPPED: PendingStatus := SERVICE_STOP_PENDING;     end;  
   repeat  
    if ControlService(ServiceHandle, SERVICE_CONTROL_INTERROGATE, ServiceStatus) = 0 then    begin  
    Error := DLLGetLastError;  
    RaiseException('ControlService@WaitForService: ' + SysErrorMessage(Error));    end;  
   if ServiceStatus.dwWin32ExitCode <> 0 then  
   Break;  
   Result := ServiceStatus.dwCurrentState = AStatus;  
   if not Result and (ServiceStatus.dwCurrentState = PendingStatus) then  
   Sleep(ServiceStatus.dwWaitHint)  
   else  
   Break;  
   until Result;  
end;  






procedure SimpleStopService(AService: string; Wait, IgnoreStopped: Boolean);  
var  
    ServiceStatus: _SERVICE_STATUS;  
    SCMHandle: Longword;  
    ServiceHandle: Longword;  
    Error: Integer;  
begin  
   try  
      SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
   if SCMHandle = 0 then  
      RaiseException('OpenSCManager@SimpleStopService: ' + AService + ' ' +   
      SysErrorMessage(DLLGetLastError));  
  try  
      ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);  
   if ServiceHandle = 0 then  
      RaiseException('OpenService@SimpleStopService: ' + AService + ' ' +   
      SysErrorMessage(DLLGetLastError));  
  try  
   if ControlService(ServiceHandle, SERVICE_CONTROL_STOP, ServiceStatus) = 0 then  
  begin  
   Error := DLLGetLastError;  
   if IgnoreStopped and (Error = ERROR_SERVICE_NOT_ACTIVE) then  
   Exit  
   else  
      RaiseException('ControlService@SimpleStopService: ' + AService + ' ' +   
      SysErrorMessage(Error));  
   if Wait then  
      WaitForService(ServiceHandle, SERVICE_STOPPED);  
  end;  
  finally  
   if ServiceHandle <> 0 then  
      CloseServiceHandle(ServiceHandle);  
  end;  
  finally  
  if SCMHandle <> 0 then  
  CloseServiceHandle(SCMHandle);  
  end;  
  except  
  ShowExceptionMessage;  
end;  
end;  






procedure SimpleStartService(AService: string; Wait, IgnoreStarted: Boolean);  
var  
SCMHandle: Longword;  
ServiceHandle: Longword;  
Error: Integer;  
begin  
try  
SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
if SCMHandle = 0 then  
RaiseException('OpenSCManager@SimpleStartService: ' + AService + ' ' +  
SysErrorMessage(DLLGetLastError));  
try  
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);  
if ServiceHandle = 0 then  
RaiseException('OpenService@SimpleStartService: ' + AService + ' ' +   
SysErrorMessage(DLLGetLastError));  
try  
if StartService(ServiceHandle, 0, '') = 0 then  
begin  
Error := DLLGetLastError;  
if IgnoreStarted and (Error = ERROR_SERVICE_ALREADY_RUNNING) then  
Exit  
else  
RaiseException('StartService@SimpleStartService: ' + AService + ' ' +   
SysErrorMessage(Error));  
if Wait then  
begin  
WaitForService(ServiceHandle, SERVICE_RUNNING);  
end;  
end;  
finally  
if ServiceHandle <> 0 then  
CloseServiceHandle(ServiceHandle);  
end;  
finally  
if SCMHandle <> 0 then  
CloseServiceHandle(SCMHandle);  
end;  
except  
ShowExceptionMessage;  
end;  
end;  






procedure SimpleDeleteService(AService: string);  
var  
SCMHandle: Longword;  
ServiceHandle: Longword;  
begin  
try  
SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
if SCMHandle = 0 then  
RaiseException('OpenSCManager@SimpleDeleteService: ' + AService + ' ' +   
SysErrorMessage(DLLGetLastError));  
try  
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);  
if ServiceHandle = 0 then  
RaiseException('OpenService@SimpleDeleteService: ' + AService + ' ' +   
SysErrorMessage(DLLGetLastError));  
try  
if DeleteService(ServiceHandle) = 0 then  
RaiseException('StartService@SimpleDeleteService: ' + AService + ' ' +   
SysErrorMessage(DLLGetLastError));  
finally  
if ServiceHandle <> 0 then  
CloseServiceHandle(ServiceHandle);  
end;  
finally  
if SCMHandle <> 0 then  
CloseServiceHandle(SCMHandle);  
end;  
except  
ShowExceptionMessage;  
end;                           
end;  




procedure SimpleSetServiceStartup(AService: string; AStartupType: Longword);  
var  
SCMHandle: Longword;  
ServiceHandle: Longword;  
begin  
try  
SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
if SCMHandle = 0 then  
RaiseException('SimpleSetServiceStartup@OpenSCManager: ' + AService + ' ' +   
SysErrorMessage(DLLGetLastError));  
try  
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);  
if ServiceHandle = 0 then  
RaiseException('SimpleSetServiceStartup@OpenService: ' + AService + ' ' +   
SysErrorMessage(DLLGetLastError));  
try  
if ChangeServiceConfig(ServiceHandle, SERVICE_NO_CHANGE, AStartupType, SERVICE_NO_CHANGE,  
'', '', 0, '', '', '', '') = 0 then  
RaiseException('SimpleSetServiceStartup@SetServiceStartup: ' + AService + ' ' +  
SysErrorMessage(DLLGetLastError));  
finally  
if ServiceHandle <> 0 then  
CloseServiceHandle(ServiceHandle);  
end;  
finally  
if SCMHandle <> 0 then  
CloseServiceHandle(SCMHandle);  
end;  
except  
ShowExceptionMessage;  
end;  
end;  






function ServiceExists(AService: string): Boolean;  
var  
   SCMHandle: Longword;  
   ServiceHandle: Longword;  
   Error: Integer;  
begin  
   try  
     SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
 if SCMHandle = 0 then  
        RaiseException('OpenSCManager@ServiceExists: ' + AService + ' ' +   
        SysErrorMessage(DLLGetLastError));  
   try  
     ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);  
   try  
     if ServiceHandle = 0 then  
     begin  
     Error := DLLGetLastError;  
     if Error = ERROR_SERVICE_DOES_NOT_EXIST then  
        Result := False  
     else  
        RaiseException('OpenService@ServiceExists: ' + AService + ' ' +   
        SysErrorMessage(Error));  
     end  
  else  
     Result := True;  
     finally  
     if ServiceHandle <> 0 then  
     CloseServiceHandle(ServiceHandle);  
     end; 
      
     finally  
     if SCMHandle <> 0 then  
     CloseServiceHandle(SCMHandle);  
     end;       except  
     ShowExceptionMessage;  
  end;  
end;  
                                                    




function SimpleQueryService(AService: string): Longword;  
    var  
    ServiceStatus: _SERVICE_STATUS;  
    SCMHandle: Longword;  
    ServiceHandle: Longword;  
    Error: Integer;  
  begin  
    Result := 0;  
    try  
       SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);  
       if SCMHandle = 0 then  
       RaiseException('OpenSCManager@SimpleQueryService: ' + AService + ' ' +   
       SysErrorMessage(DLLGetLastError));  
    try  
      ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);  
      if ServiceHandle = 0 then  
      RaiseException('OpenService@SimpleQueryService: ' + AService + ' ' +   
      SysErrorMessage(DLLGetLastError));  
   try  
      if ControlService(ServiceHandle, SERVICE_CONTROL_INTERROGATE, ServiceStatus) = 0 then  
      begin  
         Error := DLLGetLastError;  
         RaiseException('ControlService@SimpleQueryService: ' + AService + ' ' +   
         SysErrorMessage(Error));  
      end;  
        Result := ServiceStatus.dwCurrentState;  
     finally  
        if ServiceHandle <> 0 then  
        CloseServiceHandle(ServiceHandle);  
     end;  
     finally  
        if SCMHandle <> 0 then  
        CloseServiceHandle(SCMHandle);  
     end;  
   except  
       ShowExceptionMessage;  
   end;  
end;



以上服务创建需要通过系统函数DeinitializeSetup来调用,这个函数在即使用户在任何内容安装之前退出安装程序时也会调用。

(3)文件卸载

//删除所有配置文件以达到干净卸载的目的
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
     if CurUninstallStep = usUninstall then
     if MsgBox('您是否要删除用户配置信息?', mbConfirmation, MB_YESNO) = IDYES then


//删除 {app} 文件夹及其中所有文件
       DelTree(ExpandConstant('{app}'), True, True, True);end;

(4)在注册表中运行启动函数

[Registry]
;本段处理程序在注册表中的键值;启动托盘程序Root:HKLM;Subkey:"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";ValueType: string; ValueName:"FWToolsTray";ValueData:"{app}\Tools\FWToolsTray.exe";  


以上就是需要注意的几个地方!

第一次发文章,也是刚刚开始学inno setup 如果有错误请大家指出来,希望能与大家共同进步!


  

0 0
原创粉丝点击