Ciodensky
Ciodensky

Reputation: 69

Task Execution from Delphi using ShellExecute

For days now, I am trying to figure out how to execute an ExeFile with Specified Task in Delphi using ShellExecute. Below is my latest code giving my the error "The specified file was not found":

    procedure TfrmGTX.btnQuickBooksSyncClick(Sender: TObject);
    var
      ExecuteResult : integer;
      Path : string;
     begin
      Path := IncludeTrailingPathDelimiter(ExtractFilePath('MyApp.exe'));
      ExecuteResult := ShellExecute(0, nil, PChar(Path + 'cd C:\Program Files                                              
       (x86)\Folder1\Folder2\MyApp.exe a_Sales /Connect'), nil, nil, 
       SW_SHOWNORMAL);
      case ExecuteResult of
          0 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The 
              operating system is out of memory or resources.');
          2 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The 
              specified file was not found.');
          3 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The 
              specified path was not found.');
          5 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Windows 95 
              only: The operating system denied access to the specified 
              file.');
          8 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Windows 95 
              only: There was not enough memory to complete the operation.');
          10 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Wrong 
               Windows version.');
          11 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The .EXE 
               file is invalid (non-Win32 .EXE or error in .EXE image).');
          12 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Application  
               was designed for a different operating system.');
          13 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Application  
               was designed for MS-DOS 4.0.');
          15 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Attempt to 
               load a real-mode program.');
          16 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Attempt to 
               load a second instance of an application with non-readonly data 
               segments.');
          19 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Attempt to 
               load a compressed application file.');
          20 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Dynamic- 
               link library (DLL) file failure.');
          26 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': A sharing 
               violation occurred.');
          27 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The 
               filename association is incomplete or invalid.');
          28 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The DDE 
               transaction could not be completed because the request timed 
               out.');
          29 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The DDE 
               transaction failed.');
          30 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The DDE 
               transaction could not be completed because other DDE 
               transactions were being processed.');
          31 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': There is no 
               application associated with the given filename extension.');
          32 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Windows 95 
               only: The specified dynamic-link library was not found.');
        else ShowMessage('Unknown Error.');
      end;

     end;

I am sure a small glitch I am missing here. Any help please...

Many thanks!


Update: Deleted this portion.


Solution: I removed the IncludeTrailingPathDelimiter andExtractFilePath, used ShellExecuteEx, and correct Parameters. And that's it, able to solve the problem.

    procedure TfrmGTX.btnQBSyncClick(Sender: TObject);
     var
      FileName, Parameters, Folder, Directory: string;
      sei: TShellExecuteInfo;
      Error: DWORD;
      OK: boolean;
     begin
      Folder := 'C:\Program Files (x86)\Folder1\Folder2\';
      FileName := Folder + 'MyApp';
      Parameters := 'MyTask';
      ZeroMemory(@sei, SizeOf(sei));
      sei.cbSize := SizeOf(sei);
      sei.lpFile := PChar(FileName);
      sei.lpParameters := PChar(Parameters);
      sei.lpDirectory := PChar(Folder);
      sei.nShow := SW_SHOWNORMAL;
      OK := ShellExecuteEx(@sei);
      if not OK then
        begin
          Error := GetLastError;
          case Error of
              0 : ShowMessage('Error ' + IntToStr(Error) + ': The operating system is out of memory or resources.');
              2 : ShowMessage('Error ' + IntToStr(Error) + ': The specified file was not found.');
              3 : ShowMessage('Error ' + IntToStr(Error) + ': The specified path was not found.');
              5 : ShowMessage('Error ' + IntToStr(Error) + ': Windows 95 only: The operating system denied access to the specified file.');
              8 : ShowMessage('Error ' + IntToStr(Error) + ': Windows 95 only: There was not enough memory to complete the operation.');
              10 : ShowMessage('Error ' + IntToStr(Error) + ': Wrong Windows version.');
              11 : ShowMessage('Error ' + IntToStr(Error) + ': The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).');
              12 : ShowMessage('Error ' + IntToStr(Error) + ': Application was designed for a different operating system.');
              13 : ShowMessage('Error ' + IntToStr(Error) + ': Application was designed for MS-DOS 4.0.');
              15 : ShowMessage('Error ' + IntToStr(Error) + ': Attempt to load a real-mode program.');
              16 : ShowMessage('Error ' + IntToStr(Error) + ': Attempt to load a second instance of an application with non-readonly data segments.');
              19 : ShowMessage('Error ' + IntToStr(Error) + ': Attempt to load a compressed application file.');
              20 : ShowMessage('Error ' + IntToStr(Error) + ': Dynamic-link library (DLL) file failure.');
              26 : ShowMessage('Error ' + IntToStr(Error) + ': A sharing violation occurred.');
              27 : ShowMessage('Error ' + IntToStr(Error) + ': The filename association is incomplete or invalid.');
              28 : ShowMessage('Error ' + IntToStr(Error) + ': The DDE transaction could not be completed because the request timed out.');
              29 : ShowMessage('Error ' + IntToStr(Error) + ': The DDE transaction failed.');
              30 : ShowMessage('Error ' + IntToStr(Error) + ': The DDE transaction could not be completed because other DDE transactions were being processed.');
              31 : ShowMessage('Error ' + IntToStr(Error) + ': There is no application associated with the given filename extension.');
              32 : ShowMessage('Error ' + IntToStr(Error) + ': Windows 95 only: The specified dynamic-link library was not found.');
            else ShowMessage('Unknown Error.');
          end;
        end;
     end;

Upvotes: 0

Views: 12759

Answers (2)

Khun
Khun

Reputation: 202

I have created 3 different functions and using them on my needs:

function ExecWithShellExecute(AName, CLine: string; run_mode: string; var iErr: int64): boolean;
begin
  if run_mode = '' then
    run_mode := 'open';
  iErr := ShellExecute(Handle, PWideChar(run_mode), PWideChar(AName), PWideChar(CLine),
             PWideChar(ExtractFilePath(AName)), SW_HIDE);
  Result := iErr > 32;
end;

function ExecWithShell(AName, CLine: string; run_mode: string;
    var hProcess: DWord; var iErr: int64): boolean;
var
  ShExecInfo: TShellExecuteInfo;
begin
  Result := False;
  hProcess := 0;
  ZeroMemory(@ShExecInfo, SizeOf(ShExecInfo));
  ShExecInfo.cbSize := sizeof(ShExecInfo);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  if run_mode = '' then
    ShExecInfo.lpVerb := nil
  else
    ShExecInfo.lpVerb := PWideChar(run_mode);  
  ShExecInfo.lpFile := PWideChar(AName);
  ShExecInfo.lpParameters := PWideChar(CLine);
  ShExecInfo.lpDirectory := PWideChar(ExtractFilePath(AName));
  ShExecInfo.nShow := SW_HIDE;
  ShExecInfo.hInstApp := 0;
  if ShellExecuteEx(@ShExecInfo) then
  begin
    hProcess := ShExecInfo.hProcess;
    Result := hProcess > 0;
  end else
    iErr := GetLastError;
end;

function ExecWithCmdLine(AName, CLine: string;
    var pInfo: TProcessInformation; var iErr: int64): boolean;
var
  sInfo: TStartupInfo;
  AppName, AppWDir, CmdLine: string;
begin
  AppName := AName; //Full path & name of Your App.
  AppWDir := ExtractFileDir(AppName);
  CmdLine := ' ' + CLine;
  ZeroMemory(@pInfo, SizeOf(pInfo));
  ZeroMemory(@sInfo, sizeof(TStartupInfo));
  sInfo.cb      :=  sizeof(TStartupInfo);
  sInfo.dwFlags :=  STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK;
  Result := CreateProcess(PWideChar(AppName), PWideChar(CmdLine), nil, nil, False,
                CREATE_DEFAULT_ERROR_MODE or
                CREATE_NEW_PROCESS_GROUP  or
                NORMAL_PRIORITY_CLASS or
                CREATE_NO_WINDOW,
                nil, PWideChar(AppWDir), sInfo, pInfo);
  if not Result then
    iErr := GetLastError;
end;

Upvotes: 1

John Easley
John Easley

Reputation: 1580

The content of your ShellExecute is invalid. If you must change directories, use the CHDIR command first.

Also, you should pass parameters as an argument to the ShellExecute call.

This is valid

 ExecuteResult := ShellExecute(0, 'open', PChar('C:\Program Files (x86)\Intuit\QuickBooks Enterprise Solutions 18.0\qbw32.exe'), pchar('a_Sales /Connect'), nil, SW_SHOWNORMAL);

Upvotes: 1

Related Questions