Newsgroup: it.comp.programmare.win32
Titolo: come sovrascrivere l'eseguibile in esecuzione

vorrei inserire in un mio programma (che e' composto da un unico eseguibile) 
la funzione di aggiornamento da internet.
mi sono bloccato sul fatto che una volta scaricato il file eseguibile in 
memoria, non lo posso scrivere sul disco perche' e' ancora in esecuzione.
come si risolve ? 

 come si risolve ?
Dal punto di vista pratico, non lo so.
Dal punto di vista logico, se proprio non fosse concesso operare via 
filesystem su un file in esecuzione (idiozia pura e semplice), non resta 
che creare ed eseguire un nuovo processo non legato ad alcun file e 
terminare l'esecuzione. Il nuovo processo attender� il termine del 
processo padre, quindi operer� su ogni file liberamente.
Io farei cos�.


come si realizza quello che hai scritto ?
due righe di codice di esempio, o un link che ne parla, mi sarebbero molto 
utili.
-- 
alfio 

 Io farei cosï¿œ.
+1, tutti quelli che ho visto fanno cosï¿œ
-- 
Raffaele Rialdi  
http://www.iamraf.net
Weblog: 
http://blogs.ugidotnet.org/raffaele
Microsoft .NET MVP 
http://mvp.support.microsoft.com
 -
UGIdotNET - 
http://www.ugidotnet.org


se mi aiutate un briciolino di piu' .......
come si crea un processo non legato a un file ?
a me viene in mente di creare un file bat o cmd temporaneo ed eseguirlo, ma 
poi come posso sapere al suo interno che l'eseguibile principale e' 
terminato ?
-- 
alfio 

 ?
Scrivi un'applicazione a parte che chiameremo 'updater' (un 
normalissimo exe win32) che scarica la nuova versione del tuo 
applicativo da internet e la salva su disco, sovrascrivendo la vecchia.
Se non vuoi dare due file separati il tuo updater.exe lo puoi mettere 
dentro le risorse della tua applicazione.
Quando la tua applicazione vuole aggiornarsi, estrae updater.exe dalle 
risorse e lo lancia con una ShellExecute (API). Subito dopo si chiude 
in modo da liberare il file exe che potrï¿œ essere sovrascritto.
L'updater dovrï¿œ controllare che l'applicazione sia veramente chiusa 
prima di scrivere il file. Questo lo puï¿œ fare in diversi modi, per 
esempio controllando un named mutex (cioï¿œ che ha un nome) condiviso con 
l'applicazione normale.
In alternativa puoi usare l'api EnumProcesses ma questo significa fare 
'polling' sulla lista dei processi ed ï¿œ piï¿œ laborioso rispetto al 
mutex.
Il mutex "named" ï¿œ in sostanza un unico mutex condivisibile tra piï¿œ 
processi. Il primo che lo crea acquista la ownership mentre i processi 
successivi acquistano solo un handle a quello giï¿œ creato.
Il funzionamento ï¿œ semplice:
- l'update crea il mutex con nome "quellochevuoi".
- se acquista la ownership significa che il processo ï¿œ giï¿œ chiuso e puï¿œ 
aggiornare
- se non ha la ownership significa che il processo ï¿œ su e quindi esegue 
una waitforsingleobject(mutex) in attesa che esca.
- l'applicazione come va su registra il mutex e quando esce fa una 
set(mutex) in modo da segnalare all'updater che sta terminando.
Anche senza codice spero di averti dato una traccia.
Ciao



la traccia e' piu' che sufficiente, ti ringrazio, e ora mi metto al lavoro.
-- 
alfio 

> la traccia e' piu' che sufficiente, ti ringrazio, e ora mi metto al lavoro.
Prego, ciao


 Il file ï¿œ ovviamente in uso e quindi non scrivibile. Ci sono diversi 
Non ï¿œ un dogma di fede che un file in esecuzione sia considerato aperto 
e non scrivibile.

 scrivibile.
Come scrivevo prima, ci sono ottimi motivi per cui lo debba essere, a 
tutto vantaggio del consumo di ram.


Giu ha scritto:

