Если задача — запуск на рабочем столе активного пользователя (того, кто смотрит в монитор в данный момент), то можно сделать так:
function WTSGetActiveConsoleSessionId: DWORD; stdcall; external 'Kernel32.dll';
function WTSQueryUserToken(SessionId: DWORD; phToken: pHandle):bool;stdcall;external 'wtsapi32.dll';
if WTSQueryUserToken(WtsGetActiveConsoleSessionID,@hToken) then
begin
ZeroMemory(@si,SizeOf(si));
si.cb:=SizeOf(si);
si.lpDesktop:=nil;
CreateProcessAsUser(hToken,nil,PANSIChar(FilePath),nil,nil,False,0,nil,nil,si,pi);
CloseHandle(hToken);
end;
Смысл в том, что начиная с Vista (если не ошибаюсь), запуск приложения в контексте системы весь интерактив возложит в «рабочий стол пользователя SYSTEM».
Но если пользователь залогинится после запуска — окно он не увидит, скорее всего. Решение: циклическая проверка «активности» пользователя в службе и запуск этим способом.