PDA

View Full Version : ایا میشود از برنامه ای مثل cmd پیامی در دلفی دریافت کرد



ebino1363
دوشنبه 10 خرداد 1395, 00:10 صبح
با سلام دوستان عزیز ایا راهی وجود داره که بشه فهمید برنامه cmd که از طریق برنامه خودم اجرا شده حالا کارش تمام شده و بسته شده یعنی لحطه ی اتمام کاریک پیام یا سیگنال خاصی به برنامه ارسال بشه که درواقع اجرای cmd بشه یک مقدار از الگوریتم برنامه . و حالا دوباره به برنامه برگردیم .. ایا میشه با مالتی تردها و یا توابع میندوز این کار را کرد اگر میشه به چه صورت متشکرم

Mahmood_M
دوشنبه 10 خرداد 1395, 02:06 صبح
سلام
اینکه Process اجرا شده پیغامی به برنامه بفرسته امکانش در حالت معمول نمی تونه وجود داشته باشه و باید از داخل برنامه خودتون پایان کار اون رو چک کنید، می تونید Process رو اجرا کنید و منتظر پایان کار اون Process بمونید
برای منتظر موندن تا پایان کار برنامه اجرا شده می تونید از WaitForSingleObject استفاده کنید، اما این تابع یک Handle و یک مقدار در واحد میلی ثانیه دریافت می کنه و وجود اون هندل رو در زمان داده شده چک میکنه
حالا باید راهی برای اجرای برنامه انتخاب کنید که هندل Process اجرا شده رو بهتون بده که بتونید از این تابع استفاده کنید، با ShellExecute مقدار Handle قابل دریافت نیست
یا باید برای اجرا از ShellExecuteEX استفاده کنید و یا از CreateProcess
نمونه های پیاده سازی شده در اینترنت زیاد هست
مثال با استفاده از CreateProcess :

procedure ExecuteAndWait(const Command: string);
var
tmpStartupInfo: TStartupInfo;
tmpProcessInformation: TProcessInformation;
tmpProgram: String;
begin
tmpProgram := trim(Command);
FillChar(tmpStartupInfo, SizeOf(tmpStartupInfo), 0);
with tmpStartupInfo do
begin
cb := SizeOf(TStartupInfo);
wShowWindow := SW_HIDE;
end;

if CreateProcess(nil, pchar(tmpProgram), nil, nil, true, CREATE_NO_WINDOW,
nil, nil, tmpStartupInfo, tmpProcessInformation) then
begin
while WaitForSingleObject(tmpProcessInformation.hProcess , 10) > 0 do
begin
Application.ProcessMessages;
end;
CloseHandle(tmpProcessInformation.hProcess);
CloseHandle(tmpProcessInformation.hThread);
end
else
begin
RaiseLastOSError;
end;
end;
مثال با استفاده از ShellExecuteEX :

function TForm1.ShellExecute_AndWait(FileName: string; Params: string): bool;
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));
Result := true;
exit;
end;
while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
Application.ProcessMessages;
CloseHandle(Ph);

Result := true;
end;
علاوه بر این می تونید خروجی CMD رو چک کنید و مثلا بعد از دریافت نتیجه، عملیات بعدی رو انجام بدید، در این لینک (http://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app) چند نمونه قرار داده شده

ebino1363
شنبه 05 تیر 1395, 04:43 صبح
ممنونم برادر عزیزم بابت محبت شما ...فکرکنم جالبه تجربه ی خودم در این باره را بدونید.. من برای فرار از این همه داستانی که شما فرمودید .. امدم این کار را کردم
چون برنامه ی من قرار است یک دستور را با cmd اجرا کند امدم از یک فابل bat بهره بردم اما برای فهمیدن پایان کار سی ام دی اخرین دستور فایل bat را ایجاد یک فایل متنی قرار دادم . هنگامی سی ام دی تمام میشود تایمر دارد به دنبال فایل مذکور میگردد که به محض پیدا کردنش حذف میشود .. و چون پروسه سریع اتفاق میافتد حتی اگر صفحه ادرس ان فایل در ویندوز جلوی رویتان باشد تولید و حذفش را اصلا نمیتوانید ببینید .. و با یک دستوز fileexsist تقریبا از این همه مدیریت پروسه خلاص شدم .. ازقدیم گفتن همیشه تنبلی باعث خلاقیت میشه ..