[VB.NET] Console application output opvangen

Status
Niet open voor verdere reacties.

The Mighty Atom

Terugkerende gebruiker
Lid geworden
22 mei 2008
Berichten
1.380
Ik werk al twee jaar aan een front end, dat simpelweg een batchfile aanmaakt en het daarna uitvoert (je ziet dan een dos window waarin het "compile" process the volgen is.

Een tijdje terug vond ik op een forum een thread waarin gevraagt werd of dat hele process weer te geven is in een textbox. Met andere woorden: de output opvangen een in een textbox plaatsen.

Dus ik zoeken naar voorbeeld code, en ik heb inderdaad gevonden wat ik dus wil bereiken. Helaas is er een klein euvel waar ik maar geen oplossing voor kan vinden. Het is het volgende:

Zoals ik al zei vind er een compilatie process plaats als het batch bestand uitgevoerd word.

Zie hier een screenshot van het compilator process onder een gewoon dos venster:

comp_proc_dosvenster.png


Kijk eens naar de enalaatste regel. Daar staat CreateBrush. De regel daaronder is een process op zich, dat word weergegeven door een tellend getal. Van 0 naar 43 in dit geval. Dit tel process vind plaats op diezelfde regel, er word dus geen nieuwe regel gemaakt als het getal (25) met 1 verhoogd wordt.
Dit is helaas wel het geval in mijn programmaatje:

comp_proc_textbox.png


In plaats van dat dat tel process op dezelfde regel onder CreateBrush: moet plaatsvinden, word er steeds een nieuwe regel gemaakt voor elke elkeer als dat tel getal met 1 verhoogd wordt.

Dit levert natuurlijk een enorme lap text op, zeker als het een hoog eind getal (43 in dit geval) is, bijvoorbeeld 30000 en geloof me, dat komt voor.

Ik zou het dus graag hebben dat dat tel process gewoon op 1 regel blijft plaats vinden totdat het tel process voorbij, en pas daarna de rest van het compilatie process in de textbox neerzet.

En CreateBrush is niet enigste tel process, er zijn er meer, met verschillende eind getallen.
Bekijk hier het complete log bestand:
http://www.themightyatom.nl/stuff/full_comp_proc.txt

Zie je hoeveel tekst er gegenereerd is? Alleen maar omdat die tel processen steeds op een nieuwe regel worden geprint, en niet op 1 regel, wat wel het geval is als je dit compilatie process in een dos venster laat uitvoeren.

Laat er alsjeblieft iemand ziet die hier een oplossing voor weet. Ik geef je net zoveel free Internets als je maat wenst. :D
 
Laatst bewerkt:
Jaye, half-life! Vervloekte batch compilers ook... :p

Anywho:
Een tijdje terug vond ik op een forum een thread waarin gevraagt werd of dat hele process weer te geven is in een textbox. Met andere woorden: de output opvangen een in een textbox plaatsen.
hoe doe je dit precies? Wel handig om te weten. Ik neem aan dat je via een bepaalde api oid de text steeds oppvraagd. Op die manier kan je waarschijnlijk een mooie test-lus kunnen maken die de vorige zin checkt, en anders deze wist oid?


[edit]
WAAROM heb je nooit eerder gezegd dat je bezig was aan een uplink-remake? (dubbele-punt-O). Ga m meteen spelen als k weer thuis ben.


:thumb:
 
Laatst bewerkt:
Jaye, half-life! Vervloekte batch compilers ook... :p

Anywho:

hoe doe je dit precies? Wel handig om te weten. Ik neem aan dat je via een bepaalde api oid de text steeds oppvraagd. Op die manier kan je waarschijnlijk een mooie test-lus kunnen maken die de vorige zin checkt, en anders deze wist oid?


[edit]
WAAROM heb je nooit eerder gezegd dat je bezig was aan een uplink-remake? (dubbele-punt-O). Ga m meteen spelen als k weer thuis ben.


:thumb:

Kijk, dat zijn nog eens leuke reacties!
Tsja, die ingebouwde compiler in Hammer (de level editor) is echt waardeloos. Je moet het hele process afwachten voordat je verder kan gaan in Hammer, want het is namelijk net of Hammer hangt wanneer het bezig met een compile (threading kende Valve zeker nog niet ofzo).

Ik heb een klein voorbeeld appje voor je gemaakt. Tevens maak ik gebruik van een BackGroundWorker control.
Download hier: http://www.themightyatom.nl/stuff/Vegras.zip (gemaakt onder Visual Studio 2008 voor VB.Net.

En over mijn Uplink Remake: het is vrijwel hetzelfde als de originele, alleen beter/mooier/gedetaileerder brushwork, en het is ietsjes langer dan het origineel.
Komt nog bij dat ik al sinds 2006 heb beloofd om een de mod uit te breiden met wat meer maps, maar ik zoveel project dat dat vrij langzaam gaat.

Wel op hard spelen hé. :D
 
Laatst bewerkt:
Tsja, die ingebouwde compiler in Hammer (de level editor) is echt waardeloos
Tell me all about it... Ik had op een gegeven moment een of ander programma voor compilen, werkte wel aardig... maar het instellen van bepaalde dingen was waardeloos. Het is alweer een tijdje geleden dat ik gemapt heb...

Anywho, als ik thuis ben zal ik je vb even bekijken, op het moment zit ik op een pc zonder vb-mogelijkheid. Bovendien ben ik niet echt een... expert op het gebied van .NET, vb6 wel though.


Ik heb alle hl's op hard gespeeld, dus ja, deze zeker weten ook :p
 
hehe, nice. Uitgespeeld op hard, pistol/crow/nades only. :) Ohja, als je de lift omhoog laat komen waarmee je zegmaar als laatst ingaat naar beneden, net voordat het beeld zwart fade, die lift: ik sprong er in voordat ie helemaal boven was. Kwam vast te zitten (achterin de lift), moest mezelf eruit no-clippen. en opnieuw erin stappen. Maargoed, kleinigheidje.


