Jump to content

How to call a executable file on server side within unigui?


wangxuebin

Recommended Posts

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!

Link to comment
Share on other sites

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;
  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 6 years later...


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;
 

Link to comment
Share on other sites

  • 1 year later...

@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 !

  • Thanks 1
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...