2010-08-08 12 views
13

Ho un servizio di Windows, costruito utilizzando C#, che viene installato tramite un progetto di installazione VS2008, e sto avendo un paio di problemi che si verificano con il processo di disinstallazione:Modo corretto per disinstallare un servizio di Windows?

Il servizio non viene arrestato prima di disinstallare

Quando viene eseguita la routine di disinstallazione, viene generato un errore relativo ai file in uso. Se fai clic su Continua, il programma di installazione viene completato correttamente, ma il servizio viene comunque visualizzato nell'elenco, pertanto non viene disinstallato correttamente.

(Al momento, devo ricorrere all'eliminazione manuale utilizzando sc delete servicename).

Sto cercando di interrompere il servizio prima di disinstallare utilizzando il seguente codice, ma non sembra essere entrata in vigore:

protected override void OnBeforeUninstall(IDictionary savedState) 
{ 
    base.OnBeforeUninstall(savedState); 
    ServiceController serviceController = new ServiceController(MyInstaller.ServiceName); 
    serviceController.Stop(); 
} 

Quando viene chiamato questo codice, e come posso arrestare il servizio prima della disinstallazione?

cartella di installazione non eliminato dopo la disinstallazione

L'applicazione crea anche alcuni file al suo interno cartella di installazione quando viene eseguito. Dopo la disinstallazione, la cartella di installazione (C: \ Programmi \ MyApp) non viene eliminata e contiene i file creati dall'applicazione, sebbene tutti gli altri file che sono stati effettivamente installati dal programma di installazione siano stati eliminati correttamente.

È possibile che il processo di disinstallazione elimini la cartella di installazione, inclusi tutti i file generati all'interno di tale cartella e, in caso affermativo, come?

Grazie.

risposta

6

A beneficio di tutti coloro che cercano una risposta a questi problemi:

Il servizio non viene arrestato prima di disinstallare

non hanno ancora trovato una soluzione a questo.

cartella di installazione non eliminato dopo la disinstallazione

Il metodo OnAfterUninstall nel programma di installazione progetto deve essere ignorata, e tutti i file creati deve essere cancellata. La cartella del programma di installazione dell'applicazione viene automaticamente cancellata se non contiene alcun file dopo questo passaggio.

protected override void OnAfterUninstall(IDictionary savedState) 
{ 
    base.OnAfterUninstall(savedState); 

    string targetDir = Context.Parameters["TargetDir"]; // Must be passed in as a parameter 

    if (targetDir.EndsWith("|")) 
     targetDir = targetDir.Substring(0, targetDir.Length-1); 

    if (!targetDir.EndsWith("\\")) 
     targetDir += "\\"; 

    if (!Directory.Exists(targetDir)) 
    { 
     Debug.WriteLine("Target dir does not exist: " + targetDir); 
     return; 
    } 

    string[] files = new[] { "File1.txt", "File2.tmp", "File3.doc" }; 
    string[] dirs = new[] { "Logs", "Temp" }; 

    foreach (string f in files) 
    { 
     string path = Path.Combine(targetDir, f); 

     if (File.Exists(path)) 
      File.Delete(path); 
    } 

    foreach (string d in dirs) 
    { 
     string path = Path.Combine(targetDir, d); 

     if (Directory.Exists(d)) 
      Directory.Delete(d, true); 
    } 

    // At this point, all generated files and directories must be deleted. 
    // The installation folder will be removed automatically. 
} 

Ricordate, la cartella di installazione deve essere passato come parametro:

  • clic destro sul progetto di installazione, quindi scegliere Visualizza -> azioni personalizzate
  • Le azioni personalizzate si apriranno nella vostra finestra principale. Fai clic con il pulsante destro del mouse su "Output primario da XXX" sotto il nodo Disinstalla e seleziona "Finestra Proprietà"
  • Nella finestra delle proprietà, in CustomActionData, inserisci quanto segue: /TargetDir = "[TARGETDIR] |" (notare il tubo alla fine, non rimuoverlo).

Questo passerà la cartella di installazione come parametro alla routine di disinstallazione in modo da sapere dove è stata installata l'applicazione e può eliminare i file e le cartelle generati.

+1

Vorrei una risposta al tuo primo problema da solo. Si prega di postarlo se mai capirlo. – PaulH

+0

@Mun Ho aggiunto [questo codice] (http://www.primordialcode.com/blog/post/msi-simple-delete-files-custom-action) al metodo 'OnAfterUninstall', ma dice che il File è in corso utilizzato da un altro processo o accesso negato –

1

Molto probabilmente il servizio richiede solo un po 'di tempo per spegnersi, e si continua prima che il servizio si sia fermato completamente. Prova a chiamare il metodo WaitForStatus(ServiceControllerStatus).

In questo modo il codice attenderà fino a quando il servizio elabora il messaggio "stop" e si arresta. Una volta che il servizio è stato effettivamente spento, non sarà più in grado di aggrapparsi a qualsiasi handle di file.

+1

Ho provato questo, senza fortuna. Alcuni ulteriori debug rivelano che nessuno dei metodi di disinstallazione (OnBeforeUninstall, OnAfterUninstall, Uninstall) viene effettivamente chiamato prima che Windows visualizzi l'avviso "File in uso", che sarebbe il motivo per cui il servizio non viene arrestato. – Mun

+0

Ah, ok. Una domanda diversa, quando dici "file creati dall'applicazione", vuoi dire che i file non sono presenti quando l'installatore completa l'installazione, piuttosto creato mentre l'applicazione viene eseguita? Questi file potrebbero dover essere ripuliti manualmente (dopo l'installazione?) ... molti installatori faranno molta attenzione a ciò che "automaticamente" cancellano. –

+1

Sì, sono riuscito a risolvere il problema passando la directory di installazione come parametro personalizzato e sovrascrivendo il metodo OnAfterUninstall per eliminare i file creati dall'applicazione. Dopo di che la cartella è vuota, il programma di installazione la rimuove automaticamente. – Mun

Problemi correlati