2010-03-29 10 views
6

Wykonuję ftd ftp.exe poprzez typ C# System.Diagnostics.Process. I używam następującego kodu, aby uzyskać wyjście "ftp.exe" po tym, jak programowo wprowadzę polecenie "help". Ale mogę uzyskać tylko pierwszą linię wyniku. I nigdy nie dostaję się do części wyjściowej "koniec". Cały program wydaje się zablokowany.Dlaczego nie mogę uzyskać danych wyjściowych pliku ftp.exe według kodu?

Process p = new Process(); 
    p.StartInfo.FileName = @"C:\Windows\System32\ftp.exe"; 
    p.StartInfo.CreateNoWindow = true; 
    p.StartInfo.RedirectStandardInput = true; 
    p.StartInfo.RedirectStandardOutput = true; 
    p.StartInfo.RedirectStandardError = true; 

    p.StartInfo.UseShellExecute = false; 
    p.Start(); 

    p.StandardInput.WriteLine("help"); 

    Int32 c_int = p.StandardOutput.Read(); 
    while (c_int != -1) 
    { 
     Char c = (Char)c_int; 
     Console.Write(c); 
     c_int = p.StandardOutput.Read(); 
    } 

    Console.WriteLine("end"); 

jednak napisać prosty program, który tylko używać Console.WriteLine(), aby napisać kilka wyjścia do jej strumienia stdout. I testuję to z powyższym kodem. To działa dobrze. Po prostu nie mogę zrozumieć, dlaczego powyższy kod nie działa z ftp.exe? Jedyną różnicą między moim programem SimpleConsoleOutput a "ftp.exe" jest to, że ftp.exe ma własny interaktywny wiersz polecenia.

(New Progress --------------- -----------------)

Here're jakiś postęp moje osobiste dochodzenie.

napisać 2 posty pisać do standardowego wejścia i odczytywanych z stdout „ftp.exe”, a wyjście jest tak:

Commands may be abbreviated. Commands are: 

Commands may be abbreviated. Commands are: 

Commands may be abbreviated. Commands are: 
....(exactly 16 times of above lines and then exactly 16 times of the following cmds list) 
!    delete   literal   prompt   send 
?    debug   ls    put    status 
append   dir    mdelete   pwd    trace 
... 

i ostatnia lista poleceń nie jest jeszcze zakończona.

Wydaje się, że wyjście polecenia help jest podzielony na dwie części.

The 1st część jest:

Commands may be abbreviated. Commands are: 

The 2nd część jest:

!    delete   literal   prompt   send 
?    debug   ls    put    status 
append   dir    mdelete   pwd    trace 
... 

I wszystkie 1st części są wrtten do strumienia stdout "ftp.exe" przed wszystkimi 2. części . Jak to jest? Dzięki za twoje komentarze.

testowałem z innym dowództwem „ftp.exe” i wydaje się normalne, z wyjątkiem polecenia „Pomoc”

+0

prostu z odsetek, dlaczego jesteś tak zainteresowany wyjściu ftp.exe jeśli nie zamierzasz go używać? – CResults

+1

Witam, CResults. Prowadzę badania dotyczące standardowych strumieni aplikacji konsolowych. A ftp.exe jest jednym z moich celów eksperymentalnych. – smwikipedia

Odpowiedz

5

Powodem dlaczego nie można dostać wejście i wyjście z ftp.exe dlatego wbudowany program ftp.exe firmy Microsoft Windows 2000/XP/Vista używa Console Input/Output.

Nie jest to po prostu przypadek, w którym program ftp nie opróżnia swoich buforów.

Jeśli zastąpisz wywołanie ftp.exe czymś podobnym do cmd.exe, zobaczysz, że działa poprawnie. Problem polega na tym, że próbujesz odczytać dane wyjściowe, których FTP nie wysyła.
Nie można używać zwykłego podejścia do odczytu i zapisu do pliku ftp.exe dziecka. Jest to konsekwencja wdrożenia tej konkretnej aplikacji ftp.exe.


Jeśli naprawdę potrzebujesz, aby zautomatyzować wbudowanego programu ftp Windows, będzie musiał uciekać się do pinvoke a funkcja ReadConsoleOutput win32.

Twoje alternatywy są:

  • użycie innego programu ftp. Prawdopodobnie nie odwołują się do podejścia I/O konsoli, że program wbudowany MS ma
  • używać klasy FTP, takiej jak FtpWebRequest.
  • jeśli nie jest to właściwe lub możliwe, użyj interfejsu sieciowego niskiego poziomu do FTP.

zobacz także: http://discuss.joelonsoftware.com/default.asp?design.4.332503.5

+2

Dziękuję bardzo, Cheeso. Zastanawiam się, dokąd dokładnie wysyła ftp.exe? Jest jeden fakt, którego nie można zignorować, otrzymuję polecenie "pomocy" od StdOut, ale po dość "opóźnieniu" ... – smwikipedia

