Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno spusteni console pres shellexecute

Ahoj vsem, mam prikaz

ShellExecute(GetDesktopWindow,nil,'cmd.exe',pchar(' start '+edit1.text),pchar(dir1), SW_shownormal);

kdyz toto zadam nespusti se mi console, nevite nekdo jak na to aby se to spustilo v cmd jako kdyz pouziji soubor *.bat.
Program delam pro restart serveru a nestaci *.bat protoze server se obcas sekne a nenajede ani *.bat nepomuze.
Pro consoli zadavam cestu i s *.exe ale najede jen dany adresar kde console je ale aplikace se jiz nespusti.
program funguje tak ze vse hlida z SQL database kdyz padne, program ji ma restartovat ale nic se neprovede.
Pokud dam prikaz

ShellExecute(GetDesktopWindow,nil,pchar(edit1.text),'','', SW_shownormal);

consolova aplikace najede a hned spadne.

Předmět Autor Datum
Neviem ale pozeram si ShellExecute v MSDN ShellExecute( HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFi…
MM.. 29.05.2007 19:30
MM..
1. musíš uvést celou cestu k CMD.EXE 2. použij parametr /K, okno se hned nezavře Ta dávka by fungov…
Jan Fiala 29.05.2007 19:37
Jan Fiala
Program ktery to ma hlidat je _realmserver.exe je to console kterou kdyz spustim samostatne jede ale…
virus 29.05.2007 19:42
virus
Mozes trochu objasnit co myslis tym "ale pri zadani prikazu i s cestou"?
MM.. 29.05.2007 19:44
MM..
Nejak som nepochopil čo vlastne chceš spustiť? Načo spúšťať príkazový riadok cmd.exe a v ňom potom č…
pme 29.05.2007 19:45
pme
Popisi to takto, _realmserver ma vlastni databasi a do nej zapisuje status ON - OFF samotnej program…
virus 29.05.2007 19:59
virus
a co urobi ShellExecute(0,nil,'cmd.exe','c:\server\_realmserver.exe','c:\server\', SW_shownormal);…
MM.. 29.05.2007 20:06
MM..
Takze jsem zkusil vsechny moznosti, co jsou zde vypsany ani jedna nepomohla, zjistil jsem totiz ze p…
virus 29.05.2007 20:31
virus
A odkial alebo z akeho adresara spustas ten program rucne tak aby fungoval? Resp. vobec nerozumiem t…
MM.. 29.05.2007 20:34
MM..
Ak chceš silou mocou ShellExecute tak tu máš aj s čakaním na ukončenie aplikácie: uses ShellApi; pr…
pme 29.05.2007 20:22
pme
Prípadne si výstup programu zachytitíš napr. do Tmemo: {....} private function RunCaptured(const _d…
pme 29.05.2007 20:26
pme
Diky moc (pme) uz to beha jak ma :beer::-)
virus 29.05.2007 20:54
virus
Dobrý den, tohle se mi moc líbilo, zkoušel jsem to modifikovat tak, aby se do mema vypisoval postup…
Barborak 22.07.2010 23:51
Barborak
Poradte lamě. Kde dělam kopanec. zkoušim to rozchodit a vše kde je Windows je podtržene červeně. tm… poslední
Borisek 23.05.2012 05:36
Borisek

Neviem ale pozeram si ShellExecute v MSDN
ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
Operation davas null takze defailtne sa pouzije "open", na subor cmd.exe, a parametre prikazovej riadky zasa 'start ...'?

Spravne by malo byt to druhe, ako "spadne"? zavre sa konzola po skonceni aplikacie? (to je spravne) alebo nejako inac? Skus mu dat default directory nejaky normalny a nie '', a lpParameters skus dat nil, alebo nieco hocico :-)

P.S. alebo skus to s cmd.exe a do parametrov mu daj len to exe ktore sa ma spustit, bez ' start '
mozes mu dat namiesto start parameter ' /k '+edit1.text ak chces aby sa konzola po skonceni aplikacie neukoncila.

1. musíš uvést celou cestu k CMD.EXE
2. použij parametr /K, okno se hned nezavře

Ta dávka by fungovat měla.
Co se týká SQL serveru, i když se sekne, mělo by pomoct zastavit službu a znovu ji spustit (popř. bude misto SQLSERVER jméno instance):

Restart.BAT:

NET STOP SQLSERVER
NET START SQLSERVER
ShellExecute(0, 'Open', PChar(Disk:\cesta\Restart.bat), nil, nil, SW_SHOWNORMAL);

Možná by stálo za to zjistit a odstranit příčinu "sekání"

Nejak som nepochopil čo vlastne chceš spustiť? Načo spúšťať príkazový riadok cmd.exe a v ňom potom čo spúšťaš ?
Ak chceš spustiť nejakú applikáciu tak použi WinExec:

Príklady:
WinExec('C:\NC.exe', SW_NORMAL); { DOS program }
WinExec('notepad.exe', SW_MAXIMIZED); { Windows program }
WinExec("command.com /c progdos.exe",sw_ShowNormal); program, ktorý zavrie okno po spustení

Popisi to takto, _realmserver ma vlastni databasi a do nej zapisuje status ON - OFF samotnej program dost pada a je potreba ho casto rucne restartovat.
Takto kdyz to zapisi, aplikace realmserver se spusti a hned vypadne ani neni videt proc

ShellExecute(0,nil,'c:\server\_realmserver.exe','','', SW_shownormal);

Samostatne kdyz ji spustim tak jede, pres tento zpusob ne, nevim proc tomu tak je.
Zkousel jsem zadat i cestu v parametru dir ani to nepomohlo.

a co urobi

ShellExecute(0,nil,'cmd.exe','c:\server\_realmserver.exe','c:\server\', SW_shownormal);

?
Prip.

ShellExecute(0,nil,'cmd.exe','/k c:\server\_realmserver.exe','c:\server\', SW_shownormal);

aby sa nezavrela konzola a videl si preco to padlo.
Prip.

ShellExecute(0,nil,'c:\server\_realmserver.exe',nil,'c:\server\', SW_shownormal);

Prip.

ShellExecute(0,nil,'c:\server\_realmserver.exe','tralala','c:\server\', SW_shownormal);

Prip. niektore z dalsich rieseni ktore su vyssie? (WinExec('program.exe'))

Takze jsem zkusil vsechny moznosti, co jsou zde vypsany ani jedna nepomohla, zjistil jsem totiz ze pokus server spustim pomoci jakehokoliv prikazu v aplikaci tak jakoby se priradi pod adresar v kterem neni, tim padem se ztrati config,libmysql.dll a python25.dll, a druhy server ktery se na nej napojuje totez.
Kdyz dam muj program k serveru spusti ten v kterem je bez problemu ale druhy ne kazdy ten server ma svuj adresar a svou knihovnu libmysql.dll kera je velikosti jina.
prenastavit nazev knihoven nejde v tomto spociva velkej orech co stim.
Kdyz to dam pres *.bat spusti se oba ale nelze je aplikaci v pripade zaseknuti ukoncit.
Na ukonceni pouzivam vlastni FCE s pomoci Tlhelp32.
Po ukonceni by mela zase nabehnout, servery musi byt samostatne nelze je dat do jednoho adresare, prepsal by se config a nesel by spustit vubec to same libmysql.dll.

A odkial alebo z akeho adresara spustas ten program rucne tak aby fungoval?
Resp. vobec nerozumiem tomu co pises. Napis presne ako rucne spustas ten program aby fungoval. Napr. si v konzole

C:\akyadresar> akyprogram.exe akeparametre

P.S. potom az si tam dosadis co tam rucne mas, tak to bude vyzerat takto:
ShellExecute(0, nil, 'akyprogram.exe', 'akeparametre' alebo nil, 'C:\akyadresar', SW_shownormal);

Ak chceš silou mocou ShellExecute tak tu máš aj s čakaním na ukončenie aplikácie:

uses
  ShellApi;

procedure ShellExecute_AndWait(FileName: string; Params: string);
var
  exInfo: TShellExecuteInfo;
  Ph: DWORD;
begin
  FillChar(exInfo, SizeOf(exInfo), 0);
  with exInfo do
  begin
    cbSize := SizeOf(exInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := GetActiveWindow();
    ExInfo.lpVerb := 'open';
    ExInfo.lpParameters := PChar(Params);
    lpFile := PChar(FileName);
    nShow := SW_SHOWNORMAL;
  end;
  if ShellExecuteEx(@exInfo) then
    Ph := exInfo.HProcess
  else
  begin
    ShowMessage(SysErrorMessage(GetLastError));
    Exit;
  end;
  while WaitForSingleObject(ExInfo.hProcess, 50) <> WAIT_OBJECT_0 do
    Application.ProcessMessages;
  CloseHandle(Ph);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShellExecute_AndWait('FileName', 'Parameter');
end;

Prípadne si výstup programu zachytitíš napr. do Tmemo:

{....}
  private
    function RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;

{....}

function TForm1.RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;
var
  start: TStartupInfo;
  procInfo: TProcessInformation;
  tmpName: string;
  tmp: Windows.THandle;
  tmpSec: TSecurityAttributes;
  res: TStringList;
  return: Cardinal;
begin
  Result := False;
  try
     { Set a temporary file }
    tmpName := 'Test.tmp';
    FillChar(tmpSec, SizeOf(tmpSec), #0);
    tmpSec.nLength := SizeOf(tmpSec);
    tmpSec.bInheritHandle := True;
    tmp := Windows.CreateFile(PChar(tmpName),
           Generic_Write, File_Share_Write,
           @tmpSec, Create_Always, File_Attribute_Normal, 0);
    try
      FillChar(start, SizeOf(start), #0);
      start.cb          := SizeOf(start);
      start.hStdOutput  := tmp;
      start.dwFlags     := StartF_UseStdHandles or StartF_UseShowWindow;
      start.wShowWindow := SW_Minimize;
       { Start the program }
      if CreateProcess(nil, PChar(_exeName + ' ' + _cmdLine), nil, nil, True,
                       0, nil, PChar(_dirName), start, procInfo) then
      begin
        SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);
        WaitForSingleObject(procInfo.hProcess, Infinite);
        GetExitCodeProcess(procInfo.hProcess, return);
        Result := (return = 0);
        CloseHandle(procInfo.hThread);
        CloseHandle(procInfo.hProcess);
        Windows.CloseHandle(tmp);
         { Add the output }
        res := TStringList.Create;
        try
          res.LoadFromFile(tmpName);
          Memo1.Lines.AddStrings(res);
        finally
          res.Free;
        end;
        Windows.DeleteFile(PChar(tmpName));
      end
      else
      begin
        Application.MessageBox(PChar(SysErrorMessage(GetLastError())),
          'RunCaptured Error', MB_OK);
      end;
    except
      Windows.CloseHandle(tmp);
      Windows.DeleteFile(PChar(tmpName));
      raise;
    end;
  finally
  end;
end;


// Example:

procedure TForm1.Button1Click(Sender: TObject);
begin
  RunCaptured('C:\', 'cmd.exe', '/c dir');
end;

Dobrý den,

tohle se mi moc líbilo, zkoušel jsem to modifikovat tak, aby se do mema vypisoval postupný výstup z programu, který má delší odezvu ale nepodařilo se mi to. Otevřel jsem si nový handle na stejný soubor a snažil se z něho číst, ale pořad měl nulovou velikost. Neporadil by jste jak na to? Spouštím externí programy a chci jejich výstup přesměrovat do mema ale chci vidět co se dějě v reálném čase. Děkuji.

Honza

Zpět do poradny Odpovědět na původní otázku Nahoru