Dziwne zachowanie funkcji RunProcessAndWait

Odpowiedz Nowy wątek
2017-11-08 19:46
0

Witam serdecznie. Mam stworzoną aplikację w Lazarusie a w niej buttony uruchamiające aplikacje za pomocą funkcji RunProcessAndWait. No i teraz o co tak naprawdę mi chodzi. Jeżeli aplikacja którą chce wywołać za pomocą aplikacji(zrobionej przez Lazarusa) posiada na sobie prawa administratora, to jakby "wywoływanie" dzieje się w folderze w którym znajduje się aplikacja Lazarusa.

Przykład:
Aplikację z Lazarusa "autorun.exe" mam na pulpicie w folderze "kk" i nią chce wywołać plik bat(uprzednio skonwertowany do .exe), który znajduje się w "E:\setap.exe" i okienko z Windowsa pięknie nam przedstawia że coś jest nie tak ponieważ działania tej aplikacji dzieją się w folderze "kk" na pulpicie, a nie na dysku E jak powinno być. Poniżej przedstawię wycinek z konsoli:
title

Nie wiem czego to wina a potrzebuję otworzyć program który z kolei potrzebuje dodatkowe pliki do jego poprawnego działania i w efekcie wyskakuje error brakujących plików. W tym przypadku jak widać postanowiłem zrobić coś na bazie konsoli aby dokładnie zobaczyć co się dzieje no i już wiadomo jednak nie wiem co jest tego przyczyna i jak temu zaradzić. I jak mówiłem dzieje się to tylko na plikach, które mają na sobie nałożone "prawa administratora" tzn w właściwościach zaznaczone jest okienko uruchom jako administrator.

Pozdrawiam.

edytowany 3x, ostatnio: Eazy, 2017-11-08 19:54

Pozostało 580 znaków

2017-11-08 19:58
0

RunProcessAndWait to nie jest funkcja, a metoda proceduralna – tak samo jak RunProcessAsAdminAndWait. Poza tym, nie znajduje się w bibliotece standardowej, więc nikt nie wie (oprócz mnie) jak działa.


edytowany 1x, ostatnio: furious programming, 2017-11-08 19:59

Pozostało 580 znaków

2017-11-08 20:01
0

Niestety nie jestem obeznany w 100% i nie wiedziałem że to metoda proceduralna aczkolwiek podobno korzysta z "CreateProcess" więc może się ktoś wypowie na ten temat?

Pozostało 580 znaków

2017-11-08 20:02
Trzeźwy Programista
0

Ja nic nie zrozumiałem z tego co napisałeś, wrzuć kod źródłowy.

A dobra środowisko envirioment zawiera ścieżkę path aktualnego katalogu, zmień sobie i tyle.

edytowany 1x, ostatnio: furious programming, 2017-11-08 20:05

Pozostało 580 znaków

2017-11-08 20:08
0

Na pulpicie mam apke autorun.exe i przez nią uruchamiam plik, który znajduje się na dysku E(setap.exe z prawami administratora).

Problem w tym że autorun.exe normalnie wywołuje ten plik z "E" natomiast działania w konsoli(setap.exe) dzieją się tam gdzie znajduje sie aplikacja Lazarusa m.in autorun.exe. Wszystko zostało zobrazowane tak naprawdę w screenie jaki zapodałem wyżej.

Tutaj kodzik a raczej jego urywek - dodam że "FGamePath" ma szukać lokalizację na podstawie rejestru tak jak w tym przypadku jest to "E":

procedure TMainForm.CSetupButtonClick(ASender: TObject);
begin
  try
    FProcessing := True;

    PrepareButtons();
    Application.ProcessMessages();

    if FileExists(FGamePath + 'setap.exe') then
    begin
      if not RunProcessAndWait(FGamePath, 'setap.exe') then
        RunProcessAsAdminAndWait(FGamePath, 'setap.exe');
    end
    else
      ShowError('nie można odnaleźć pliku setap.exe', 'title');
  finally
    FProcessing := False;

    PrepareInstallationData();
    PrepareButtons();
  end;
end;   
edytowany 2x, ostatnio: furious programming, 2017-11-08 20:13

Pozostało 580 znaków

