tStringlist'teki cmd komutlarını çalıştırma

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
PROGRAMADOR
Üye
Mesajlar: 239
Kayıt: 04 Oca 2008 01:53
Konum: Karşıyaka/İzmir

tStringlist'teki cmd komutlarını çalıştırma

Mesaj gönderen PROGRAMADOR »

Merhaba arkadaşlar.

Dinamik olarak bir batch file oluşturup bunu çalıştırıyorum delphi üzerinden herhangi bir sorun yok.

Kod: Tümünü seç


procedure CreateBatchFileForCopyAndRun(spath,dpath:string);
var
  batchlines:Tstringlist;
begin
  batchlines:=Tstringlist.Create;
  batchlines.Add('@echo off');
  batchlines.Add('Setlocal EnableDelayedExpansion');
  batchlines.Add('set source='+spath);
  batchlines.Add('set target='+dpath);
  ...bla bla bla

  batchlines.SaveToFile(BatFile_path);
  ExeAndWait(BatFile_path, SW_HIDE);
end;
Burada ben batch file oluşturmadan doğrudan memoryden dos komutlarını nasıl çalıştırabilirim?
In dubio pro reo...
Şüpheden sanık/özgürlük yararlanır...
Kullanıcı avatarı
m_ekici
Kıdemli Üye
Mesajlar: 563
Kayıt: 11 Haz 2003 06:49
Konum: Adana
İletişim:

Re: tStringlist'teki cmd komutlarını çalıştırma

Mesaj gönderen m_ekici »

Her satırı tek tek gönderebileceğiniz zannetmiyorum. her komut kendi ayrı ayrı çalışacağı için bir önceki komut (örneğin set source=..) unutulacaktır.
PROGRAMADOR
Üye
Mesajlar: 239
Kayıt: 04 Oca 2008 01:53
Konum: Karşıyaka/İzmir

Re: tStringlist'teki cmd komutlarını çalıştırma

Mesaj gönderen PROGRAMADOR »

Şöyle bir örnek buldum:

Kod: Tümünü seç

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Shellapi, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    PID: DWORD;
  public
    { Public declarations }
  end;

type
  PEnumInfo = ^TEnumInfo;
  TEnumInfo = record ProcessID: DWORD; HWND: THandle; end;

function AttachConsole(dwProcessId: DWORD): BOOL; stdcall;
  external kernel32 name 'AttachConsole';

 

var
  Form1: TForm1;


implementation

{$R *.dfm}

function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): BOOL; stdcall;
var
  PID: DWORD;
begin
  GetWindowThreadProcessID(Wnd, @PID);  // get processID from WND of Enumeration
  // continue EnumWindowsProc if found PID is not our wished, visible and enabled  processID (EI.ProcessID)
  Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or
    (not IsWindowEnabled(WND));
  if not Result then // WND found for EI.ProcessID
    EI.HWND := WND;
end;

function FindMainWindow(PID: DWORD): DWORD;
var
  EI: TEnumInfo;
begin
  //Store our processID and invalid Windowhandle to EI
  EI.ProcessID := PID;
  EI.HWND := 0;
  EnumWindows(@EnumWindowsProc, Integer(@EI));
  Result := EI.HWND;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin       

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  AProgram: WideString;
  StartupInfo: TStartupInfoW;
  ProcessInfo: TProcessInformation;
begin
  AProgram := 'cmd /K Dir C:\temp';   // using /K for keeping console alive
  UniqueString(AProgram);             // ensure that AProgram is writeable by API
  ZeroMemory(@StartupInfo, SizeOf(StartupInfo)); // create minimum startup info
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOW;
  if CreateProcessW(nil, PWideChar(AProgram), nil, nil, False,  // Create Consoleprocess
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
    ProcessInfo) then
    try
      PID := ProcessInfo.dwProcessId;  // Store  ProcessId to PID
    finally
      // close not longer required handles
      Showmessage(IntToStr(Integer(CloseHandle(ProcessInfo.hProcess))));
      Showmessage(IntToStr(Integer(CloseHandle(ProcessInfo.hThread))));
    end;
