501 messaggi dal 09 giugno 2006
Contributi
Ciao.

Prima di tutto mi sembra di capire che l'applicazione da monitorare sia una Console Application (questo cambia un po' le cose) e non una Winform Application. E' così?.

Esattamente come utilizzi il redirect di standard output e error puoi utilizzare lo stream di standard input per "scrivere" verso l'applicazione (es. inviare un NewLine in risposta ad un probabile Console.Readline presente nell'applicazione di origine).

In alternativa, se i tempi di elaborazione dell'applicazione sono noti, puoi invocare il metodo WaitForExit passando il timeout di attesa (espresso in millisecondi) e poi killare il processo.

Ciao.
Modificato da mrdev il 20 febbraio 2008 12.54 -

.:. Marcello Rutter .:.
53 messaggi dal 27 novembre 2001
mrdev ha scritto:
Ciao.

Prima di tutto mi sembra di capire che l'applicazione da monitorare sia una Console Application (questo cambia un po' le cose) e non una Winform Application. E' così?.

Esattamente come utilizzi il redirect di standard output e error puoi utilizzare lo stream di standard input per "scrivere" verso l'applicazione (es. inviare un NewLine in risposta ad un probabile Console.Readline presente nell'applicazione di origine).

In alternativa, se i tempi di elaborazione dell'applicazione sono noti, puoi invocare il metodo WaitForExit passando il timeout di attesa (espresso in millisecondi) e poi killare il processo.

Ciao.
Modificato da mrdev il 20 febbraio 2008 12.54 -

Ciao.
l'applicazione è una Windows Form application scritta in vb.net, ma è stata scritta da un non programmatore, quindi non ha tracer interni o log che facciano capire cosa succede e cosa da errore.
ti posto il codice che utilizzo:

Dim Prc As New System.Diagnostics.Process
Dim ProcessStartInfo As New ProcessStartInfo
Prc.StartInfo.UseShellExecute = False
Prc.StartInfo.RedirectStandardError = True
Prc.StartInfo.RedirectStandardInput = True
Prc.StartInfo.RedirectStandardOutput = True
Prc.StartInfo.FileName = "Processo.exe"
Prc.Start()
Prc.WaitForExit()
If Prc.ExitCode <> 0 Then
Dim stdErr As StreamReader = Prc.StandardError
Scrivo l'errore
Else
Dim stdErr As StreamReader = Prc.StandardOutput
Scrivo l'errore
End If

il problema non è quello dello stream di errore da leggere, quanto il fatto che quando eseguo il metodo "WaitForExit" l'applicazione aspetta un ritorno dalla 1° applicazione. Il problema però è proprio nel fatto che anche quando si verifica un errore, esce fuori un messaggio con il codice dell'errore, ma l'applicazione non si chiude se non con un input dell'utente.
Come posso killare il processo mantenendo traccia del codice d'errore?
501 messaggi dal 09 giugno 2006
Contributi
Ok, ma precisamente cos'è questo input che dovrebbe fare l'utente? Premere un tasto su una finestra di dialogo, premere ENTER o altro?

Inoltre se usi RedirectStandardError e RedirectStandardOutput con i relativi Stream, significa che la tua applicazione da monitorare scrive sulla console di sistema.

Per il problema di killare il processo dipende ancora una volta dal tipo di applicazione. Secondo me dovresti lavorare sulla prima parte ossia prendere il controllo dell'input dell'applicazione. L'alternativa che ti suggerivo era qualcosa di simile a questo:

' Ometto il codice che hai già scritto
Prc.Start() 
' Attendo il processo per 60 secondi (è un esempio, il tempo lo dovrai valutare te)
Prc.WaitForExit(60 * 1000)
' Leggi sempre sia standard output che standard error
' usando i due stream Prc.StandardOutput e Prc.StandardError 
' A questo punto chiudi il processo con un brutale Kill.
' Se l'applicazione possiede un form, anziché Kill dovresti provare a richiamare Prc.CloseMainWindow()
If Not Prc.HasExited Then
   Prc.Kill()
End If


Con tutti i benefici del caso dovuti al fatto che non mi è ancora chiaro cosa faccia l'applicazione originale da controllare. A tal proposito: i sorgenti non puoi modificarli ma puoi quasi sicuramente leggerli (alla peggio disassemblando il codice .NET). Da qui dovresti verificare come si comporta l'applicazione nei confronti di STDIN/STDERR/STDOUT e quindi ottimizzare il tuo programma affinché reagisca correttamente.

Ciao.
Modificato da mrdev il 20 febbraio 2008 15.43 -

