WinApi Wykonywanie komendy wiersza poleceń za pomocą okienka


(Julek94) #1

Witam,

Mam problem. Piszę program w WinAPI, który ma wykonywać komendę systemową z konsoli (net.exe do łączenia się z sambą). Nie wiem jednak jak obsłużyć zwracane komunikaty, np. gdy serwer jest niedostępny, to wpisując z konsoli tą komendę, otrzymuję systemowy kod błędu: 1231, ale gdy wykonuję tą komendę z poziomu CreateProcess, czy WinExec, nie dostaję kodu błędu ze wzgl. na to, że proces net.exe sam w sobie się uruchomił, jak otrzymać kod zwracany przez uruchamiany przeze mnie proces? Dodam, ze wolałbym za pomocą WinExec, bo CreateProcess, na chwilę, ale jednak uruchamia konsolę i zamyka ją, chciałbym, aby ta konsola była zupełnie niewidoczna. (No chyba, że źle używam CreateProcess, więc napiszę, jak go używam :

CreateProcess("C:\\WINDOWS\\system32\\net.exe", command, NULL, NULL, FALSE, 0, NULL, NULL, &si, π);

)

Tak więc jak otrzymać kody błędu z uruchomionego procesu aby je obsłużyć i wyśpietlkić odpowiednie komunikaty?

Z góry dzięki za pomoc.

Pozdrawiam


([alex]) #2

Pobranie wyniku - GetExitCodeProcess

Jak nie chcesz widzieć okna to daj:

    si.cb=sizeof(si);si.dwFlags=STARTF_USESHOWWINDOW;si.wShowWindow=SW_HIDE; [/code]

przed CreateProcess

(Julek94) #3

Dzięki, na prawdę wielkie dzięki, bardzo mi pomogłeś, tylko mam jeszcze jedno pytanie.

W ten sposób obsługuję tak naprawdę tylko jeden komunikat. Jeżeli GetExitProcess() zwraca zero, to ok, zalogowano, ale jeżeli coś jest nie tak, to niestety nie zwraca tych błędów tak jak w przypadku wywołania tej komendy z palca, tzn, np. jeżeli nie znaleziono serwera, to net.exe wpisany z palca pokazuje kod błędu 53, jeżeli błędne dane logowania, to jeszcze jakiś tam inny. GetExitCodeProcess() zwraca w każdym przypadku nieudanej próby połączenia wartość 2, czyli jak wyczytałem na msdn, to jest ERROR_FILE_NOT_FOUND, jakby nie mógł znaleźć net.exe, co jest nie prawdą, bo przecież, jak podaje się prawidłowe dane logowania, to jest wszystko ok, chciałbym zrobić obsługę większej ilości błędów, np. źle wpisane dane logowania, serwer nie odpowiada, zalogowano już innego użytkownika, dysk jest zajęty itd, te wszystkie komunikaty normalnie zrwaca net.exe odpalany z palca. Dla ułatwienia podam kilka linikej kodu:

if(CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, π))

{

   WaitForSingleObject(pi.hProcess, INFINITE);

if(!GetExitCodeProcess(pi.hProcess, &exitCode))

{

//błąd, pobranie kodu błędu zakończone niepowodzeniem

}

if(exitCode == 0) //zalogowano

else //tutaj reszta błędów, narazie nie mam co tu pisać, bo i tak zawsze zwraca wartość 2, niezależnie od tego jaki to błąd w rzeczywistości

}

else

{

//CreateProcess niepowiódł się

}

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

zmienna command wygląda mniej więcej tak:

"c:\WINDOWS\system32\net.exe use z: \\serwer\login haslo /user:login"

I tak jak powiedziałem wcześniej, jeżeli wszystko jest ok, czyli serwer włączony, login i hasło podane poprawnie, to wszystko działa dobrze, jednak jeżeli coś jest nie tak, to GetExitCodeProcess i tak zwraca 2 :confused:

Robię coś nie tak?

Jak powinienem to poprawić?

Jeszcze raz dzięki za pomoc

Pozdrawiam


([alex]) #4

To przeczytaj uważnie:

hProcess [in]

A handle to the process.

The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right. For more information, see Process Security and Access Rights.

Windows Server 2003 and Windows XP/2000: The handle must have the PROCESS_QUERY_INFORMATION access right.


(Julek94) #5

Owszem, tylko, że ten program ma docelowo pracować na Windows NT4. Efekt jest taki sam i na XP i na NT4.

Poza tym, to jak mogę nadać taki przywilej temu procesowi?

EDIT:

Nie było pytania, niezauważyłem, że 3 argument w CreateProcess odpowiada za przywileje

EDIT2:

A jednak... w takim razie jak nadać owe uprawnienia i czy ja ich już przypadkiem nie posiadam?

Na MSDN wyczytałem również coś takiego:

The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object.

Czyli wygląda, że mam pełne prawa nad tym procesem...

W takim razie co mogę jeszcze zrobić? O czym nie wiem? :smiley:

Dobra, do zamknięcia, znalazłem inne rozwiązanie.

Mianowicie poczytałem o CreatePipe i o używaniu tego. Teraz po prostu messageboxem wyświetlam dokładnie ten sam komunikat który pokazywałby się w konsoli, niezależnie od tego co to za błąd. Musiałem do tego napisaćź jeszcze funkcję tłumaczącą polskie litery w postaci krzaczków z konsoli (inne kodowanie w konsoli i inne w programie okienkowym) na ich polskie odpowiedniki. Wszystko działa jak należy, mimo tego, że GetLastError zwraca błąd 109 (The pipe has been ended.) po zamknięciu pipe'a (zamykam, zaraz po funkcji createProcess, ponieważ w innym miejscu owocuje to zawieszeniem się programu, choć nie do końca wiem dlaczego, zamykanie wygląda tak: CloseHandle(pipeWrite):wink: co teoretycznie nie powinno być błędem, bo przecież osobiście go zamykam. Nie wiem jak to poprawić, ale mniejsza o to, ważne, że działa

Pozdrawiam