end;




procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = #13) then
     begin
        Key := #0;
        Button1.Click;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Wnd: HWND;
  S: String;
begin
  if PID <> 0 then  // do we have a valid ProcessID
  begin
    Wnd := FindMainWindow(PID);
    if Wnd <> 0 then  // did we find the window handle
    begin
      S := 'Test';
      // change caption of found window
      SendMessage(Wnd, WM_SETTEXT, 0, LPARAM(@S[1]));
      if AttachConsole(PID) then   // are we able to attach to console of our proecess?
      begin
        Writeln('Here we are'); // write to attached console
        //FreeConsole;  // free if not longer needed
      end;
    end;
  end;
end;

end.
Ancak button 2'de writeln ile cmd komutu gönderemiyorum.
In dubio pro reo...
Şüpheden sanık/özgürlük yararlanır...
PROGRAMADOR
Üye
Mesajlar: 239
Kayıt: 04 Oca 2008 01:53
Konum: Karşıyaka/İzmir

Re: tStringlist'teki cmd komutlarını çalıştırma

Mesaj gönderen PROGRAMADOR »

Sonunda çözümü buldum.

Başka arayan arkadaşlar için çözümü paylaşıyorum:

Kod: Tümünü seç

type
  PEnumInfo = ^TEnumInfo;
  TEnumInfo = record ProcessID: DWORD; HWND: THandle; end;

function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): BOOL; stdcall;
var
  PID: DWORD;
begin
  GetWindowThreadProcessID(Wnd, @PID);  // get processID from WND of Enumeration
  // continue EnumWindowsProc if found PID is not our wished, visible and enabled  processID (EI.ProcessID)
  Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or
    (not IsWindowEnabled(WND));
  if not Result then // WND found for EI.ProcessID
    EI.HWND := WND;
end;

function FindMainWindow(PID: DWORD): DWORD;
var
  EI: TEnumInfo;
begin
  //Store our processID and invalid Windowhandle to EI
  EI.ProcessID := PID;
  EI.HWND := 0;
  EnumWindows(@EnumWindowsProc, Integer(@EI));
  Result := EI.HWND;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  DosApp: String;
  DosSize: Integer;
  Security : TSecurityAttributes;
  start : TStartUpInfo;
  s:string;
begin
  AProgram := 'cmd /K';   // cmd'yi sürekli açık hale getiriyoruz
  UniqueString(AProgram);             // ensure that AProgram is writeable by API
  ZeroMemory(@StartupInfo, SizeOf(StartupInfo)); // create minimum startup info
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOW;//burayı SW_HIDE yaparsanız cmd penceresi görünmez
  if CreateProcessW(nil, PWideChar(AProgram), nil, nil, False,  // Create Consoleprocess
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
    ProcessInfo) then
        PID := ProcessInfo.dwProcessId  // Store  ProcessId to PID
    else Halt; //process oluşturulmazsa programdan çıkıyoruz.
end;

//bu prosedür ile açmış olduğumuz cmd'ye komut gönderiyoruz.
procedure SendToCMD(msg:string);
var
  i:integer;
begin
  Wnd := FindMainWindow(PID);
  for I := 1 to length(msg) do 
      SendMessage(Wnd, WM_CHAR, Ord(msg[i]), 0);

      SendMessage(Wnd, WM_CHAR, Ord(Ansichar(13)), 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
msg,s:string;
i:integer;
begin
  msg:=Edit1.Text;
  //Edit1'deki komutu cmd'ye gönderiyoruz
  SendToCMD(msg);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //konsola kapan komutunu gönderelim.
  SendMessage(wnd, WM_CLOSE, 0, 0);
  //handle'ları kapatalım.
  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ProcessInfo.hThread);
end;

Faydalı olması ümidi ile.
In dubio pro reo...
Şüpheden sanık/özgürlük yararlanır...
Cevapla