2017-11-08 20:11
Trzeźwy Programista
1

A te setap jak ręcznie odpalisz na pulpicie, to gdzie się wykonuje?

Pozostało 580 znaków

2017-11-08 20:14
0

@Trzeźwy Programista

Chciałeś powiedzieć kiedy go wywołuję z dysku E? To wtedy działa poprawnie i otwiera plik znajdujący się obok(screen obrazuje działanie).

Plik setap.exe ma uruchomić plik setup.exe a oba znajdują się obok siebie. Kiedy wywołuje setap.exe to ten powinien uruchomić program obok natomiast tak się nie dzieje i szuka on tego pliku obok aplikacji Lazarusa.

Pozostało 580 znaków

2017-11-08 20:16
Trzeźwy Programista
1

Jak dla mnie ten converter bat na exe statycznie zlinkował położenie, daj jeszcze plik bat.

Pozostało 580 znaków

2017-11-08 20:20
0

Raczej nie ma takiej możliwości bo jak pisałem wywołując bezpośrednio tego problemu nie ma. Przypominam też ze dzieje się to na plikach z uprawnieniami administratora. A cały ten pliczek .bat stworzyłem po to bo właściwa aplikacja którą chce wykorzystać zachowuje się podobnie i chciałem sobie zobrazować co może być nie tak - potrzebuje ona dodatkowe pliki i uruchamiając bezpośrednio z dysku działa bez problemu natomiast przez Lazarusa brakuje jej dodatkowych plików niezbędnych do działania.

echo Nacisnij dowolny klawisz aby kontynuowac...
start setup.exe
pause

Pozostało 580 znaków

2017-11-08 20:28
0

Tutaj kod jak się te 2 procedury zachowują - być może gdzieś tu jest błąd?

function TMainForm.RunProcessAndWait(const APath, AFileName: String): Boolean;
var
  LStartup: TStartupInfo;
  LProcess: TProcessInformation;
var
  LCommand: String;
  LFlags: DWORD;
begin
  Result := False;

  FillChar(LStartup{%H-}, SizeOf(LStartup), 0);
  FillChar(LProcess{%H-}, SizeOf(LProcess), 0);

  LStartup.cb := SizeOf(LStartup);
  LStartup.dwFlags := STARTF_USESHOWWINDOW;
  LStartup.wShowWindow := SW_SHOW;

  LCommand := APath + AFileName;
  LFlags := NORMAL_PRIORITY_CLASS;

  Result := CreateProcess(nil, PChar(LCommand), nil, nil, False, LFlags, nil, PChar(APath), LStartup, LProcess);

  if Result then
  begin
    repeat
      Application.ProcessMessages();
    until (WaitForSingleObject(LProcess.hProcess, 20) <> WAIT_TIMEOUT);

    CloseHandle(LProcess.hProcess);
    CloseHandle(LProcess.hThread);
  end;

  Application.ProcessMessages();
end;

procedure TMainForm.RunProcessAsAdminAndWait(const APath, AFileName: String);
var
  LShellInfo: TShellExecuteInfo;
  LExitCode: DWORD = 0;
begin
  FillChar(LShellInfo{%H-}, SizeOf(LShellInfo), 0);

  LShellInfo.cbSize := SizeOf(TShellExecuteInfo);
  LShellInfo.wnd := Self.Handle;
  LShellInfo.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_NOCLOSEPROCESS;
  LShellInfo.lpVerb := PChar('runas');
  LShellInfo.lpFile := PChar(APath + AFileName);
  LShellInfo.nShow := SW_SHOW;

  if ShellExecuteExA(@LShellInfo) then
  repeat
    Application.ProcessMessages();
    GetExitCodeProcess(LShellInfo.hProcess, LExitCode);
  until LExitCode <> STILL_ACTIVE;

  Application.ProcessMessages();
end;                                
edytowany 2x, ostatnio: furious programming, 2017-11-08 20:45

Pozostało 580 znaków

2017-11-08 20:42
Szalony Mleczarz
0
echo Nacisnij dowolny klawisz aby kontynuowac...
start setup.exe
pause

I taki skrypt na pulpicie odpala setup.exe z dysku E?

edytowany 2x, ostatnio: furious programming, 2017-11-08 21:27

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0