Entwickler-Ecke
Basistechnologien - aufgerufener Code darf keine Dateiarbeit leisten?
Scrabble-Fan - Mo 20.08.07 09:46
Titel: aufgerufener Code darf keine Dateiarbeit leisten?
Guten Morgen!
ich versuche aus einer CLI-Anwendung heraus eine Win32-Konsolen-Anwendung aufzurufen. Dazu verwende ich die Klasse process. Der Aufruf als solcher funktioniert und Testausgaben zeigen, dass die .exe prinzipiell ausgeführt wird.
Versucht diese aber, eine Datei zu öffnen oder selbst zu erstellen, klappt das nicht(ohne weitere Fehlermeldung, da isopen() lediglich anzeigt, ob die Datei korrekt geöffnet wurde).
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| ifstream datei; datei.open(Dateiname.txt); if(!datei.isopen()); ...
fstream ausgabe; ausgabe.open("Test.txt", ios::out); ausgabe << "Hallo Kekse"; |
Die .exe selbst ist prinzipiell funktionsfähig wie Aufrufe aus der Eingabeaufforderung zeigen.
Vielen Dank im Voraus!
Moderiert von
UGrohne: Code- durch C#-Tags ersetzt
Christian S. - Mo 20.08.07 10:51
:wave:
Hast Du mal geschaut, ob wirklich die richtige Dateiname.txt genommen wird? (Stichwort: relative und absolute Pfade)
Könnte Dateiname.txt noch von Deiner Anwendung geöffnet sein, sodass die zweite Anwendung sie nicht öffnen kann?
Grüße
Christian
P.S.: Ich spiel Scrabble ja ganz gerne bei Yahoo ;-)
Scrabble-Fan - Mo 20.08.07 10:57
Hallo,
ja, die Pfade stimmen. Daten.txt ist vorhanden und befindet sich im selben Ordner wie die .exe - zu Testzwecken habe ich auch absolute Pfade versucht, hat aber nicht geholfen.
Die Textdatei ist vorhanden und nicht geöffnet.
Eine andere Datei erstellen, öffnen und "Test" reinschreiben geht aber auch schon nicht. Deshalb glaub ich nicht, dass es an den Aufrufen liegt.
Gruß
PS: bei Yahoo war ich auch schon, aber offline ist schöner :-).
Leuchtturm - Mo 20.08.07 10:58
Zitat: |
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| ifstream datei; datei.open(Dateiname.txt); if(!datei.isopen()); ...
fstream ausgabe; ausgabe.open("Test.txt", ios::out); ausgabe << "Hallo Kekse"; | |
Das müsste doch eigentlich
datei.open("Dateiname.txt"); heißen oder
Christian S. - Mo 20.08.07 11:07
Also das hier in der Eingabeaufforderung funktioniert:
Aber das hier nicht:
C#-Quelltext
1:
| Process.Start("Deine.exe"); |
P.S.: Offline hab ich schon viel zu lange nicht mehr gespielt.
Scrabble-Fan - Mo 20.08.07 11:09
Hallo,
Original-Quellcode ist
Quelltext
1: 2: 3: 4:
| std::ifstream in; in.open("Daten.txt", ios::in); if (!in.is_open()) { ... |
das lässt sich nicht öffnen, auch nicht, wenn ein absoluter Pfad verwendet wird. Die .exe für sich genommen ist aber ausführbar- wenn ich sie in der Eingabeaufforderung aufrufe läuft alles wie es soll.
Gruß
Christian S. - Mo 20.08.07 11:13
Zeig mal bitte den Aufruf in der Kommandozeile und wie Du ihn mit Process.Start umgesetzt hast.
Scrabble-Fan - Mo 20.08.07 11:23
Kommandozeile:
Verdichtung.exe
Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| System::String ^pfad = Convert::ToString(System::Threading::Thread::GetDomain()->BaseDirectory->ToString()); pfad = System::IO::Path::Combine(pfad, "prg"); System::String ^verdichtungsdatei = "Verdichtung.exe"; System::Diagnostics::Process ^prozess = gcnew System::Diagnostics::Process(); prozess->StartInfo->CreateNoWindow = false; prozess->StartInfo->UseShellExecute =false; prozess->StartInfo->RedirectStandardError =true; prozess->StartInfo->RedirectStandardOutput =true; prozess->StartInfo->FileName = System::IO::Path::Combine(pfad, verdichtungsdatei); prozess->Start(); prozess->WaitForExit();
System::String ^ error = prozess->StandardError->ReadToEnd(); System::String ^ output = prozess->StandardOutput->ReadToEnd();
if(output->Length + error->Length != 0) MessageBox::Show("Fehlermeldungen:\n\n" + error + "\n\n" + output, "Fehler"); |
Moderiert von
Christian S.: Code- durch C#-Tags ersetzt
Christian S. - Mo 20.08.07 11:37
Hm. Deine Methode den Pfad zu ermitteln, ist zwar etwas umständlich (-> Application.StartupPath ) aber sollte gehen.
Versuch mal, UseShellExecute auf True zu setzen, nur für Testzwecke. Dann bekommste zwar den Standardoutput nicht mehr, aber für 'nen Test ist das erstmal egal.
Scrabble-Fan - Mo 20.08.07 11:41
Geht auch nicht.
Christian S. - Mo 20.08.07 11:50
Also nochmal:
Das Programm wird gestartet. Aber es kann weder Dateien lesen noch schreiben. Aber es gibt Testausgaben aus. Richtig?
Wenn Du das Programm über die Kommandozeile startest, hast Du dann andere Benutzerrechte?
Scrabble-Fan - Mo 20.08.07 11:57
ja, stimmt es ist aufrufbar, gibt auch Testausgaben aus, aber keine Dateien lesen oder schreiben.
Die Benutzerrechte sollten die gleichen sein.
Was müsste ich denn machen, wenn ich mit der Klasse Process die Eingabeaufforderung öffnen und dort die .exe mit einem absoluten Pfad aufrufen wollte?
Christian S. - Mo 20.08.07 12:07
Naja, eigentlich so, aber das hast Du schon probiert:
C#-Quelltext
1: 2: 3: 4: 5:
| System::Diagnostics::Process ^prozess = gcnew System::Diagnostics::Process(); prozess->StartInfo->UseShellExecute =true; prozess->StartInfo->FileName = "E:\\Downloads\\Reflector\\Reflector.exe"; prozess->Start(); prozess->WaitForExit(); |
Das ShellExecute = true sollte dazu führen, dass die System Shell verwendet wird.
Scrabble-Fan - Mo 20.08.07 12:11
ach so, ok.
Dass es am prinzipiellen Aufruf liegt, glaub ich aber eh nicht, weil er die Datei ja aufruft. Wenn ich die Parameter(die mittlerweile ja nicht mal mehr da sind) einzeln ausgeben lasse, sieht man auch, dass er die richtig nimmt. Er kann halt keine Dateien öffnen.
Inwiefern könnte das ein Sicherheitsproblem sein, was CLI zu unterbinden versucht? Zumindest beim Öffnen fände ich das plausibel. Weniger, wenn ich ne Textdatei schreiben möchte...
Christian S. - Mo 20.08.07 12:13
Bei Sicherheits-Problemen werfen die Programme eigentlich immer mit Exceptions um sich, das würde man dann merken.
Du kannst auch mal diesen Code verwenden, das öffnet dann wirklich das Konsolenfenster und führt aus:
C#-Quelltext
1: 2:
| System::Diagnostics::Process ^prozess = System::Diagnostics::Process::Start("cmd.exe", "/c E:\\Downloads\\Reflector\\Reflector.exe"); prozess->WaitForExit(); |
Das ist zwar ziemlich gefrickelt, aber vielleicht hilft es ja ;-)
Scrabble-Fan - Mo 20.08.07 13:33
das ähm geht partiell...
wenn in PFADNAME der absolute Pfad für die .exe steht dann öffnet mir
C#-Quelltext
1:
| System::Diagnostics::Process ^prozess = System::Diagnostics::Process::Start("cmd.exe", "c/ 2 + PFADNAME); |
lediglich das Konsolenfenster aber an falscher Stelle. Scheinbar sieht er die .exe der CLI-Anwendung als Ordner und navigiert zu diesem.
wenn ich nun zum richtigne Ordner gehe und meine .exe aufrufe läuft die Sache durch und die Dateien werden richtig gelesen und erstellt. Wenn ich Argumente(PFADNAME) und Funktion(cmd.exe) trenne und dann prozess starten lasse, kommt dasselbe heraus.
:?:
Moderiert von
Christian S.: C#-Tags hinzugefügt
Christian S. - Mo 20.08.07 14:02
Dann scheint der Programmierer das aufzurufenden Programmes geschlampt zu haben und die Dateien im aktuelle Arbeitsverzeichnis und nicht im Programmverzeichnis zu suchen. Das aktuelle Arbeitsverzeichnis ist dann da, wo gerade Deine EXE liegt.
Du kannst es aber vor dem Aufruf von Process.Start auf das Verzeichnis der aufzurufenden Anwendung setzen:
C#-Quelltext
1:
| Environment::CurrentDirectory = "E:\\Downloads\\Reflector\\"; |
Dann sollte das Konsolenfenster im entsprechenden Verzeichnis öffnen.
Scrabble-Fan - Mo 20.08.07 14:36
:dance2: :dance: :dance2:
:-)
Dankeschön!
Christian S. - Mo 20.08.07 14:38
Schön, das es klappt, war ja auch eine schwere Geburt! :-)
Jetzt versuch doch mal bitte, nachdem Du das CurrentDirectory gesetzt hast, das Programm mit Process.Start zu starten. Bei der Sache über das Konsolenfenster bluten einem ja die Augen *g*
Scrabble-Fan - Mo 20.08.07 14:58
hatte ich schon :-)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!