ShellExecute i iconv.exe problem z przekazaniem parametrów

dział ogólny

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 14:56

Cyfrowy Baron napisał(a):Wynika więc z tego, że wartość STARTF_USESTDHANDLES nie ma nic wspólnego z elementem wShowWindow, gdyż go nie dotyczy.

Tyle że flaga ta musi być ustawiona, żeby uwzględniało uchwyty plików hStdInput i hStdOutput .

Darek_C++ napisał(a):(...) czy można zmienić standardowe wyjście hStdOutput w tym wypadku z zapisania do pliku na zmianną , lub TMemo ?

Hmm... na zmienną może nie, ale rurę (pipes) możesz podłączyć.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 15:13

Przyznam się, że chyba jestem za cienki by sam sobie z rura poradzić :(
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 15:22

CreatePipe + ReadFile + trochę pomyślunku i będzie git. Wszystkie niezbędne szczegóły są w dokumentacji, pod linkiem, który podałem.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Cyfrowy Baron » sobota, 19 czerwca 2010, 15:28

polymorphism napisał(a):Tyle że flaga ta musi być ustawiona, żeby uwzględniało uchwyty plików hStdInput i hStdOutput .


Przecież tak właśnie napisałem:

Cyfrowy Baron napisał(a):Ta druga wartość podana przez ciebie czyli STARTF_USESTDHANDLES jest potrzebna dla elementów hStdInput i hStdOutput, gdyż wypełniasz zarówno element wShowWindow jak też elementy hStdInput i hStdOutput.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 15:30

Chyba będę musiał posiłkować się pośrednictwem zapisu do pliku i wczytania z niego danych zamiast tej rury :|
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 15:33

Cyfrowy Baron napisał(a):Przecież tak właśnie napisałem: (...)

Dopisałeś. Odnosiłem się do wersji pierwotnej.

@Darek_C++, nie przesadzasz? Z tego co widzę w dokumentacji, stworzenie i użycie z rury nie wygląda na coś bardziej skomplikowanego niż otworzenie i czytanie pliku za pomocą funkcji WinAPI. Więc zamiast biadolić, że coś Ci nie wyjdzie, poeksperymentuj, spróbuj chociaż.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 15:54

Stworzyłem coś takiego:
Kod: Zaznacz cały
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   float Start = GetTickCount();
   SECURITY_ATTRIBUTES sa;
    sa.nLength              =   sizeof  (   SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor =   NULL;
   sa.bInheritHandle       =   TRUE;

   HANDLE hRead;
  HANDLE hWrite;
  char buffer[1024];
  DWORD bytesRead;

   SECURITY_ATTRIBUTES sat;
    STARTUPINFO si;
    ZeroMemory( &si, sizeof(STARTUPINFO));

    si.cb = sizeof(STARTUPINFO);
   si.dwFlags    = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
   si.wShowWindow = SW_HIDE;

   //Tworzenie potoku...
   sat.nLength  = sizeof(SECURITY_ATTRIBUTES);
   sat.lpSecurityDescriptor =  NULL;
   sat.bInheritHandle = TRUE;
   CreatePipe((PHANDLE)&hRead, (PHANDLE)&hWrite, &sat, NULL);

    /* wejście */
   si.hStdInput = CreateFile("E:\\php\\test.php",
                GENERIC_READ,
                FILE_SHARE_READ,
                &sa,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);

   /* wyjście */
   /**
   si.hStdOutput = CreateFile("E:\\php\\outtest.txt",
                GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                &sa,
                CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
            NULL);
   */
   si.hStdOutput  = (PHANDLE)hWrite;
   si.hStdError  = (PHANDLE)hWrite;

    PROCESS_INFORMATION ProcessInfo;


    if(CreateProcess(NULL,
                    "E:\\php\\php-cgi.exe",
                    NULL,
                    NULL,
                    TRUE,
               NORMAL_PRIORITY_CLASS,
                    NULL,
                    NULL,
                    &si,
                    &ProcessInfo))
    {
        WaitForSingleObject(ProcessInfo.hProcess,INFINITE); //<--- czekamy...
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
   }

   RtlZeroMemory(buffer, 1024);
    ReadFile(hRead, buffer, 1023, &bytesRead, NULL);
   Memo1->Lines->Add( buffer );

    CloseHandle(si.hStdInput);
   CloseHandle(si.hStdOutput);
   float End = GetTickCount();
   Edit1->Text =  FloatToStr((End - Start) / 1000) + " s.";
   //   Memo1->Lines->LoadFromFile("E:\\php\\outtest.txt");
}

W tym wypadku uruchamiam PHP który wykonuje jakiś kod jeśli efekt wykonania kodu nawet

<?php
echo file_get_contents('http://www.google.pl');
?> czyli pobranie kodu strony google idzie do pliku jest OK, ale jeśli ma iść na Memo1 program się zawiesza. Program działa jeśli dane wyjściowe są mniejsze.






polymorphism napisał(a):@Darek_C++, nie przesadzasz?

Zależy jak Podchodzisz do klimatu forum i pomoc jako takiej. Dla kogoś dobrze znającego dany język pewne kwestie wydają się bardzo łatwe. Jednak dla kogoś kto mniej zna sprawa wygląda inaczej...
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 16:39

Dla kogoś dobrze znającego dany język pewne kwestie wydają się bardzo łatwe. Jednak dla kogoś kto mniej zna sprawa wygląda inaczej...

Widzisz, tu nie chodzi o język, tylko o umiejętność samodzielnego tudzież kreatywnego myślenia. To w programowaniu jest bardzo ważne i tego wymagam od ludzi zajmujących się programowaniem. Dla mnie pomoc to podpowiedź lub wskazanie błędu, a nie pisanie za kogoś kodu. Przez moment odniosłem wrażenie, że czekasz na gotowy kod, pisząc "nie umiem, jestem za cienki", pomimo że dostałeś pewne wskazówki. Takie podejście rzadko spotyka się ze zrozumieniem (no i się mści, bo po paru latach programowania taki delikwent nic nie umie 8-) ).

