Cześć!!!
A więc umieszczam obiecany kod. Trochę go opisałem ale nie wiem czy to wystarczy bez poprawnego rozumienia jak działa przekierowywanie strumieni w Windows.
Ponieważ tutaj chodzi o plik wsadowy więc opiszę krótko jak to jest z programami konsolowymi. Program który uruchamia się w konsoli posiada swoje domyślne standardowe wejście jakim jest klawiatura, oraz standardowe wyjście którym jest konsola. Windows umożliwia przekierowanie danych zarówno ze standardowego wejścia i wyjścia na inne urządzenie. Przy pomocy konsoli efekt ten jest bardzo łatwo uzyskać wystarczy użyć specjalnych operatorów.
Jeżeli mamy jakiś program
prog.exe który wyświetla nam w konsoli jakieś informacje, to bardzo łatwo możemy to przekierować na plik np.
a.txt:
- Kod: Zaznacz cały
C:\>prog.exe > a.txt
Jeżeli nasz program także umożliwia wprowadzenie jakiś danych za pomocą klawiatury, to możemy zamiast klawiatury użyć np. pliku:
- Kod: Zaznacz cały
C:\>prog.exe < a.txt
No i w końcu jeżeli chcemy aby na zapisane w pliku dane program wydrukował odpowiedź do pliku to wystarczy napisać:
- Kod: Zaznacz cały
C:\>prog.exe < a.txt > b.txt
i w pliku
b.txt będzie
odpowiedź programu na dane z pliku
a.txt.
Wstęp ten był potrzebny aby zrozumieć jak wywoływane są pliki wsadowe *.bat.
Tak naprawdę instrukcje zapisane w plikach wsadowych mogą być równie dobrze zapisane w zwykłych plikach tekstowych i uruchomione poleceniem przekierowania strumienia na program - interpreter tych instrukcji (w tym przypadku
cmd.exe):
- Kod: Zaznacz cały
cmd.exe < polecenia_pliku_bat.txt
Czyli tylko rozszerzenie *.bat mówi systemowi że trzeba dokonać takiego przekierowania i dlatego do uruchomienia pliku wsadowego wystarczy na niego kliknąć.
Weźmy na przykład prosty plik wsadowy a.bat o treści:
- Kod: Zaznacz cały
echo konsola
copy a.txt b.txt
mkdir newdir
uruchamiając taki plik wsadowy w konsoli poleceniem:
- Kod: Zaznacz cały
a.bat
na ekranie pojawi się nam:
- Kod: Zaznacz cały
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\>echo konsola
konsola
C:\>copy a.txt b.txt
1 file(s) copied.
C:\>mkdir newdir
C:\>
W tym wypadku system przekierował treść pliku wsadowego na program
cmd.exe a program
cmd.exe pokazał rezultat na swoim standardowym wyjściu czyli konsoli. Czyli pisząc:
- Kod: Zaznacz cały
cmd.exe < polecenia_pliku_bat.txt > rezultat.txt
w pliku "rezultat.txt" otrzymamy powyższe linie które wcześniej się ukazały w konsoli, natomiast konsola będzie pusta.
Właśnie w ten sposób trzeba podejść do przekierowywania strumieni, czyli jak opisał Cyfrowy Baron jest bardzo nie ścisłe:
Program uruchamia jakiś plik *.BAT zawierający szereg instrukcji, a potem przechwytuje do np. Memo to co jest wyświetlane w tej konsoli na bieżąco, czyli konsola wykonuje po kolei jakieś instrukcje i dokładnie to samo pojawia się w Memo.
Oczywiście też nie do końca ponieważ można uzyskać dostęp do konsoli i z jej bufora i odczytać dane, ale jest to znacznie bardziej skomplikowane.
Proponowane przeze mnie rozwiązanie to utworzenie właśnie mechanizmu (pipe) umożliwiającego przekierowanie danych na inne wejścia/wyjścia standardowe.
Pipe to jest programowy odpowiednik operatorów przekierowania:
'<' '>'.
Więc w moim rozwiązaniu to wszystko działa tak:
Wczytujemy dowolny plik w formacie tekstowym w którym są zapisane instrukcje do wykonania przez jakiś program (tutaj cmd.exe). Następnie tworzymy interfejs przekierowań w obie strony. Tak aby można było pisać do procesu i wyciągać rezultaty (zupełnie jak w przypadku
C:\>prog.exe < a.txt > b.txt), gdzie
prog.exe to nasz
cmd.exe,
a.txt to nasz
plik wsadowy a
b.txt to np.
Memo.
Interfejs pipe zawsze posiada dwa końce (jak to rura) jeden do czytania i drugi do pisania. Tak więc definiując pipe dla standardowego wyjścia mamy dwa uchwyty jeden do pisania na to wyjście a drugi do odczytu co tam zapisano. Podobnie jest dla wejścia. W sumie daje nam to 4 uchwyty.
W podesłanym archiwum znajdziecie wszystko co potrzeba
na początek. Znajdziecie tam klasę
pipeCtrl zdefiniowaną w plikach:
pipe_ctrls.h i
pipe_ctrls.cpp, która udostępnia prosty interfejs do kontroli pipe-ów, oraz przykładowy programik który pokazuje jak jej użyć (bardziej ambitnych odsyłam do lektury
http://msdn.microsoft.com). W razie pytań, sugestii, uwag piszcie!!!
Pliki zawierają konfigurację którą można zmienić w zależności od uruchamianych procesów. Może się okazać że ustawiony bufor jest za mały, lub czas oczekiwania na przetworzenie danych za krótki.
Wszystko można sobie pozmieniać według upodobań.
UWAGA Mam specyficznie skonfigurowanego BCB i do tego dużo różnych dodatków, więc nie wiem czy będzie chciał poprawnie skompilować plik
.bpr. Jeżeli nie to proponuje najprostsze rozwiązanie, utworzyć nowy projekt i dodać moje pliki do tego projektu:
pipe_ctrls.cpp oraz
Unit1.cpp. Natomiast sam program powinien się uruchomić bez problemu.
Powodzenia
P.S. Taka mała uwaga co do formatu pliku instrukcji.
Ostania linia pliku powinna być pusta, czyli po ostatniej nie pustej linii wystarczy enter.Mam nadzieje że wszystko działa!! Proszę o
feedback bo kod troszkę zmieniłem i nie wiem czy bug-a gdzieś nie walnąłem!!
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
If a machine is expected to be infallible, it cannot also be intelligent.
-- A.Turing