PDA

View Full Version : اجرای فایل exe دلخواه با برنامه نوشته شده به زبان دلفی XE



DarkACE
شنبه 05 فروردین 1391, 03:01 صبح
سلام

با چه دستوری می تونم یه فایل اجرایی که خارج از برنامه نوشته شده با دلفی دارمش رو اجرا کنم؟

من یه دونه E-Book با فرمت exe ساختم فقط نمی دونم با چه دستوری باید بازش کنم.

می خوام که محل فایل اجرایی دلخواه باشه، مثلاً توی پوشه ی خود برنامه. اما نه به این شکل که مجبور بشم مسیر برنامه رو هم همین مسیر فایل اجرایی قرار بدم

مرسی.

lord_viper
شنبه 05 فروردین 1391, 09:12 صبح
برای اجرای یک فایل بوسیله دلفی میتونین از دستور shellExecute در یونیت shellApi استفاده کنید

DarkACE
شنبه 05 فروردین 1391, 14:16 عصر
نمی خوام که یه آدرس خاص بهش بدم. می خواح از مسیر نصب برنامه اجرا بشه، چون ممکنه کاربر مسیر نصب برنامه رو عوض کنه.

مرسی

Felony
شنبه 05 فروردین 1391, 14:29 عصر
ShellExecute(0, 'Open', PChar(ExtractFilePath(Application.ExeName) + '\FileName.exe'), nil, '', SW_SHOWNORMAL);

بهروز عباسی
چهارشنبه 04 بهمن 1391, 19:27 عصر
درود به همه
من یک برنامه دارم که یک متن رو (که درون Memoقرار داره)در یک فایل ذخیره میکنه و اون فایل ذخیره شده رو به عنوان پارامتر یک برنامه که در کنار برنامه منه ارسال میکنه ، تا اون برنامه-دوم تغییراتی رو در متن اون فایل ایجاد کنه و دوباره اون فایل رو که تغییر کرده در برنامه نشون بده (توی همون Memo).

تابع زیرو براش نوشتم :

procedure FormatCode(const Code: TMemo);
var
sAppPath: string;
iRet: Integer;
const
sTempPasFile = 'TempFormatCode.pas';
begin
sAppPath := ExtractFilePath(ParamStr(0));
try
Code.Lines.SaveToFile(sAppPath + sTempPasFile);

iRet := ShellExecute(Application.Handle, PChar('open'),
PChar(sAppPath + 'Formatter.exe '), PChar(sTempPasFile), nil, SW_HIDE);

{ ShellExecute Returns a value greater than 32 if successful .}
if iRet > 32 then
begin
Code.Lines.LoadFromFile(sAppPath + sTempPasFile);
end
else
ShowMessage('Error in ShellExecute Function !');
except
on E: Exception do
ShowMessage('Exception ' + E.Message);
end;
end;

فایل درست ذخیره میشه تغییرات هم اعمال میشه امّا وقتی اون فایل رو می خوام توی Memo نشون بدم هیچ تغییری نکرده.

به نظر من اشکال از تابع ShellExecute .
چون وقتی کد زیرو که برای بارگذاری اون فایل به ممو ازش استفاده کردم رو توی یک Button یا... دیگه ای اجرا میکنم ،درست عمل میکنه
Code.Lines.LoadFromFile(sAppPath + sTempPasFile);

به نظر شما مشکل چیه؟
به نظر حودم وقتی اقدام به بارگذاری فایل میکنم هنوز کار ShellExecute تموم نشده !

اینم اون فایل "Formatter.exe" در کنار فایل اجرای برنامه قرار بدید و تست کنید.
ممنون

بهروز عباسی
چهارشنبه 04 بهمن 1391, 20:35 عصر
اینو یادم رفت بگم
برای تست برنامه متن موجود در ممو باید از سورس کدهای دلفی باشه
این برنامه کار FormatCode دلفی رو انجام میده و کدهای نامرتب رو مرتب میکنه

Felony
پنج شنبه 05 بهمن 1391, 04:40 صبح
من وقت ندارم کدت رو بررسی کنم ولی احتمالا مشکل همونی هست که گفتی ، خوب تا تموم شدن کار صبر کن :


function ExecAndWait(sExe, sCommandLine: string): Boolean;
var
dwExitCode: DWORD;
tpiProcess: TProcessInformation;
tsiStartup: TStartupInfo;
begin
Result := False;
FillChar(tsiStartup, SizeOf(TStartupInfo), 0);
tsiStartup.cb := SizeOf(TStartupInfo);
if CreateProcess(PChar(fsExe), PChar(sCommandLine), nil, nil, False, 0,
nil, nil, tsiStartup, tpi) then
begin
if WAIT_OBJECT_0 = WaitForSingleObject(tpiProcess.hProcess, INFINITE) then
begin
if GetExitCodeProcess(tpiProcess.hProcess, dwExitCode) then
begin
if dwExitCode = 0 then
Result := True
else
SetLastError(dwExitCode + $2000);
end;
end;
dwExitCode := GetLastError;
CloseHandle(tpiProcess.hProcess);
CloseHandle(tpiProcess.hThread);
SetLastError(dwExitCode);
end;
end;

بهروز عباسی
پنج شنبه 05 بهمن 1391, 11:51 صبح
مجتبی جان ممنون از کمکت مشکلم حل شد
تابع زیر کارو درست انجام میده ،تابعی که شما گذاشتی امکان اجرای مخفی برنامه رو نداشت که نمونه زیر داره.
procedure Tfrm_Main.FormatCode(const Code: TMemo);
function WinExecAndWait32V2(FileName: string; Visibility: Integer): DWORD;
procedure WaitFor(processHandle: THandle);
var
Msg: TMsg;
ret: DWORD;
begin
repeat
ret := MsgWaitForMultipleObjects(1, { 1 handle to wait on }
processHandle, { the handle }
False, { wake on any event }
INFINITE, { wait without timeout }
QS_PAINT or { wake on paint messages }
QS_SENDMESSAGE { or messages from other threads }
);
if ret = WAIT_FAILED then
Exit; { can do little here }
if ret = (WAIT_OBJECT_0 + 1) then
begin
{ Woke on a message, process paint messages only. Calling
PeekMessage gets messages send from other threads processed. }
while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
DispatchMessage(Msg);
end;
until ret = WAIT_OBJECT_0;
end; { Waitfor }

var { V1 by Pat Ritchey, V2 by P.Below }
zAppName: array [0 .. 512] of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin { WinExecAndWait32V2 }
StrPCopy(zAppName, FileName);
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil, zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
False, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS, nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) { pointer to PROCESS_INF } then
Result := DWORD(-1) { failed, GetLastError has error code }
else
begin
WaitFor(ProcessInfo.hProcess);
GetExitCodeProcess(ProcessInfo.hProcess, Result);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end; { Else }
end; { WinExecAndWait32V2 }

var
sAppPath: string;
const
sTempPasFile = 'TempFormatCode.pas';
begin
sAppPath := ExtractFilePath(ParamStr(0));
try
Code.Lines.SaveToFile(sAppPath + sTempPasFile);

WinExecAndWait32V2(sAppPath+ 'Formatter.exe ' + sTempPasFile,SW_hide);

Code.Lines.LoadFromFile(sAppPath + sTempPasFile);
except
on E: Exception do
ShowMessage('Exception ' + E.Message);
end;
end;