Anywho, over je vb prog: deze sub:
Code:
    Private Sub UpdateTextBox(ByVal Tex As String)
        If Me.InvokeRequired Then
            Dim del As New UpdateTextBoxDelegate(AddressOf UpdateTextBox)
            Dim args As Object() = {Tex}
            Me.Invoke(del, args)
      Else
            tbOutput.AppendText(Tex & Environment.NewLine)
        End If
    End Sub
en dan specifiek de 'else':

maak een globale var aan, genaamd prevLine oid. String. Daarin sla je de vorige regel op, maar alleen als de nieuwe regel niet 'hetzelfde' is. Of, maak een var te, boolean, die flase is, maar naar true gaat als je een speciale regel aantreft.

Ik hoop dat je begrijpt wat ik bedoel. Voorbeeldje:
Code:
[COLOR="SeaGreen"]'globaal[/COLOR]
dim isCreateBrush as boolean = false


[COLOR="SeaGreen"]'je sub:[/COLOR]
    Private Sub UpdateTextBox(ByVal Tex As String)
        If Me.InvokeRequired Then
            Dim del As New UpdateTextBoxDelegate(AddressOf UpdateTextBox)
            Dim args As Object() = {Tex}
            Me.Invoke(del, args)
      Else
            [COLOR="SeaGreen"]'check eerst of t al in createBrush modus zit:[/COLOR]
            if isCreateBrush then
               tbOutput.lastline.changeto(tex & enviroment.newline)
            else
               [COLOR="SeaGreen"]'check of we naar createBrush modus moeten
                'Dit's tricky. Lees even na de eind van deze code.[/COLOR]
               if ......... then
                  isCreateBrush = true
                else
                   isCreateBrush = false
                end if
               [COLOR="SeaGreen"]'in text pushen[/COLOR]
               tbOutput.AppendText(Tex & Environment.NewLine)
            end if
        End If
    End Sub
Zoiets zou ik ervan maken. Je moet natuurlijk even iets verzinnen voor de tbOutput.lastline.changeto(tex & enviroment.newline), maargoed, dat's niet zo lastig. Natuurlijk is het probleem de 'if ...... then' - je moet iets vinden dat aan een bepaald iets voldoet. Tricky. Ik ga er even een nachtje over slapen :p Mischien als je de string 'CreateBrush:' tegenkomt, en pas stoppen als je weer een lege regel vind... hmm.



[edit]
Hm, alle regels die dus moeten overlappen hebben wel wat gemeen bedenk ik me net:
int / int [optional] (int % string)
regexp?
[/edit]
 
Laatst bewerkt:
Hey,

Hoe doe je die commandprompt in een form? Is dat een COM component ofzo?

Cheers
BN
 
nee, zoiets:
Code:
Private Sub bgwLongProcess_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwCompilationProcess.DoWork

        Dim P As Process = New Process()
        P.StartInfo.FileName = 'BESTAND HIER
        P.StartInfo.WorkingDirectory = 'WORKINGDIRECTORY HIER
        P.StartInfo.Arguments = 'ARGUMENTEN HIER
        P.StartInfo.UseShellExecute = False
        P.StartInfo.CreateNoWindow = True
        P.StartInfo.RedirectStandardOutput = True

        AddHandler P.OutputDataReceived, AddressOf UpdateTB
        P.Start()
        P.BeginOutputReadLine()
        P.WaitForExit()
        P.Close()

    End Sub
en
Code:
    Sub UpdateTB(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        UpdateTextBox(e.Data)
    End Sub
 
Argh, dat is ******* lastig. Ik krijg het gewoon niet voor elkaar.
Die UpdateTextBox sun is nu één grote bende van random code die ik van internet haal in de hoop dat het samen doet wat ik wil. Niet echt dus. :(

Ik denk inderdaad dat RegEx de oplossing zou kunnen zijn, maarja, RegEx is nou niet bepaald het makkelijkste en ik heb daar ook totaal geen ervaring mee. Ik zal eens zoeken.

Het zal wel zoiets worden als:

if Match then
...keep replacing last line until no more matches

of zoiets.



En Vegras, als je eens niks te doenhebt, probeer hier iets van:
http://twhl.co.za/user.php?id=469

:D

Edit:

De RegEx voor " # / #" is:
\s+\d+\s+/\s+\d+

De RegEx voor " # / # (#%: est. time to completion <# sec) " is:
\d+ /\s+\d+\s+\(\d+%: est. time to completion <\d+ sec\)

Nu moet ik het dus alleen nog voor elkaar krijgen dat de laatste regel overschreven word als er een match word gevonden en gewoon steeds text blijven appenden (AppentText) als er geen match is.

Kan iemand mij daar wat opweg mee helpen?
Dank. :)
 
Laatst bewerkt:
Niemand die me wat opweg kan helpen?

Ik heb het regex gedeelte voor elkaar, het probleem is dat de gehele textbox leeggehaald word en daarna de counter laat zien op de eerste regel in plaats van dat het gewoon op de laatste regel gebeurt.

Ik weet echt niet hoe ik dit nou goed moet uitleggen...
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan