WinExecute

Vse drugo, kar ne spada v nobeno zgornjo kategorijo.
Odgovori
odisej
Prispevkov: 1363
Pridružen: 09.05.2003 12:58:10

WinExecute

Odgovor Napisal/-a odisej » 01.12.2011 13:23:33

Za WinExecute uporabljam spodnjo kodo. Pa ne morem izvršiti ukaza dir > d:\dir.txt. A je komu jasno zakaj?

Koda: Izberi vse

procedure WinExecute(const CommandLine, CurrentDir, OutputFile: string; const ErrorFile: String = '');
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  hStdOut, hStdError: THandle;
  SecurityAttributes: TSecurityAttributes;
begin
  ZeroMemory(@SecurityAttributes, SizeOf(SecurityAttributes));

  SecurityAttributes.nLength := SizeOf(SECURITY_ATTRIBUTES);
  SecurityAttributes.lpSecurityDescriptor := nil;
  SecurityAttributes.bInheritHandle := true;

  hStdOut := CreateFile(PChar(OutputFile), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
                        @SecurityAttributes, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0);

  if ErrorFile <> '' then
    hStdError := CreateFile(PChar(ErrorFile), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
                          @SecurityAttributes, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0);
  

  ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
  ZeroMemory(@ProcessInfo, SizeOf(ProcessInfo));

  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  StartupInfo.wShowWindow := SW_HIDE;
  StartupInfo.hStdOutput := hStdOut;
  if ErrorFile <> '' then
    StartupInfo.hStdError := hStdError;

  if not CreateProcess(nil, PChar(CommandLine), nil, nil, true,
                       CREATE_NO_WINDOW, nil, PChar(CurrentDir), StartupInfo, ProcessInfo) then
  begin
    raise Exception.Create('Error in WinExecute: ' + SysErrorMessage(GetLastError));
  end
  else
  begin
    WaitforSingleObject(ProcessInfo.hProcess, INFINITE);

    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end;
  CloseHandle(hStdOut);
  if ErrorFile <> '' then
    CloseHandle(hStdError);
end;

Uporabniški avatar
krho
Prispevkov: 709
Pridružen: 11.01.2003 23:02:56

Re: WinExecute

Odgovor Napisal/-a krho » 01.12.2011 17:16:33

am > nekaj pomeni preusmeri stdout v to datoteko.. ti pa stdout že bindaš v svojem appu

odisej
Prispevkov: 1363
Pridružen: 09.05.2003 12:58:10

Re: WinExecute

Odgovor Napisal/-a odisej » 02.12.2011 07:36:43

Probl sem tudi tako, da sm stdout naredil tako kot ErrorFile in podal not prazen string, pa še vedno nič.

Silver_War
Prispevkov: 664
Pridružen: 01.06.2004 14:50:41

Re: WinExecute

Odgovor Napisal/-a Silver_War » 03.12.2011 00:22:28

Ti v svojem primeru kličeš CreateProcess za izvedbo tvojega ukaza. Kolikor jaz vem se lahko CreateProcess uporablja samo za zaganjanje zagonskih datotek *.exe, *.com in pa *.bat datoteke. Ne podpira pa izvajanje posebnih ukazov, kot je recimo DOS-ovski ukaz dir. Za klicanje teh ukazov se uporablja ShellExecute.
Drugače če pa v tvojem programu uporabljaš tvojo WinExecute funkcijo tudi za druge stvari in ti uporaba ShellExecute ne pride v poštev, enostavno spravi tvojo ukazno vrstico v neko *.bat datoteko in potem to pokliči s tvojo obstoječo kodo.

aky
Prispevkov: 368
Pridružen: 27.12.2001 22:08:32

Re: WinExecute

Odgovor Napisal/-a aky » 03.12.2011 08:57:10

Silver_War napisal/-a:Ti v svojem primeru kličeš CreateProcess za izvedbo tvojega ukaza. Kolikor jaz vem se lahko CreateProcess uporablja samo za zaganjanje zagonskih datotek *.exe, *.com in pa *.bat datoteke. Ne podpira pa izvajanje posebnih ukazov, kot je recimo DOS-ovski ukaz dir. Za klicanje teh ukazov se uporablja ShellExecute.
Drugače če pa v tvojem programu uporabljaš tvojo WinExecute funkcijo tudi za druge stvari in ti uporaba ShellExecute ne pride v poštev, enostavno spravi tvojo ukazno vrstico v neko *.bat datoteko in potem to pokliči s tvojo obstoječo kodo.

Ali pa naj izvede "cmd /c dir > d:\dir.txt"

A.

mig640
Prispevkov: 59
Pridružen: 03.01.2008 11:36:54

Re: WinExecute

Odgovor Napisal/-a mig640 » 05.12.2011 16:42:54

http://www.delphicorner.f9.co.uk/articles/wapi4.htm

That said, executing a program in Win32 really means loading a process and its child thread(s) in memory. And the way you do that in Win32 is with CreateProcess. Mind you, for backward compatibility, the Win16 calls for executing programs, WinExec and ShellExecute are still supported in the Windows API, and still work. But for 32-bit programs, they're considered obsolete.

Če pa poskusim tvojo kodo v Delphiju 2009 ..tam pa se veselica začne..

Koda: Izberi vse

   ExecNewProcess('cmd /c dir C:\Delo\ > C:\dir.txt',true);

procedure TForm12.ExecNewProcess(ProgramName: String; Wait: Boolean);
var
  StartInfo : TStartupInfo;
  ProcInfo : TProcessInformation;
  CreateOK : Boolean;
begin
    { fill with known state }
  UniqueString(ProgramName); // Delphi 2009 ..
  FillChar(StartInfo,SizeOf(TStartupInfo),#0);
  FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
  StartInfo.cb := SizeOf(TStartupInfo);
  CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,
              CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
              nil, nil, StartInfo, ProcInfo);
    { check to see if successful }
  if CreateOK then
    begin
        //may or may not be needed. Usually wait for child processes
      if Wait then
        WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    end
  else
    begin
      ShowMessage('Unable to run '+ProgramName);
     end;

  CloseHandle(ProcInfo.hProcess);
  CloseHandle(ProcInfo.hThread);
end;
admin: prosim v prihodnje zapri kodo v [ code ] tag

Odgovori