Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]5223[/thread]

WIN32::GUI Problem mit Systemaufrufe: Datei lesen nach ShellExecute geht nicht

Tags: Ähnliche Threads

Leser: 1


<< >> 5 Einträge, 1 Seite
OliverW
 2006-08-04 04:08
#45745 #45745
User since
2006-08-04
3 Artikel
BenutzerIn
[default_avatar]
Hallo,

ich möchte unter einer WIN32::GUI Oberfläche etwas ganz einfaches tun, nämlich Daten in eine Datei (z.B. in.txt) zu schreiben, diese Datei von einem Program bearbeiten lassen, welches seine Ergebnisse in eine weitere Datei (z.B. out.txt) ausgibt, die dann wiederum von der Oberfläche eingelesen wird um weiteres damit anzustellen. Den Aufruf des Programs könnte man mit system, oder qx, etc. machen, was dann auch funktioniert, nur das sich kurz so ein lästiges Windowsfenster öffnet und wieder schliesst, was halt gar nicht so dolle wirkt... WIN32::GUI bietet die Routine ShellExecute, welche mit einem Parameter erlaubt das Fenster zu unterdrücken. Das funktioniert auch schön, nur das jetzt das Dateieinlesen nach dem Programaufruf nicht mehr funktioniert.

Nach langen rummachen und ausprobieren scheint mir das Problem darin zu liegen, dass die frisch generierten Daten der Ausgabedatei zu dem Zeitpunkt wo diese von der Perl-Oberfläche wieder eingelesen wird aus irgendeinem Grund noch nicht zur Verfügung stehen. Statt dessen werden die alten Daten eingelesen... Als einzigste Lösung, die ich bisher, trotz viel Recherche, gefunden habe, ist zwischen dem Programaufruf und dem Einlesen der Ausgabedatei lange genug zu warten, z.B. mittels eines sleep(1), was dann halt nervig langsam ist...

Meine Frage, weis jemand eine vernünftige Lösung (vernünftig in dem Sinne das kein Fenster erscheint und man nicht ewig warten muss)? Gibt es z.B. eine Möglichkeit rauszufinden wann die aktuellen Daten eingelesen werden können, oder zu erzwingen das sie zur Verfügung stehen?

Tausend Dank,
 Olli

Diese Informationen sind vielleicht noch nützlich.

Das Program heisst bei mir owH_extract.exe, und benötigt als Parameter die Eingabe- und Ausgabedatei (also z.B. owH_extract in.txt out.txt). Ich habe es mit C geschrieben. Das commit-to-disk flag wurde gesetzt, und for dem fclose() habe ich extra noch einen expliziten fflush(). Das ist aber eigentlich alles nicht wichtig weil das Problem nicht beim Program zu liegen scheint...

perl -v liefert
This is perl, v5.8.7 built for MSWin32-x86-multi-thread
(with 7 registered patches, see perl -V for more detail)
Copyright 1987-2005, Larry Wall
Binary build 813 [148120] provided by ActiveState http://www.ActiveState.com
ActiveState is a division of Sophos.
Built Jun  6 2005 13:36:37

Und zu guter, noch ein kleines Progrämchen um die Problemstellung auch anhand von Code nachvollziehbar zu machen. Es wird bei Euch nicht funktionieren weil Ihr owH_extract nicht habt, aber jedes andere Program welches eine Datei einliest und eine Neue ausgibt sollte es tun.

#Beispielprogram
Code: (dl )
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
65
66
67
68
69
70
71
use strict;

# Hier kommt nur die GUI zum Testen
use Win32::GUI;

my $w_Main= GUI::Window->new( -name=> 'm_Window',
 -text=>'Test DoTheJob',-pos=>[0,0],-size=>[380,250]
);
$w_Main-> AddTextfield( -name=> "m_InText",
 -prompt=>"In:",-pos=>[25,5],-size=>[200,100],-multiline=>1
);
$w_Main-> AddTextfield( -name=> 'm_OutText',
 -prompt=>"Out:",-pos=>[25,110],-size=>[200,100],
 -multiline=>1,-readonly=>1
);
$w_Main->AddButton( -name=> 'm_DoSys',
 -text=>'DoTheJob via system',-pos=> [235,73],-width=>130
);
$w_Main->AddButton( -name=> 'm_DoShell',
 -text=>'DoTheJob via Shell',-pos=> [235,98],-width=> 130
);
$w_Main->AddButton( -name=> 'm_DoShellSleep',
 -text=>'DoTheJob via Shell&Sleep',-pos=> [235,123],-width=> 130
);

