exeを落とさずに数回動かせるには?


tama  2011-12-12 15:15:04  No: 41323

他のexeからの命令でexeを操作しています。立ち上げては閉じるを繰り返していますので時間がかかります。落とさずにexe内部でクリエイトから繰り返す方法ありますか?


monaa  2011-12-13 08:17:10  No: 41324

exeファイルは他のexeファイルから使うように設計されていません、
もし他人の作ったexeファイルにメッセージを送って処理しているのであれば、操作用exe内部でクリエイト?する事は出来ません。
そういう用途はDllと言う形式になります。
なので、一般的にはそのような方法はありません。


tama  2011-12-14 03:43:42  No: 41325

monaaさんご返事ありがとうございます。

説明が悪かったようでもう一度説明させてください
座標値を与えると動くプログラムがあります
X100,Y200とかです
プロセスでデータを送りそのソフトを立ち上げて作業させるというものです
作業が終わったらそのソフトは閉じて次を待ちます
連続して行うことはできますが、時間がかかりますので座標値をまとめて
送ってソフト内で連続で動いてほしいのです
ソフトを改良すれば済むかもしれませんが膨大なプログラムなので
出来そうもありません。そこで本題の質問させていただきました。
よろしくお願いいたします。


  2011-12-14 04:41:47  No: 41326

データの受け渡し方法もわからないのに、回答はできないと思うよ。
状況説明をもう少ししてください。

その値はコマンドラインパラメータで渡す?それともファイル経由?
複数のデータ、たとえば3つとか4つのデータ渡し方やどうやるの?
そもそもそのソフトはそのデータに対して、希望通りの動作をしてくれるの?


monaa  2011-12-14 08:24:32  No: 41327

あー、もしかして、
http://mrxray.on.coocan.jp/Halbow/Notes/N001.html
この様な操作をしてるのですかね?(Mr.XRayさんいつもありがとうございます。)
操作方法にもよりますが、
普通にShellExecuteで立ち上げてSendmessageでもよさそうですが。
このプログラムをスレッド上で立ち上げて横から命令を追加させるという手もあります。
サンプルを書くのは構いませんが、もう少し状況が具体的に分らないとキツイです。
出来れば命令を受けるexeの立ち上げ閉じるの部分とその中間に書かれた命令部分のソースは差し障りない程度に欲しいところです。


tama  2011-12-14 17:31:52  No: 41328

あさん  monaaさん
お返事ありがとうございます

受け渡しの要領を書いてみます

iniファイルを利用してます

送り側  
FileNmae  := FileDir + 'test.exe';
DoFileName:= FileDir + 'test.exe /TMS';
  if FileExists(FileNmae) then begin
    WinExecAndWait32V2(DoFileName, SW_SHOWNORMAL);
  end;

受け取り側
  if  ParamCount  > 0 then begin
    for ix  :=  1 to  ParamCount do begin
      Para:= UpperCase(ParamStr(ix));
      if bmAwkSub('^/TMS', True, '',Para) then FTM_SoftFlg:= True;
    end;
  end;
これでわかりますでしょうか?
よろしくお願いいたします。


monaa  2011-12-14 22:14:29  No: 41329

起動引数でパラメータを渡してるようなので
起動引数は起動時のみしか渡せません。
受け取り側のソースをお持ちなら、起動引数以外でパラメータを受け取れる様にしないと無理です。
アプリケーション間のデータ渡しは
https://www.petitmonte.com/bbs/answers?question_id=6141
http://mrxray.on.coocan.jp/Halbow/Notes/N012.html
方法は複数あります、それほど難しい作業ではありませんがご自分のスキルと転送データ量に応じて適切な方法をお探しください。

とりあえず組み込む前に簡単な送りアプリと受けアプリを作って見ることをお勧めします。
オススメはSendMessageで
xのデータ、yのデータを個別でLParamに入れて送信
最後に計算司令とか簡単そうです。


tama  2011-12-15 08:05:30  No: 41330

monaaさん
何度もすみません

試行錯誤して結果を報告いたします
ありがとうございました。


KHE00221  2011-12-17 06:28:27  No: 41331

EXE を起動しなおさなくても Form1 (MainForm) を Create しなおせば
いいので、後はコマンドラインの問題

コマンドラインは共有メモリーにしてしまう。

ParamCount と ParamStr  を共有メモリから取得するようにする

1)親  から  子を起動
2)新しいコマンドラインを指定してから 子を終了で
3)新しいコマンドラインで起動(Form1 を作成しなおし)

MapViewOfFilePointer.Exit を  0 以外にしておけば  子終了

