他のexeからの命令でexeを操作しています。立ち上げては閉じるを繰り返していますので時間がかかります。落とさずにexe内部でクリエイトから繰り返す方法ありますか?
exeファイルは他のexeファイルから使うように設計されていません、
もし他人の作ったexeファイルにメッセージを送って処理しているのであれば、操作用exe内部でクリエイト?する事は出来ません。
そういう用途はDllと言う形式になります。
なので、一般的にはそのような方法はありません。
monaaさんご返事ありがとうございます。
説明が悪かったようでもう一度説明させてください
座標値を与えると動くプログラムがあります
X100,Y200とかです
プロセスでデータを送りそのソフトを立ち上げて作業させるというものです
作業が終わったらそのソフトは閉じて次を待ちます
連続して行うことはできますが、時間がかかりますので座標値をまとめて
送ってソフト内で連続で動いてほしいのです
ソフトを改良すれば済むかもしれませんが膨大なプログラムなので
出来そうもありません。そこで本題の質問させていただきました。
よろしくお願いいたします。
データの受け渡し方法もわからないのに、回答はできないと思うよ。
状況説明をもう少ししてください。
その値はコマンドラインパラメータで渡す?それともファイル経由?
複数のデータ、たとえば3つとか4つのデータ渡し方やどうやるの?
そもそもそのソフトはそのデータに対して、希望通りの動作をしてくれるの?
あー、もしかして、
http://mrxray.on.coocan.jp/Halbow/Notes/N001.html
この様な操作をしてるのですかね?(Mr.XRayさんいつもありがとうございます。)
操作方法にもよりますが、
普通にShellExecuteで立ち上げてSendmessageでもよさそうですが。
このプログラムをスレッド上で立ち上げて横から命令を追加させるという手もあります。
サンプルを書くのは構いませんが、もう少し状況が具体的に分らないとキツイです。
出来れば命令を受けるexeの立ち上げ閉じるの部分とその中間に書かれた命令部分のソースは差し障りない程度に欲しいところです。
あさん 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;
これでわかりますでしょうか?
よろしくお願いいたします。
起動引数でパラメータを渡してるようなので
起動引数は起動時のみしか渡せません。
受け取り側のソースをお持ちなら、起動引数以外でパラメータを受け取れる様にしないと無理です。
アプリケーション間のデータ渡しは
https://www.petitmonte.com/bbs/answers?question_id=6141
http://mrxray.on.coocan.jp/Halbow/Notes/N012.html
方法は複数あります、それほど難しい作業ではありませんがご自分のスキルと転送データ量に応じて適切な方法をお探しください。
とりあえず組み込む前に簡単な送りアプリと受けアプリを作って見ることをお勧めします。
オススメはSendMessageで
xのデータ、yのデータを個別でLParamに入れて送信
最後に計算司令とか簡単そうです。
monaaさん
何度もすみません
試行錯誤して結果を報告いたします
ありがとうございました。
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.
当然コマンドラインの設定は 共有メモリーに
子の改造はほぼいらないはず
主旨からずれちゃいますが、IdTCPServerとIdTCPClientのセットを使うとかダメです?
ツイート | ![]() |