$w_Main-> Show();
Win32::GUI::Dialog();

sub m_DoSys_Click{
 $w_Main->m_OutText->Text( Convert(0,$w_Main->m_InText->Text()) );
}
sub m_DoShell_Click{
 $w_Main->m_OutText->Text( Convert(1,$w_Main->m_InText->Text()) );
}
sub m_DoShellSleep_Click{
 $w_Main->m_OutText->Text( Convert(2,$w_Main->m_InText->Text()) );
}

# Hier kommt jetzt das worum es eigentlich geht

sub Convert{
 my $flag= shift; #flag= 0: via system; 1: via ShellExecute;  2: via ShellExecute & sleep
 my $s= shift;

 #String in Datei ausschreiben
 open( DATEI, ">in.txt" );
 print DATEI $s."\n";
 close( DATEI);

 #Info in Datei mit owH_extract bearbeiten und Resultat in out.txt speichern
 if( $flag==0 ){
   # so funktionierts, öffnet aber ein lästiges Fenster...
   system( "owH_extract.exe in.txt out.txt" );
 }elsif( $flag==1 ){
   # öffnet kein lästiges Fenster, aber funktioniert auch nicht...
   $w_Main->ShellExecute('open',"owH_extract.exe","in.txt out.txt",'',0);
 }else{
   # funktioniert und öffnet kein lästiges Fenster, aber dauert halt...
   $w_Main->ShellExecute('open',"owH_extract.exe","in.txt out.txt",'',0);
   sleep(1);
 }

 #Ergebnisdatei einlesen
 open(DATEI2,"<out.txt") or die("Mist");
 my @txt= <DATEI2>;
 close(DATEI2);

 #Ergebnis bearbeiten, wird hier zum Test einfach zurückgegeben
 $s= ''; foreach(@txt){ $s.= $_;}
 return $s;
}
\n\n

<!--EDIT|esskar|1154652085-->
esskar
 2006-08-04 04:40
#45746 #45746
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
hallo.
schau dir mal CPAN:Win32::Process.
damit kannst du auch programme im hintergrund starten und auch warten bis dieses porgramm zu ende ist.
das ist naemlich genau dein problem: shellexecute kehrt sofort zurueck, was aber nicht garaniert, dass das dein programm schon beendet ist - koennte sogar sein, dass es noch gar nicht gestartet ist. Deswegen ist out.txt auch leer.
Gast Gast
 2006-08-04 06:28
#45747 #45747
Ok. Die Erklärung macht Sinn (wäre ich ja nie im Leben darauf gekommen das ShellExecute so was machen könnte...:-)). Thank you so much. Zumindestens verstehe ich nun das Problem schonmal. Werde mir mal Win32::Process genau ansehen...

Danke nochmal soweit,
Olli

PS: und Danke das du das Codefenster gemacht hast, dadurch ist es mir auch plötzlich aufgegangen was diese ominösen iB Buttons wohl machen könnten...
esskar
 2006-08-04 13:18
#45748 #45748
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
kein thema: hier werden Sie eben immer geholfen. :)
OliverW
 2006-08-05 18:29
#45749 #45749
User since
2006-08-04
3 Artikel
BenutzerIn
[default_avatar]
Super, die Lösung ist dann tatsächlich einfach.

Code: (dl )
1
2
3
4
use Win32;
Win32::SetChildShowWindow(0); #damit system kein Fenster öffnet

system( "owH_extract.exe in.txt out.txt" );


Ich möchte allerdings gestehen, das nicht ich die Lösung gefunden habe, sondern sie hier bei Euch im Forum steht (ich glaube es war weit hinten im Allgemeines zu Perl). Leider gelang es mir jetzt nachträglich auch durch suchen nicht mehr diesen Beitrag zu finden.

Daher, tausend Dank an esskar und ein unbekanntes Perl-Community Genie. :)
<< >> 5 Einträge, 1 Seite



View all threads created 2006-08-04 04:08.