--------- プロジェクト ------
program Project1;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas';

{$R *.res}

begin

   Application.Initialize;
   Application.MainFormOnTaskbar := True;

   while MapViewOfFilePointer.Exit = 0 do
   begin
     Form1 := TForm1.Create(Application);
     Form1.ShowModal;
     Form1.Release;
   end;

end.

----------------- UNIT 1 --------------

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//終了フラグ
procedure TForm1.Button1Click(Sender: TObject);
begin
    MapViewOfFilePointer.Exit := 1;
end;

//コマンドライン変更
procedure TForm1.Button2Click(Sender: TObject);
begin
    SetCommandLine (['XXX','YYYYYY','ZZZZZZZ']);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

    Memo1.Lines.Add(IntToStr(MapViewOfFilePointer.ParamCount));
    Memo1.Lines.Add('Param0:'+ParamStr(0));
    Memo1.Lines.Add('Param1:'+ParamStr(1));
    Memo1.Lines.Add('Param2:'+ParamStr(2));
    Memo1.Lines.Add('Param3:'+ParamStr(3));

end;

end.

unit Unit2;

interface

uses
    Windows,SysUtils;

type

    TFileMap = record
      Exit: Integer;
      ParamCount: Integer;
      ParamStr: array[0..1047] of WChar;
    end;
    PFileMap = ^TFileMap;

var
    FileMappingHandle : THandle;
    MapViewOfFilePointer: PFileMap;

    procedure SetCommandLine(Params: array of String);
    function ParamStr(Index: Integer): String;

const
    UniqueName = 'UniqueName';

implementation

function ParamStr(Index: Integer): String;
var
  P2: PChar;

//System からコピー
{$IFDEF MSWINDOWS}
function GetParamStr(P: PChar; var Param: string): PChar;
var
  i, Len: Integer;
  Start, S: PChar;
begin
  // U-OK
  while True do
  begin
    while (P[0] <> #0) and (P[0] <= ' ') do
      Inc(P);
    if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break;
  end;
  Len := 0;
  Start := P;
  while P[0] > ' ' do
  begin
    if P[0] = '"' then
    begin
      Inc(P);
      while (P[0] <> #0) and (P[0] <> '"') do
      begin
        Inc(Len);
        Inc(P);
      end;
      if P[0] <> #0 then
        Inc(P);
    end
    else
    begin
      Inc(Len);
      Inc(P);
    end;
  end;

  SetLength(Param, Len);

  P := Start;
  S := Pointer(Param);
  i := 0;
  while P[0] > ' ' do
  begin
    if P[0] = '"' then
    begin
      Inc(P);
      while (P[0] <> #0) and (P[0] <> '"') do
      begin
        S[i] := P^;
        Inc(P);
        Inc(i);
      end;
      if P[0] <> #0 then Inc(P);
    end
    else
    begin
      S[i] := P^;
      Inc(P);
      Inc(i);
    end;
  end;

  Result := P;
end;
{$ENDIF}
//Systemからコピー

begin
    if Index = 0 then
    begin
      Result := System.ParamStr(0);
    end
    else
    begin
      P2 := MapViewOfFilePointer.ParamStr;
      Dec(Index);
      while True do
      begin
        P2 := GetParamStr(P2, Result);
        if (Index = 0) or (Result = '') then Break;
        Dec(Index);
      end;
    end;
end;

procedure SetCommandLine(Params: array of String);
var
    I: Integer;
    S: String;
begin
    for I:=0 to High(Params) do
    begin
      S := S + Params[I] + Char(1) + Char(2);
    end;
    S := S + Char(0) + Char(0);

    MapViewOfFilePointer.ParamCount := High(Params);
    StrPCopy(MapViewOfFilePointer.ParamStr,S);
end;

initialization

   FileMappingHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS,False,PWChar(UniqueName));
   if FileMappingHandle = 0 then
   begin
     FileMappingHandle := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,1024+8,PChar(UniqueName));
   end;

   if FileMappingHandle <> 0 then
   begin
     MapViewOfFilePointer := MapViewOfFile(FileMappingHandle,FILE_MAP_ALL_ACCESS,0,0,0);
   end;

finalization

   UnmapViewOfFile(MapViewOfFilePointer);
   CloseHandle(THandle(FileMappingHandle));

end.


KHE00221  2011-12-17 06:30:02  No: 41332

当然コマンドラインの設定は 共有メモリーに

子の改造はほぼいらないはず


やま  2012-02-22 03:10:48  No: 41333

主旨からずれちゃいますが、IdTCPServerとIdTCPClientのセットを使うとかダメです?


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加