Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Запуск интерактивного приложения из службы / 6 сообщений из 6, страница 1 из 1
23.12.2020, 11:40
    #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
23.12.2020, 12:44
    #40030424
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запуск интерактивного приложения из службы
Fresh Meat,

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

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

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

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

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

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


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