wangxuebin Posted July 21, 2013 Posted July 21, 2013 How to call a executable file on server side within unigui? I want to call a external exe file to produce reports,i.e: ss:=UniMainModule.appath+'\reportmk\reportmk.exe';ShellExecute(handle,'open', PChar(ss),nil, nil, sw_show); but nothing occured on the server. what's wrong with this?someone can help me? thank you! Quote
Semper Posted July 21, 2013 Posted July 21, 2013 Hi, What is UniMainModule.appath? Try ExtractFilePath(ParamStr(0)) instead. Also, carefully check all paths. Regards Quote
mhmda Posted July 22, 2013 Posted July 22, 2013 Hi, You can use this procedure, you may run the file and wait till it finish and do any thing after finishing... procedure RunMe(aPath:string;aFilename:string); var ahwnd: HWND; sInfo: TStartupInfo; pInfo: TProcessInformation; AppName, AppWDir, CmdLine: PChar; begin if (trim(aFilename)='') or (trim(aPath)='') then begin ShowMessage('Please enter a valid path and a valid file name'); exit; end; //init sInfo.wShowWindow:=SW_SHOW;//show or hide the window sInfo.dwXSize:=0; sInfo.dwYSize:=0; AppName := PChar(aFilename); AppWDir := PChar(aPath); CmdLine := PChar('username:test1 password:1234');//if you need to pass params FillChar(sInfo, sizeof(TStartupInfo), 0); sInfo.cb := sizeof(TStartupInfo); sInfo.dwFlags := STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK; //run it CreateProcess( AppName, CmdLine, nil, nil, False, CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS, nil, AppWDir, sInfo, pInfo ); ahwnd:=pInfo.hProcess; //wait untill finish while WaitForSingleObject(ahwnd, 100)=WAIT_TIMEOUT do begin end; //do anything after finishing...:-) end; 1 Quote
wangxuebin Posted July 23, 2013 Author Posted July 23, 2013 thanks to both of you very much! but I found the function RunMe can work for unigui standardalone(exe) server mode,but can't work for DLL mode(under apache). what's the reason? thank again. Quote
stiaan Posted July 30, 2013 Posted July 30, 2013 Hi I have had allot of success with this execute function from both the standalone and ISAPI DLL modules. The main thing is to understand where the paths are pointing to when running in the context of a standalone service or an integrated ISAPI DLL. I would suggest getting the paths right in the beginning of the MainModule.pas file: procedure TUniMainModule.UniGUIMainModuleCreate(Sender: TObject);var dwExitCode, dwRes : Dword; begin //Setup all my paths sBinPath := IncludeTrailingBackslash(ServerModule.UniServerModule.StartPath) + 'bin\'; sTempPath := IncludeTrailingBackslash(ServerModule.UniServerModule.TempFolderPath);. . I hope this helps Stiaan Quote
stiaan Posted July 30, 2013 Posted July 30, 2013 Just another thought. NEVER use SHELLEXECUTE. ShellExecute is only available when Explorer.Exe is running. Always try and use CreateProcess instead, especially in the context of a NT service or an ISAPI DLL. Quote
azago Posted February 28, 2020 Posted February 28, 2020 Starting an exe is a purely delphi language solution (no UniGUI). It all depends on whether you need a return output from running the process. In the latter case you have to use a semaphores management (also via file). However I have used it in UNIGUI in this way: // call var NameExec : string; NameFileJSON : string; rc : word; begin // exec process if dmDataset.ExecFile(NameExec, NameFileJSON, rc) then begin // timer OnThreadTerminate type TUniTimer for file response OnThreadTerminate.Enabled := True; end; end; // function in Datamodule function TdmDataset.ExecFile(const sComand, sParameter : string; var rc : word) : boolean; var SI : TStartupInfo; PI : TProcessInformation; sCmd : string; begin Result := True; FillChar(SI, SizeOf(SI), 0); SI.cb := SizeOf(SI); SI.wShowWindow := SW_SHOWMINNOACTIVE; sCmd := sComand; if sParameter > '') then sCmd := sCmd + ' ' + sParameter; if (Not CreateProcess(Nil, PChar(sCmd), Nil, Nil, False, Normal_Priority_Class, Nil, Nil, SI, PI)) then begin rc := GetLastError; Result := (rc = 0); exit; end; CloseHandle(PI.hThread); end; procedure OnThreadTerminateTimer(Sender: TObject); var FFolder : string; Sr : TSearchRec; FileDownload: string; SearchStr : string; begin // Response dir FFolder := IncludeTrailingPathDelimiter(UniMainModule.Configurazione.PathLocal); SearchStr := '*.json'; if SysUtils.FindFirst(FFolder + SearchStr, faAnyFile, Sr) = 0 then begin repeat if Sr.Attr and faDirectory = 0 then begin if UpperCase(ExtractFileName(ChangeFileExt(Sr.Name, ''))) = 'RESPONSE' then begin // fistr disable OnThreadTerminate.Enabled := False; // action business -- download -- other --- UniSession.SendFile(IncludeTrailingPathDelimiter(UniMainModule.Configurazione.PathLocal) + ExtractFileName(Sr.Name), FileDownload); // send message dmToast.Success('Download. Scarico eseguito.'); Break; end; end; until SysUtils.FindNext(sr) <> 0; SysUtils.FindClose(sr); end; Quote
Fred Montier Posted November 17, 2021 Posted November 17, 2021 @mhmda has the best solution. Also, my two cents, see https://github.com/TurboPack/DOSCommand/releases/tag/102Tokyo This is free and do all of that and many more. Don't understand why is never incorporated in the RAD Studio VCL CP , so basic as it is to many things. There are similar solutions in JEDI and DEVExpress utils code. Buts DOS Command , using for years and never disappoints ! 1 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.