--- za moment odniosę się do kodu ---
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 16:42

Panie Kolego nie od razu Kraków zbudowano....
Usiłowałem też odczytać to w ten sposób:
Kod: Zaznacz cały
const int bufSize = 1024;
   char buf[bufSize];
  // DWORD bytesRead;
   while (ReadFile(hRead, buf, bufSize-1, &bytesRead, 0) && (bytesRead > 0))
   {
     buf[bytesRead] = 0;
     // dopisz buf do stringu, editboxa...
   }

ale program się zawiesza
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 17:35

Zawiesza się dlatego, ponieważ ReadFile blokuje w momencie, gdy rura jest opróżniona. Funkcja zachowuje się podobnie do recv, która czeka na dane jeśli nie ma ich w sockecie.

Check it out:
Kod: Zaznacz cały
char buffer[10000];
DWORD bytes_read;
DWORD bytes_avail;
string out; //<--- to jest przykladowo

while(PeekNamedPipe(hReadPipe,NULL,0,NULL,&bytes_avail,NULL) &&
    bytes_avail > 0 &&
    ReadFile(hReadPipe,buffer,10000,&bytes_read,NULL))
{
    out.append(buffer,buffer + bytes_read);
}
 

Wywołaj to za WaitForSingleObject, bo wtedy jest pewność, że aplikacja coś wtłoczyła do rury, choć nie wiem jak to będzie wyglądać z dużymi ilościami danych, przy przepełnieniu bufora rury. Najlepiej byłoby czytać przed zamknięciem aplikacji, ale to nie przejdzie z tą pętlą, trzeba by jakiś timeout ustawić jeśli bytes_avail == 0. No ale nieważne...

--- DODANE ---

...a może i ważne :D Tu masz pewniejszy algorytm czytania:

  1. funkcją PeekNamedPipe sprawdź, czy w rurze są jakieś dane do przeczytania.
    1. jeśli są, skok do 2
    2. jeśli nie ma, sprawdź funkcją WaitForSingleObject, czy aplikacja jest aktywna.
      • jeśli jest, daj Sleep(1) i skocz do 1
      • jeśli nie jest, skok do 3
  2. czytasz dane funkcją ReadFile i skok do 1
  3. koniec pętli
Całość dajesz zaraz po CreateProcess.


Panie Kolego nie od razu Kraków zbudowano....

...ale zbudowano. Nikt za budowniczych tego nie zrobił 8-)
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 18:51