.:. Marcello Rutter .:.
53 messaggi dal 27 novembre 2001
scusa se non sono stato molto chiaro ma la cosa non è semplicissima da spiegare.
Allora ci riprovo:
c'è una applicazione WindowsForm che devo monitorare perche molte volte va in errore. Purtroppo non mi è dato modo di modificare o cmq di intervenire sul codice sorgente.
Ho creato questa applicazione con il codice sorgente che hai letto sopra che monitorasse la prima.
Per input dell'utente intendo il fatto che quando la mia applicazione esegue il metodo "WaitForExit" resta appesa fino a quando non riceve una risposta dalla prima; siccome spesso va in crash, appare un messaggio di errore al quale l'utente deve dare il "Fine" per proseguire(questo è quello che intendevo per input). Solo a questo punto il programma di monitoraggio riceve un exitcode e quindi puo procedere a scrivere la risposta, positiva o negativa.
Il problema dunque è: posso forzare la chiusura dell'applicazione quando questa va in errore potendo però anche scrivere l'eventuale messaggio di errore dall'applicazione di monitoraggio(e quindi dall'esterno dell'applicazione che va in crash utilizzando i processi di diagnostica)?
176 messaggi dal 04 giugno 2007
Contributi | Blog
Niddu,

Stai reinventando la ruota.

Fai girare l'applicazione sotto un debugger e aspetta che si pianti.
In questo modo avrai il break esattamente dove l'applicazione sta fallendo.

Se non basta, attiva tutti gli MDA (Managed Debug Assistant) e ripeti.
In questo caso ogni violazione che genera un MDA generera' un break nel debugger.

Se non vuoi/puoi usare il debugger di VS, usa NTSD o WinDbg

Se non hai i simboli, fai un break nell'IL e vai di Reflector.
Se non puoi fare neanche questo, almeno saprai in che funzione si pianta l'applicazione.

Agendo dall'esterno per capire che cosa sta succedendo puoi fare alcune operazioni avanzate:
1) hai fatto girare l'applicazione in uno host che fa il handling dell unhandled exception?
2) facendo girare l'applicazione con un profiler attaccato, come e' il profilo di alloazione? L'applicazione sta morendo di out-of-memory, stack overflow, access violation or unhandled exception? Nei primi due casi il problema e' un baco serio nella gestione del ciclo di vita degli oggetti usati nell'applicazione. Nel caso 3 e' al 90% un errore nella signature di una P/Invoke, il quarto caso puo' essere piuttosto semplice da correggere.

Saluti

--Alessandro
Secondo me il problema è la tecnica che Niddu vuole adottare e cioè non vuole risolvere il problema, ma reagire in funzione dei problemi che si verificano. Mettere sotto debugging o profiling un'applicazione per sempre non mi sembra il massimo (non a caso sono tecniche per sviluppare/ottimizzare).

Io mi inpunterei con il capo perché non accettabile dire di lasciare buggata un'applicazione, ma piuttosto investirei ad ottimizzarla con le tecniche che ha detto Alessandro

Ciao

Il mio blog
Homepage
53 messaggi dal 27 novembre 2001
Sono assolutamente d'accordo con voi ma purtroppo il rifare l'applicazione non è fattibile...
ora vi chiedo un'altra cosa: allo stato attuale con il metodo SendKeys (attraverso la funzione FindWindow di "user32.dll")riesco a intercettare la finestra che appare in caso di errore e simulare il click sul tasto "Fine" per chiudere la finstra di errore. Ma se volessi anche leggere cosa c'è scritto nel messaggio di errore della finestra nella sezione dove c'è il call stack di dove è avvenuto l'errore?
501 messaggi dal 09 giugno 2006
Contributi
Ciao.

Fermo restando quanto scritto negli altri post puoi provare nel seguente modo. Prima di tutto ti suggerisco di utilizzare il tool Spy++ disponibile tra i tools di Visual Studio. Con questo tool puoi analizzare e monitorare in dettaglio ogni singola finestra del sistema compresi i messaggi ad essa indirizzati. Applicandolo al tuo caso, quindi, monitorando la finestra di errore dovresti individuare le diverse componenti tra le quali immagino ci sia un controllo sotto forma di sub-window che contiene il messaggio che a te interessa.

Ottentuo l'handle di quella specifica finestra, ti sarà sufficiente richiamare l'API GetWindowText (http://www.pinvoke.net/default.aspx/user32/GetWindowText.html) per leggerne il contenuto (oppure SendMessage con WM_GETTEXT).

Ciao.

.:. Marcello Rutter .:.

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.