2010-03-16 17 views
12

Inno Setup'ı kullanarak temel bir Windows hizmeti yüklemesi oluşturdum. hem yükleme hem de kaldırma düzgün çalışır.Inno Setup'ı kullanarak Windows hizmetini yükseltme

Ancak, yükseltme prosedürü ile ilgili sorun yaşıyorum. o hizmeti durdurmak için gereklidir ve sadece hizmeti tamamen güncellenmiş yürütülebilir hedef klasöre yerleştirilebilir durduktan sonra servis yürütülebilir yükseltmek amacıyla

.

nasıl hizmet durdurma komutunu çalıştırmak ve dosya dağıtım aşaması başlamadan önce hizmeti tamamen durdurulması için bekleyebilir?

cevap

5

iki parça Buna vardır:

  1. Inno Setup ile oluşturulan bir yükleyici başlatmak ve hizmetlerini nasıl durdurabilirim, nasıl bunları oluşturmak ve silebilir, nasıl onun başlangıç ​​modunu değiştirebilirsiniz? Tam olarak bu amaç için yazılmış bu collection of routines sağlanan yardımcı işlevlerini kullanarak

    . Inno Setup'ın Ansi sürümü için yazılmıştır, bu yüzden API işlevi içe aktarma ve PChar parametre türlerinde değişiklikler gerekli olacaktır, ancak başlamanız gerekir. Yeni dosya sürümü kopyalanır önce

  2. Nasıl varolan hizmet durdurulabilir ?

    Temel olarak bunu yapmanın iki yolu vardır. Hizmeti durdurmak için yukarıda belirtilen işlevleri yürütmek için Pascal komut dosyası kullanırsanız, yalnızca etkinlik işlevlerinden birinde mi yapılacağına veya Check parametresiyle çağrılacak özel bir işlevde yapılıp yapılmayacağına karar vermeniz gerekir. Hizmet çalıştırılabilir için dosya girişi. Kesinlikle bunu eskiden yapardım, böylece hizmetin başarıyla durdurulup durdurulmadığını kontrol edebilir ve kurulum başarısız olduğunda gerçekte başlatmayı engelleyebilir.

    CurStepChanged() ve NextButtonClick() olay işlevlerini, bir sonraki adımı önlemeniz gerekip gerekmediğine bağlı olarak bakmalısınız. Inno Kurulum örnekleri her iki fonksiyonun kullanımını gösterir. Aşağıda

16

kod aşağıdaki sayfada geliyor:
http://www.vincenzo.net/isxkb/index.php?title=Service_-_Functions_to_Start%2C_Stop%2C_Install%2C_Remove_a_Service

Ancak, çalışması için küçük bir düzeltme uygulamak zorunda kaldı. Ben aslında de 2010 yılında kodunu bu cevabı yayınlanmıştır

Not sayfası yukarıdaki 2011 yılında güncellendi, bu yüzden görülmeye değer olabilir.

Bu kodu, yükleyicimde #include olarak kullanıyorum. Inno Kurulumu ANSI'da derlenmiştir.
Tüm external bildirimlerinde [email protected] ile [email protected]'u değiştirerek Inno Kurulumu'nun Unicode sürümü için çalışabilir (bunu belirtmek için JeroenWiertPluimers teşekkür ederiz). Ayrıca, StartService ve StopService'un sadece bir başlatma/durdurma sinyali göndermesini sağladığını, ancak hizmetin durmuş durumun çalışmasını beklemesini beklemediğini unutmayın.Pascal Script Sleep() işlevi ile birlikte IsServiceRunning kullanarak, hizmetin çalışmasını bekleyecek kodu yapılandırabilirsiniz. Ya da sadece Sleep() önceden belirlenmiş bir saniye.

kod bu fonksiyonları uygulayan:

function IsServiceInstalled(ServiceName: string) : boolean; 
function IsServiceRunning(ServiceName: string) : boolean; 
function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean; 
function RemoveService(ServiceName: string) : boolean; 
function StartService(ServiceName: string) : boolean; 
function StopService(ServiceName: string) : boolean; 
function SetupService(service, port, comment: string) : boolean; 

gerçek kod: Inno Setup 5.5.0 itibariyle