Zostawmy Kraków na inną okazję, bo program nadal nie działa do końca poprawnie :(
Działa jeśli dane wynikowe z PHP są niewielkie, ale jak ich jest więcej np kod wywołania funkcji :

<?php
phpinfo();
?>



jest dosyć duży plik utworzony przy wyjściu nie do rury, ale na pilik ma 40,1 KB (bajtów: 41 105) przy wyjściu do pliku działa [0,094 s.]
Ale przy odczytywaniu przez rurę program się zawiesza.
Poniżej zamieszczam cały kod może będzie łatwiej dojść dlaczego tak się dzieje - co mam źle w tym kodzie;

Kod: Zaznacz cały
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   float Start = GetTickCount();
   SECURITY_ATTRIBUTES sa;
    sa.nLength              =   sizeof  (   SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor =   NULL;
   sa.bInheritHandle       =   TRUE;

   HANDLE hRead;
   HANDLE hWrite;

   SECURITY_ATTRIBUTES sat;
   STARTUPINFO si;
    ZeroMemory( &si, sizeof(STARTUPINFO));

    si.cb = sizeof(STARTUPINFO);
   si.dwFlags    = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
   si.wShowWindow = SW_HIDE;

   //Tworzenie potoku...
   sat.nLength  = sizeof(SECURITY_ATTRIBUTES);
   sat.lpSecurityDescriptor =  NULL;
   sat.bInheritHandle = TRUE;
   CreatePipe((PHANDLE)&hRead, (PHANDLE)&hWrite, &sat, NULL);

    /* wejście */
   si.hStdInput = CreateFile("E:\\php\\test.php",
                GENERIC_READ,
                FILE_SHARE_READ,
                &sa,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);

   /* wyjście */
   /**
   si.hStdOutput = CreateFile("E:\\php\\outtest.txt",
                GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                &sa,
                CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
            NULL);
   */
   si.hStdOutput  = (PHANDLE)hWrite;
   si.hStdError  = (PHANDLE)hWrite;

   PROCESS_INFORMATION ProcessInfo;


   if(CreateProcess(NULL,
               "E:\\php\\php-cgi.exe",
                    NULL,
                    NULL,
                    TRUE,
               NORMAL_PRIORITY_CLASS,
                    NULL,
                    NULL,
                    &si,
                    &ProcessInfo))
    {
        WaitForSingleObject(ProcessInfo.hProcess,INFINITE); //<--- czekamy...
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
   }
   // odczytanie tego co proces wypluł na stdout;

    char buffer[10240];
    DWORD bytesRead;
    DWORD bytes_read;
    DWORD bytes_avail;
   std::string out; //<--- to jest przykladowo

   while(PeekNamedPipe(hRead,NULL,0,NULL,&bytes_avail,NULL) &&
        bytes_avail > 0 &&
      ReadFile(hRead,buffer,10239,&bytes_read,NULL))
    {
        out.append(buffer,buffer + bytes_read);
   }
   Memo1->Lines->Add(out.c_str() );

   CloseHandle(hRead);
        CloseHandle(si.hStdInput);
   CloseHandle(si.hStdOutput);

   float End = GetTickCount();
   Edit1->Text =  FloatToStr((End - Start) / 1000) + " s.";

}

Więc ponownie zwracam się z prośba o pomoc...
Ostatnio edytowano sobota, 19 czerwca 2010, 18:54 przez Darek_C++, łącznie edytowano 1 raz
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 18:54

Czyli moje obawy się potwierdziły... U góry masz inny algorytm czytania, który dopisałem.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 18:58

Ale po co mam sprawdzać czy dane są w rurze skoro wiem, że są. Zostaje kwestia ich odczytania.... i po co stosować mam te sekundowe opóźnienie ?
Poza tym jak już pisałem problem występuje przy czytaniu większej ilości danych z rury.
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez polymorphism » sobota, 19 czerwca 2010, 19:04

Ale po co mam sprawdzać czy dane są w rurze skoro wiem, że są.

Tak? A wiesz dokładnie ile bajtów jest w rurze i co ile bajtów aplikacja flushuje swój bufor, że możesz sobie robić takie założenia na sztywno?

Skąd to 10240?!

Zostaje kwestia ich odczytania....

Ot, drobiazg...

i po co stosować mam te sekundowe opóźnienie ?

Żeby nie zarzynać procesora. I nie sekundowe, tyko milisekundowe. Dokumentacja się kłania...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ShellExecute i iconv.exe problem z przekazaniem parametrów

Nowy postprzez Darek_C++ » sobota, 19 czerwca 2010, 19:14

polymorphism napisał(a):Skąd to 10240?!.

a skąd te Twoje 10000 char buffer[10000];
moje to 10 * 1024
Dokumentacja się nie musi się od razu kłamać, bo pomyliłem z PHP gdzie jest to właśnie sleep(1) jedna sekunda.
----
Tak czy inaczej podany przez Ciebie kod sparwdza czy jest coś w rurze jednak wiesza program wiec nie jest prawidłowy...
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Poprzednia stronaNastępna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 10 gości