How to Start and stop a VBA application from within a Windows Service (Delphi XE5)


I have a service application within which I wish to start / stop any executable (in this instance, written in VBA) from the service. I can launch the program using the code below:
function TSvceMgrMethods.StartApplication(Visibility : integer; Wait: Boolean; var AProcessId: integer) : boolean;
  ProcessID : DWord;

  Function WinExecute32(FileName : String; Visibility : integer; Wait: Boolean;
  Var ProcessId: DWORD): DWORD;
    WorkDir: String;
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    UniqueString(FileName); // important for CreateProcessW()
    WorkDir := GetCurrentDir;
    ZeroMemory(@StartupInfo, Sizeof(StartupInfo));
    ZeroMemory(@ProcessInfo, Sizeof(ProcessInfo));
    StartupInfo.cb := Sizeof(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := Visibility;
    if not CreateProcess(
      PChar(FileName), { 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 }
      nil, { pointer to new environment block }
      nil, { pointer to current directory name }
      StartupInfo, { pointer to STARTUPINFO }
      ProcessInfo) then
      raise Exception.Create('WinExecute32: Error Creating Process:'+ GetLastError().ToString());
    ProcessId := ProcessInfo.dwProcessId;

    if Wait then
      WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
      GetExitCodeProcess(ProcessInfo.hProcess, Result);
      Result := 0;
    end else begin
      Result := 0;


  result := WinExecute32('M:\XE5\projects\win32\debug\MKTplaceAPIcontrolP.exe',Visibility, Wait, ProcessId) = 0;
  AProcessID := ProcessID;


But when I try to stop the application using this code, I get nowhere:

function TSvceMgrMethods.StopApplication(ProcessID: integer): boolean;
  ProcessList : TDGProcessList;
  AIndex : integer;
  PID : DWord;
  hProcess: THandle;

  function TerminateProcessByID(dwProcessID: Cardinal): Boolean;
    Result := False;
    hProcess := OpenProcess(PROCESS_TERMINATE, False, dwProcessID);
    if hProcess <> 0 then begin
      Result := WinAPI.Windows.TerminateProcess(hProcess,0);

  PID := ProcessID;
  result := TerminateProcessByID(PID);

Open in new window

The code works fine if run from a Windows Application, but when launched (via a DataSnap call) the application does not close.

I have seen something related to privileges, but cannot fathom out how to elevate such privileges.

I would be most grateful for any assistance?

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

a service application ... to start / stop any executable (in this instance, written in VBA)
VBA code runs inside another application, such as Excel, Word, Access, Visio.  Please explain.
TimFHayesAuthor Commented:
Apologies - I am new to Expert's exchange.

The VBA is running in Access.
Sinisa VukCommented:
It is different when service start some app. Go here (another EE question) - where I wrote example how to destroy such process using wmi.

When you create/run process - you should get process id and keep it for destroying.
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

TimFHayesAuthor Commented:
Thank you.

I have resolved the issue :

1) Needed to run the service in a user account with admin privileges.
2) Ran MSAccess.exe with the test.accde in the command line using CreateProcessWithLogonW.
3) Obtained the exe handle (which I could have saved but wanted to be safe in case the service had inadvertently closed) by iterating thru snapshot  made by CreateToolhelp32Snapshot using Process32First and Process32Next and comparing process entries with EXE name until matched.
4) finally able to terminate the process  using the handle of the EXE process with the TerminateProcess command.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
terminate the process  using the handle of the EXE process with the TerminateProcess command.
TerminateProcess is not a friendly way to close a process. if the program is busy while being killed, your action may cause some severe damage to the system, for example a corrupt database or a file and directory which couldn't be moved or removed since there are some open file handles.

you may try some alternatives before you call TerminateProcess. for example you could send WM_ENDSESSION to the main window of the process. this message normally was sent to windows programs if the system performs a shutdown. normaly, an application getting this message would close and save the current screen and terminate. see for more information. if that doesn't work (or leads to unwished messages to the user), you may send WM_CLOSE message to the current active window of the process and its parent windows. by sending WM_CLOSE you also could close a message box like 'do you really want to close?' and have an orderly termination. the TerminateProcess i only would do as a last resort after a reasonable timeout.

TimFHayesAuthor Commented:
Generally a roundabout way to work with MS Access from Delphi. Difficulty overcome was understanding that my service needed administrator privileges before it had the proper visibility.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.