type 
    SERVICE_STATUS = record 
     dwServiceType    : cardinal; 
     dwCurrentState    : cardinal; 
     dwControlsAccepted   : cardinal; 
     dwWin32ExitCode    : cardinal; 
     dwServiceSpecificExitCode : cardinal; 
     dwCheckPoint    : cardinal; 
     dwWaitHint     : cardinal; 
    end; 
    HANDLE = cardinal; 

const 
    SERVICE_QUERY_CONFIG  = $1; 
    SERVICE_CHANGE_CONFIG  = $2; 
    SERVICE_QUERY_STATUS  = $4; 
    SERVICE_START    = $10; 
    SERVICE_STOP    = $20; 
    SERVICE_ALL_ACCESS   = $f01ff; 
    SC_MANAGER_ALL_ACCESS  = $f003f; 
    SERVICE_WIN32_OWN_PROCESS = $10; 
    SERVICE_WIN32_SHARE_PROCESS = $20; 
    SERVICE_WIN32    = $30; 
    SERVICE_INTERACTIVE_PROCESS = $100; 
    SERVICE_BOOT_START   = $0; 
    SERVICE_SYSTEM_START  = $1; 
    SERVICE_AUTO_START   = $2; 
    SERVICE_DEMAND_START  = $3; 
    SERVICE_DISABLED   = $4; 
    SERVICE_DELETE    = $10000; 
    SERVICE_CONTROL_STOP  = $1; 
    SERVICE_CONTROL_PAUSE  = $2; 
    SERVICE_CONTROL_CONTINUE = $3; 
    SERVICE_CONTROL_INTERROGATE = $4; 
    SERVICE_STOPPED    = $1; 
    SERVICE_START_PENDING  = $2; 
    SERVICE_STOP_PENDING  = $3; 
    SERVICE_RUNNING    = $4; 
    SERVICE_CONTINUE_PENDING = $5; 
    SERVICE_PAUSE_PENDING  = $6; 
    SERVICE_PAUSED    = $7; 

{ nt based service utilities } 
function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE; 
external '[email protected] stdcall'; 

function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE; 
external '[email protected] stdcall'; 

function CloseServiceHandle(hSCObject :HANDLE): boolean; 
external '[email protected] stdcall'; 

function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal; 
external '[email protected] stdcall'; 

function DeleteService(hService :HANDLE): boolean; 
external '[email protected] stdcall'; 

function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean; 
external '[email protected] stdcall'; 

function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean; 
external '[email protected] stdcall'; 

function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean; 
external '[email protected] stdcall'; 

function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean; 
external '[email protected] stdcall'; 

function GetLastError() : cardinal; 
external '[email protected] stdcall'; 

function OpenServiceManager() : HANDLE; 
begin 
    if UsingWinNT() = true then begin 
     Result := OpenSCManager('','',SC_MANAGER_ALL_ACCESS); 
     if Result = 0 then 
      MsgBox('the servicemanager is not available', mbError, MB_OK) 
    end 
    else begin 
      MsgBox('only nt based systems support services', mbError, MB_OK) 
      Result := 0; 
    end 
end; 

function IsServiceInstalled(ServiceName: string) : boolean; 
var 
    hSCM : HANDLE; 
    hService: HANDLE; 
begin 
    hSCM := OpenServiceManager(); 
    Result := false; 
    if hSCM <> 0 then begin 
     hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_CONFIG); 
     if hService <> 0 then begin 
      Result := true; 
      CloseServiceHandle(hService) 
     end; 
     CloseServiceHandle(hSCM) 
    end 
end; 

function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean; 
var 
    hSCM : HANDLE; 
    hService: HANDLE; 
begin 
    hSCM := OpenServiceManager(); 
    Result := false; 
    if hSCM <> 0 then begin 
     hService := CreateService(hSCM,ServiceName,DisplayName,SERVICE_ALL_ACCESS,ServiceType,StartType,0,FileName,'',0,'','',''); 
     if hService <> 0 then begin 
      Result := true; 
      { Win2K & WinXP supports additional description text for services } 
      if Description<> '' then 
       RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName,'Description',Description); 
      CloseServiceHandle(hService) 
     end; 
     CloseServiceHandle(hSCM) 
    end 
