powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Запуск интерактивного приложения из службы
6 сообщений из 6, страница 1 из 1
Запуск интерактивного приложения из службы
    #40030398
Fresh Meat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!
Требуется запустить интерактивное приложение из службы. На просторах инета нашел код. Вроде все должно работать, но нет. Помогите, пжлст, где тут затык? Ось - Windows 10.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
unit Unit1;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  SvcMgr,
  Dialogs,
  Psapi,
  ExtCtrls,
  ShlObj,
  ComObj,
  ActiveX,
  Registry,
  ShellAPI;

const
  PI_NOUI = 1;


type
  WTS_INFO_CLASS = (WTSInitialProgram,
    WTSApplicationName,
    WTSWorkingDirectory,
    WTSOEMId,
    WTSSessionId,
    WTSUserName,
    WTSWinStationName,
    WTSDomainName,
    WTSConnectState,
    WTSClientBuildNumber,
    WTSClientName,
    WTSClientDirectory,
    WTSClientProduct,
    WTSClientHardwareId,
    WTSClientAddress,
    WTSClientDisplay,
    WTSClientProtocolType);

  _WTS_CONNECTSTATE_CLASS = (WTSActiveWTSActive, WTSConnected, WTSConnectQuery,
    WTSShadow, WTSDisconnected, WTSIdle, WTSListen,
    WTSReset, WTSDown, WTSInit);
  SessionInfo = ^_WTS_SESSION_INFO;
  _WTS_SESSION_INFO = record
    SessionId: DWord;
    pWinStationName: PChar;
    State: _WTS_CONNECTSTATE_CLASS;
  end;
  pDWord = ^DWord;
  MySessionInfo = array of SessionInfo;
  ppSessionInfo = ^MySessionInfo;
    //pHandle=^THandle;

  PProfileInfo = ^TProfileInfo;
  TProfileInfo = packed record
    dwSize: DWORD;
    dwFlags: DWORD;
    lpUserName: PAnsiChar;
    lpProfilePath: PAnsiChar;
    lpDefaultPath: PAnsiChar;
    lpServerName: PAnsiChar;
    lpPolicyPath: PAnsiChar;
    hProfile: THandle;
  end;

  PProfileInfoW = ^TProfileInfoW;
  TProfileInfoW = packed record
    dwSize: DWORD;
    dwFlags: DWORD;
    lpUserName: PWideChar;
    lpProfilePath: PWideChar;
    lpDefaultPath: PWideChar;
    lpServerName: PWideChar;
    lpPolicyPath: PWideChar;
    hProfile: THandle;
  end;



type
  TService1 = class(TService)
    Timer1: TTimer;
    //Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }

  public
    procedure RunFile(h: THandle; AppName, FileName: string);
    function FindExec(const h: HKEY; const UserFileName: string; var command: string): boolean;
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;





procedure WTSFreeMemory(p: pointer); stdcall; external 'wtsapi32.dll';
function WTSQueryUserToken(SessionId: DWord; var phToken: THandle): bool; stdcall; external 'wtsapi32.dll';
function WTSGetActiveConsoleSessionId: DWord; stdcall; external 'kernel32.dll';
//function SHGetFolderLocation(hwndOwner:HWND;nFolder:DWord;hToken:THandle;dwReserved:DWord;ppidl:PITEMIDLIST):HRESULT;stdcall;external 'shell32.dll';
function LoadUserProfileA(Token: THandle; var ProfileInfo: TProfileInfo): bool; stdcall; external 'Userenv.dll';
function UnloadUserProfile(Token: THandle; Profile: THandle): bool; stdcall; external 'Userenv.dll';
function RegOpenUserClassesRoot(hToken: THANDLE; dwOptions: DWORD; samDesired: REGSAM; phkResult: PHKey): LongWord; stdcall; external 'advapi32.dll';
function WTSQuerySessionInformationA(hServer: THandle; SessionId: DWord; WTSInfoClass: WTS_INFO_CLASS; ppBuffer: PChar; pBytesReturned: PDword): Bool; stdcall; external 'wtsapi32.dll';

const
  AppPath = 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\';
var
  Service1: TService1;
  PIDArray: array[0..1023] of DWORD;
  PIDW: array[0..1023] of DWORD;
  ExplorerHandle: THandle;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service1.Controller(CtrlCode);
end;


function TService1.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

function TService1.FindExec(const h: HKEY; const UserFileName: string; var command: string): boolean;
var
  r: TRegistry;
  UserFileDir, FileExt, AppDefault: string;
  Comm: PChar;
begin
  Result := False;

  UserFileDir := ExtractFileDir(UserFileName);
  GetMem(comm, Max_Path);
  if FindExecutable(@UserFileName[1], @UserFileDir[1], Comm) > 32 then
    begin
      Command := comm;
      Result := True;
      FreeMem(comm);
      exit;
    end;
  FreeMem(comm);
     {не нашли расширение, ищем ручками. Это капец, конечно, но - бывает нужно.
     И само собой - не котируется с DDE}
  r := TRegistry.Create(KEY_READ);
  r.RootKey := h;

  FileExt := ExtractFileExt(UserFileName);
  if r.KeyExists(FileExt) then
    begin
      r.OpenKey(FileExt, False);
      AppDefault := r.ReadString('');
      r.CloseKey;
      if not r.KeyExists(AppDefault + '\shell') then
        begin
          r.Free;
          exit;
        end;
      r.OpenKey(AppDefault + '\shell', false);
      command := r.ReadString('');
      if not r.KeyExists(command + '\command') then
        begin
          r.Free;
          exit;
        end;
      r.OpenKey(command + '\command', false);
      command := r.ReadString('');
      if command[1] = '"' then
        begin
          delete(command, 1, 1);
          command := Copy(command, 1, pos('"', command) - 1);
        end;
    end
  else
    Result := False;
  r.Free;