Io farei in modo + semplice:
rinomini il file in esecuzione (questo lo puoi fare) e gli assegni un 
nome temporaneo e "noto". Scrivi tranquillamente quello nuovo e alla 
prossima esecuzione cancelli quello temporaneo (o lo tieni "archiviato" 
se per caso vuoi poter tornare indietro.
Semplice ed efficace


provato e funzionante, grazie mille.
aggiungo un'altra domanda:
quale api devo usare per chiudere il programma corrente (e' una GUI)  e 
lanciare il nuovo eseguibile appena scaricato ?
su DOS c'erano le spawn (in C) e su win32 ? 

 su DOS c'erano le spawn (in C) e su win32 ?
Per lanciare il nuovo exe CreateProcess.
Se ti ï¿½ utile, puoi anche passarti eventuali handle per sincronizzazione...
Per chiudere il prog corrente, dipende. Ci sono API che "stroncano" il 
processo ma non ti conviene usarle perchï¿½ in certi casi sono troppo 
violente (ad esempio potresti perdere dati). Dipende molto dalla logica 
del tuo programma: devi prevedere un modo pulito per uscire salvando 
tutto, e tenendo conto dell'interazione con l'utente (tipo evita di 
chiedergli 100 volte se ï¿½ sicuro di uscire e/o se vuole salvare...)
Normalmente la chiusura di un prog GUI ï¿½ scatenata da un messaggio 
WM_CLOSE (ï¿½ quello che succede se ad es. l'utente preme la X della 
finestra principale), ma ochio a quelloc che ti dicevo sopra con 
l'interazione con l'utente...


perfetto, e' proprio cio' che stavo sperimentando,
grazie, grazie e ancora grazie.
-- 
alfio 

 applicativo da internet e la salva su disco, sovrascrivendo la vecchia.
Aggiungo che io seguo di solito questa strada, ma l'updater scarica un
vero e proprio setup, lo lancia e si chiude. Il setup di solito richiede
un minimo di interattivit� con l'utente, per cui c'� sempre tempo per
l'updater di chiudersi. In questo modo, con un setup, � possibile
aggiornare l'updater stesso. 
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


purtroppo le mie conoscenze attuali non arrivano a tanto.
il mio programma attualmente non ha un setup, e' un singolo eseguibile.
ho provato la soluzione di GM, e per me e' piu' facile da realizzare, ma 
grazie lo stesso per i vostri suggerimenti, saranno materiale da 
approfondire nel prossimo futuro.
-- 
alfio 

 il mio programma attualmente non ha un setup, e' un singolo eseguibile.
Ma per creare un setup si adopera uno dei tanti installer free
disponibili. Io ho usato NSIS per esempio.


 lanciare il nuovo eseguibile appena scaricato ?
Puoi usare CreateProcess/ShellExecute/ShellExecuteEx.
Guarda MSDN per documentarti.


 aggiornare l'updater stesso. 
Concordo, il setup ï¿œ la tecnica migliore (senza dubbio in formato msi) 
perchï¿œ gira come "TrustedInstaller" e quindi ha automaticamente i 
privilegi necessari per copiare in program files l'exe dove normalmente 
un utente non dovrebbe avere i diritti in scrittura (anche su XP, non 
parlo solo di Vista o Win7).
In alcuni casi (vedi reflector.exe) se ï¿œ un tool come singolo file puï¿œ 
essere accettabile non usare un setup perchï¿œ magari lo lanci da 
chiavetta usb.
In questo caso per elevare il privilegio di un utente ad amministratore 
per far girare l'updater (da Vista in su), ï¿œ sufficiente usare 
ShellExecute con il verb impostato a "runas". Questo funge da trigger 
per la UAC.
La CreateProcess riceverebbe l'errore "ERROR_ELEVATION_REQUIRED" e 
quindi sarebbe inutilizzabile.


Raffaele Rialdi [MVP] ha scritto:
<snip>
Molto interessante! grazie delle info!


> Molto interessante! grazie delle info!
Prego :)



bene, lo aggiungo alla (lunga) lista delle cose da imparare  :)
-- 
alfio