end; 

function RemoveService(ServiceName: string) : boolean; 
var 
    hSCM : HANDLE; 
    hService: HANDLE; 
begin 
    hSCM := OpenServiceManager(); 
    Result := false; 
    if hSCM <> 0 then begin 
     hService := OpenService(hSCM,ServiceName,SERVICE_DELETE); 
     if hService <> 0 then begin 
      Result := DeleteService(hService); 
      CloseServiceHandle(hService) 
     end; 
     CloseServiceHandle(hSCM) 
    end 
end; 

function StartService(ServiceName: string) : boolean; 
var 
    hSCM : HANDLE; 
    hService: HANDLE; 
begin 
    hSCM := OpenServiceManager(); 
    Result := false; 
    if hSCM <> 0 then begin 
     hService := OpenService(hSCM,ServiceName,SERVICE_START); 
     if hService <> 0 then begin 
      Result := StartNTService(hService,0,0); 
      CloseServiceHandle(hService) 
     end; 
     CloseServiceHandle(hSCM) 
    end; 
end; 

function StopService(ServiceName: string) : boolean; 
var 
    hSCM : HANDLE; 
    hService: HANDLE; 
    Status : SERVICE_STATUS; 
begin 
    hSCM := OpenServiceManager(); 
    Result := false; 
    if hSCM <> 0 then begin 
     hService := OpenService(hSCM,ServiceName,SERVICE_STOP); 
     if hService <> 0 then begin 
      Result := ControlService(hService,SERVICE_CONTROL_STOP,Status); 
      CloseServiceHandle(hService) 
     end; 
     CloseServiceHandle(hSCM) 
    end; 
end; 

function IsServiceRunning(ServiceName: string) : boolean; 
var 
    hSCM : HANDLE; 
    hService: HANDLE; 
    Status : SERVICE_STATUS; 
begin 
    hSCM := OpenServiceManager(); 
    Result := false; 
    if hSCM <> 0 then begin 
     hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_STATUS); 
     if hService <> 0 then begin 
      if QueryServiceStatus(hService,Status) then begin 
       Result :=(Status.dwCurrentState = SERVICE_RUNNING) 
      end; 
      CloseServiceHandle(hService) 
      end; 
     CloseServiceHandle(hSCM) 
    end 
end; 
+4

Yanıtınız gibi görünen bazı kodları devraldım. Kaynaktan da bahsetmediler, ne de * ANSI *, “OpenSCManager” tarafından atılan "ERROR_INVALID_NAME" aka 123 (0x7B) hatası, "A" ile "W @" ile değiştirilerek çözülebiliyordu. Inno Setup * Unicode * çalıştırırken "harici" bildirimleri. –

6

, CloseApplications ve RestartApplications direktifleri artık kullanılabilir. Bu seçenekler kullanımdaki dosyaları tespit eder ve bunları kullanarak uygulamaları kapatır.

+0

Bu hizmetler için çalışmaz bence ... – Roddy

+0

CloseApplications ve RestartApplications [Windows Yeniden Başlatma Yöneticisi'ni (http://msdn.microsoft.com/en-us/library/windows/desktop/aa373524.aspx) kullanın, GUI, Console ve ** service ** uygulamalarını destekler. – jachguate

+0

Bir hizmet için çalışmak üzere CloseApplications alamadım - neden olmasın – pogorman

2

Belirli bir hizmeti durduran, yükleyen, yükleyen ve başlatan bir toplu iş dosyası kullanıyorum, sadece tüm dosyalar kopyalandıktan sonra innosetup kullanarak batchfile'ı arıyorum.

[Run] 
Filename: "{app}\Scripts\installwindowsService.bat"; Parameters: "{app}"; Flags: runhidden 

benim toplu dosya

net stop MyService 

%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u MyService.exe 

%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\installutil.exe MyService.exe /unattended 

net start MyService 

Bu bir cazibe gibi çalışır ve çok basittir aşağıdaki komutları koydu. İlk kurulum veya güncelleme için kullanılabilir. Umarım size yardımcı olur.

İlgili konular