+0

Cześć, Cheeso, mam nadzieję, że mógłbyś dać mi więcej komentarzy na temat mojego ostatniego zainteresowania. .. dzięki. – smwikipedia

+0

Nie wiem właściwie; ale co próbujesz zrobić? Jeśli chcesz wykonywać operacje FTP, możesz to zrobić na inne sposoby. Dlaczego ograniczenie, które należy użyć ftp.exe, gdy jest to w sposób niepraktyczny, gdy jest zautomatyzowane? – Cheeso

2

Myślę, że problemem jest to, że bufor wyjściowy nie jest jeszcze zaczerwieniona, a więc nie możesz uzyskać pełny wynik polecenia ftp.

Kiedy emitować „quit” polecenie powinno widać wyjście polecenia pomocy.

nie mam rozwiązanie jeszcze, ale wrócę później, jeśli znajdę coś pomocny.

+0

Dzięki, 0xA3. Polecenie "quit" może być obejściem problemu. Ale chcę tylko poznać różnicę między ftp.exe i moim SimpleConsoleOutput.exe. Dlaczego ten drugi może biec płynnie? – smwikipedia

+0

@smwikipedia: Wierzę, że 0xA3 już wyjaśnił, że całkiem dobrze w odpowiedzi -> "bufor wyjściowy nie jest jeszcze przepłukany" –

0

Z doświadczenia (wielokrotnie korzystałem z FTP z wiersza poleceń), lepiej byłoby użyć wtyczki FTP, takiej jak ta Enterprise DT FTP.

ten sposób będziesz mieć pełną kontrolę nad swoim sesji FTP, być w stanie dać lepsze zwrotnej do użytkownika i radzić sobie z błędami w odpowiedni sposób.

Ostatnim punktem, obsługa błędów jest bardzo ważne, gdy mamy do czynienia z FTP.

+0

Myślałem, że to samo, i rzeczywiście, ftp.exe/help wyświetli STDERR. W trybie interaktywnym wyjście przechodzi do STDOUT. –

+0

Ahh ok, dowiadujesz się czegoś codziennie! - Zmienię moją odpowiedź, ale nadal uważam, że uruchamianie ftp.exe jako zewnętrznego procesu jest złym sposobem na obsługę FTP. Jest zbyt wiele rzeczy, które mogą pójść nie tak, aby pozostawić je kodowi zewnętrznemu. – CResults

+2

Tak, znacznie lepiej używać biblioteki FTP lub klasy 'FtpWebRequest'. –

2

ftp.exe po prostu działa. Nie dojdziesz do części "końcowej", ponieważ program ftp.exe nie kończy się na po wydaniu polecenia pomocy, wyświetla monit i czeka na kolejne polecenie.

Jeśli chcesz przeczytać odpowiedź polecenia, trzeba przeanalizować odpowiedź i szukać nowego wiersza.Oznacza to, że masz całą odpowiedź, gdy ponownie zobaczysz linię, taką jak ftp>.

(chyba że masz bardzo dobre powody, aby używać ftp.exe, użyć klasy FtpWebRequest raczej)

+0

Dzięki, nos. Ale jeśli nie dojdę do końca, dlaczego mój program zatrzymuje się tuż po pierwszym wierszu wyjścia polecenia "pomoc"? – smwikipedia

0

próbowałeś ReadLine zamiast Read czytać z przekierowanego wyjścia?

+0

Thansk za odpowiedź. Tak, próbowałem ReadLine(), ReadToEnd() ... żaden z nich nie mógł poprawnie uzyskać danych wyjściowych. – smwikipedia

0

trochę zaniepokojony, że nie jest zamknięcie procesu prawidłowo, Twój kod do czytania wyjście z procesu powinien wyglądać mniej więcej tak:

process.Start(); 

output = process.StandardOutput.ReadToEnd(); // read the output here... 

process.WaitForExit(); // ...then wait for exit, as after exit, it can't read the output 

returnCode = process.ExitCode; 

process.Close(); // once we have read the exit code, can close the process 

nie wiem, czy to by rozwiązać ten konkretny problem chociaż.

Ponadto, dlaczego piszesz „pomoc” do standardowego wejścia, to nie działa, jeśli nie

process.Arguments = "help"; 
+0

Dziękuję za odpowiedź. Piszę polecenie "help" do StdIn, ponieważ chcę emulować interaktywny wiersz polecenia "ftp.exe". – smwikipedia

+0

Ah Widzę. Czy próbowałeś sprawdzić stdout dla '> ftp', a następnie wysyłanie "bye" do stdin? Następnie należy przejść do wywołania WaitForExit, zamiast tylko czekać na więcej danych wejściowych. –

Powiązane problemy