end;

procedure TService1.RunFile(h: THandle; AppName, FileName: string);
var
  FileDir: string;
  s: TStartupInfo;
  p: TProcessInformation;


  ProfileInfo: TProfileInfo;
  UserName: PAnsichar;
  Pr: PDword;
  b: Bool;
  r: TRegistry;
  OldPath: PChar;
  Env: string;
begin
  SetLastError(0);
  GetMem(UserName, Max_Path);
  GetMem(pr, SizeOf(DWord));
  b := WTSQuerySessionInformationA(0, WTSGetActiveConsoleSessionId, WTSUserName, @UserName, pr);

  ProfileInfo.dwSize := SizeOf(ProfileInfo);
  ProfileInfo.dwFlags := PI_NOUI;
  ProfileInfo.lpUserName := UserName;
  ProfileInfo.lpProfilePath := nil;
  ProfileInfo.lpDefaultPath := nil;
  ProfileInfo.lpServerName := nil;
  ProfileInfo.lpPolicyPath := nil;

  b := LoadUserProfileA(h, ProfileInfo);

  s.cb := SizeOf(s);
  s.lpReserved := nil;
  s.lpDesktop := nil;
  s.lpTitle := nil;
  s.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  s.wShowWindow := SW_SHOWDEFAULT;
  s.cbReserved2 := 0;
  s.lpReserved2 := nil;
  sleep(1000);
  FileDir := ExtractFileDir(FileName);
  FileName := ' "' + FileName + '"';

  r := TRegistry.Create(Key_Read);
  r.RootKey := HKEY_Local_Machine;

  GetMem(OldPath, Max_Path);
  GetEnvironmentVariable('path', OldPath, Max_Path);

  Env := ExtractFileName(AppName);
  if r.KeyExists(AppPath + Env) then
    begin
      r.OpenKeyReadOnly(AppPath + Env);
      if r.ValueExists('path') then
        begin
          env := r.ReadString('path');
          SetEnvironmentVariable('path', @Env[1]);
        end;
      r.CloseKey;
    end;
  r.Free;
  SetLastError(0);

  b := CreateProcessAsUser(h, @AppName[1], @FileName[1], nil, nil, false, CREATE_DEFAULT_ERROR_MODE,
    nil, @FileDir[1], s, p);
  SetEnvironmentVariable('path', OldPath);
  if not B then
    LogMessage(' LastError=' + IntToStr(GetLastError));

  CloseHandle(p.hProcess);
  CloseHandle(p.hThread);

  FreeMem(pr);
  UnloadUserProfile(h, ProfileInfo.hProfile);
end;

procedure TService1.Timer1Timer(Sender: TObject);
var
  h: THandle;
  b: Bool;
  w: DWord;
  ww: LongWord;
  phkResult: PHKey;
  UserFileName, UserFileDir: string;
  command: string;
begin
  Timer1.Enabled := False;

  SetLastError(0);
  w := WTSGetActiveConsoleSessionId;
  b := WTSQueryUserToken(w, h); { служба терминалов отключена}

  GetMem(phkResult, SizeOf(phkResult));

  ww := RegOpenUserClassesRoot(h, 0, KEY_READ, phkResult);

  UserFileName := 'C:\Windows\notepad.exe';
  UserFileDir := ExtractFileDir(UserFileName);
  if FindExec(phkResult^, UserFileName, command) then
    RunFile(h, command, UserFileName);
  RegCloseKey(phkResult^);
  FreeMem(phkResult);
  CloseHandle(h);
end;

end.

...
Рейтинг: 0 / 0
Запуск интерактивного приложения из службы
    #40030424
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Fresh Meat,

запустить можно, но ты его не увидишь. Аминь.
...
Рейтинг: 0 / 0
Запуск интерактивного приложения из службы
    #40030444
Fresh Meat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ъъъъъ
ты его не увидишь

Это и не требуется, как это ни странно.
...
Рейтинг: 0 / 0
Запуск интерактивного приложения из службы
    #40030447
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Fresh Meat
ъъъъъ
ты его не увидишь

Это и не требуется, как это ни странно.

Тогда - как обычно, CreateProces.
...
Рейтинг: 0 / 0
Запуск интерактивного приложения из службы
    #40030449
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
Fresh Meat,
запустить можно, но ты его не увидишь. Аминь.

Почему не увидишь? Если через CreateProcessAsUser к своей сессии подключиться?
Как там всякие TeamViewer'ы тогда работают?
...
Рейтинг: 0 / 0
Запуск интерактивного приложения из службы
    #40030510
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fresh Meat
ъъъъъ
ты его не увидишь

Это и не требуется, как это ни странно.
Тогда тебе Сюда
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Запуск интерактивного приложения из службы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]