[c#] Gebruik van Diagnostics.Process blijft hangen

Pagina: 1
Acties:

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 08:09
Hallo,

Ik ben op dit moment bezig met het maken van een applicatie die een aantal handelingen met betrekking tot het inpakken van iso's (eigen backups) moet vergemakkelijken.

Deze iso's zijn normaal gesproken rond de 700MB (1CD).
Deze wil ik met behulp van Rar.exe (Dos versie van winrar) inpakken in bestanden van een X aantal MB (tijdens het testen heb ik voor 15 MB bestanden gekozen).

Hier komen dan normaal gesproken +- 48 rar bestanden uit. (de delen 0 t/m 47 dus).
Met behulp van een System.Diagnostics.Process wil ik de output van de applicatie zelf opvangen en later analyseren (het aantal gemaakte bestanden etc zijn later in het process nog nodig). STDOUT en STDERR moeten dus worden opgevangen door mijn applicatie, wat in eerste instantie goed lijkt te werken.

Tijdens het bouwen van de applicatie heb ik voor test doeleinden gebruik gemaakt van 50 MB iso's. Dit werkte perfect, het process wordt in de achtergrond opgestart, er worden 3 rar bestanden gemaakt en de stdout wordt goed opgevangen.

Toen ik dacht dat de applicatie klaar was begon ik met het testen van 700MB bestanden. Hier ging het fout. Wanneer het inpakken van de 1e CD rond het 20e rar bestand zat liep het "vast". Mijn programma en RAR bleven gewoon lopen, er werd echter geen data meer ingepakt.
Wanneer ik mijn eigen programma echter afsloot ging rar vrolijk verder met het inpakken van de resterende data.

De volgende code start het rar process op:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Creating new process
System.Diagnostics.Process procRar = new Process();

// Adding executable path
procRar.StartInfo.FileName = strRarExe;
        
// Assigning workign directory
procRar.StartInfo.WorkingDirectory = this.GetFolder(this.arrFile1[0]);

// Adding the execute arguments (including the file list we need to pack)
procRar.StartInfo.Arguments = strRarExecutionCommand + " " + strFileList;
                
// Dont use the system shell to execute. We handle the stdout and stderr by ourself
procRar.StartInfo.UseShellExecute = false;

// Redirecting stdout and stderr messages so we can analyze it later
procRar.StartInfo.RedirectStandardError = true; 
procRar.StartInfo.RedirectStandardOutput = true;
                
// Run the app in the background
procRar.StartInfo.CreateNoWindow = true;
            
// Creating a string for our stdout and stderr
string strStdOut,strStdErr;
                        
// Lets run the application (using try/catch, we never know what happends)
try
{
    // Lets fire the thing
    procRar.Start();

    // Setting process priority to Idle.
    //procRar.PriorityClass = System.Diagnostics.ProcessPriorityClass.Idle;
    
    // Test code, werkt net als procRar.WaitForExit() niet.
    while (procRar.HasExited == false)
    {
        Application.DoEvents();
    }
    
    // Waiting till the rarring is done
    //procRar.WaitForExit();
    
}
catch (Exception ex)
{
    // Something went wrong
    MessageBox.Show(ex.ToString(),"Error!",MessageBoxButtons.OK,MessageBoxIcon.Error);

    return;
}

// We are done, now we check if Rar exited on an error
strStdErr = procRar.StandardError.ReadToEnd().ToString();
strStdOut = procRar.StandardOutput.ReadToEnd().ToString();

if (strStdErr != "")
{
    // Rar exit was with an error
    MessageBox.Show(strStdErr,"RAR Error!",MessageBoxButtons.OK,MessageBoxIcon.Error);
    return;
}   

procRar.Close();


(sorry voor het engelse commentaar, maar het is de bedoeling dat de code ook bij een niet-nederlands persoon komt).

Ik weet niet wat ik fout doe (volgens mij niet?), maar het lijkt net of er een of andere buffer vol zit waardoor hij de stdout niet meer op kan slaan? Ik heb de msdn erop nageslagen, maar daar gebruiken ze een soort gelijke methode.

Ik heb het ook getest door gebruik te maken van de windows shell, daarin werkt het wel zonder problemen.

Misschien is het ook handig te vermelden dat hij fastloopt bij het maken van een nieuw rar bestand, dit bestand blijft dan 0kb groot totdat ik mijn eigen applicatie afsluit.

Ook misschien handig, mijn applicatie loopt niet compleet vast. Als ik in de while loop een tekstbox laat vullen met data wordt die tekstbox steeds verder aangevuld, de applicatie blijft dus wel "goed" lopen.

Edit:

Tijdens het typen van dit bericht had ik me bedacht dat ik misschien de stdout en stderr in de while loop uit moest lezen om zo een buffer overflow te voorkomen, ook dit werkt niet. (hierbij gebruik gemaakt van Read(), niet van ReadToEnd() )

[ Voor 5% gewijzigd door IceM op 29-04-2005 19:48 ]

...


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 04-05 13:09
Misschien moet je is kijken of de Application.DoEvents() misschien de boel in het honderd stuurt?
CAUTION Calling this method can cause code to be re-entered if a message raises an event.

[ Voor 35% gewijzigd door riezebosch op 29-04-2005 20:55 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • IceM
  • Registratie: Juni 2003
  • Laatst online: 08:09
riezebosch schreef op vrijdag 29 april 2005 @ 20:54:
Misschien moet je is kijken of de Application.DoEvents() misschien de boel in het honderd stuurt?


[...]
Application.DoEvents() heb ik als test gebruikt. Ik had eerst de optie procRar.WaitForExit(); om te wachten totdat het inpakken klaar was.
Dit werkte echter niet, net als de while loop die ik daarna gebruikt heb.

...


  • IceM
  • Registratie: Juni 2003
  • Laatst online: 08:09
Het lijkt erop dat ik niet goed genoeg gelezen heb, hier staat het helemaal uitgelegt:
http://msdn.microsoft.com...ssStandardOutputTopic.asp

Domme ik :/

...


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 04-05 13:09
Zou je ook nog even aan willen geven wat je probleem dan precies was (en de oplossing)?

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack