Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Запуск GUI-приложения через сервис  (Прочитано 10735 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Shouldercannon
Постоялец

ru
Offline Offline

« : 23-08-2012 14:36 » 

Подскажите как через сервис запустить GUI-приложение.
Код: (Delphi)
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ShellAPI;

type
  TService1 = class(TService)
    procedure ServiceExecute(Sender: TService);
    procedure ServiceCreate(Sender: TObject);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
  private
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  Service1: TService1;

implementation

{$R *.DFM}

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

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

procedure TService1.ServiceCreate(Sender: TObject);
begin
  //
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
  Sender.ReportStatus;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
  ShellExecute(GetForegroundWindow, 'open', PChar(ExtractFilePath(ParamStr(0)) + 'Project1.exe'), nil, PChar('C:\'), SW_SHOWNORMAL);
  Started := False;
end;

end.
Запускает программу, но её видно только в процессах.
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #1 : 23-08-2012 16:03 » 

Сервис должен быть интерактивным
Записан
Shouldercannon
Постоялец

ru
Offline Offline

« Ответ #2 : 23-08-2012 17:03 » 

Сервис должен быть интерактивным
Можно подробнее? Первый раз с сервичами сталкиваюсь.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-08-2012 17:03 » 

Shouldercannon, сервис не привязан к рабочему столу и текущему залогиненному пользователю. Соответственно, нужно разыскать нужную сессию нужного пользователя, и запускать процесс с дубликатом token-а этой сессии.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Shouldercannon
Постоялец

ru
Offline Offline

« Ответ #4 : 23-08-2012 17:07 » 

А если это делать под LocalSystem как TeamViewer?
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #5 : 23-08-2012 17:38 » 

dwServiceType:=SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS (структура SERVICE_STATUS)

Цитата
Interactive Services
Typically, services are console applications that are designed to run unattended without a graphical user interface (GUI). However, some services may require occasional interaction with a user. This page discusses the best ways to interact with the user from a service.

Important  Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.

Interacting with a User from a Service Indirectly

You can use the following techniques to interact with the user from a service on all supported versions of Windows:


Display a dialog box in the user's session using the WTSSendMessage function.
Create a separate hidden GUI application and use the CreateProcessAsUser function to run the application within the context of the interactive user. Design the GUI application to communicate with the service through some method of interprocess communication (IPC), for example, named pipes. The service communicates with the GUI application to tell it when to display the GUI. The application communicates the results of the user interaction back to the service so that the service can take the appropriate action. Note that IPC can expose your service interfaces over the network unless you use an appropriate access control list (ACL).
If this service runs on a multiuser system, add the application to the following key so that it is run in each session: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. If the application uses named pipes for IPC, the server can distinguish between multiple user processes by giving each pipe a unique name based on the session ID.


The following technique is also available for Windows Server 2003, Windows XP, and Windows 2000:


Display a message box by calling the MessageBox function with MB_SERVICE_NOTIFICATION. This is recommended for displaying simple status messages. Do not call MessageBox during service initialization or from the HandlerEx routine, unless you call it from a separate thread, so that you return to the SCM in a timely manner.
Using an Interactive Service
By default, services use a noninteractive window station and cannot interact with the user. However, an interactive service can display a user interface and receive user input.

Caution  Services running in an elevated security context, such as the LocalSystem account, should not create a window on the interactive desktop because any other application that is running on the interactive desktop can interact with this window. This exposes the service to any application that a logged-on user executes. Also, services that are running as LocalSystem should not access the interactive desktop by calling the OpenWindowStation or GetThreadDesktop function.


To create an interactive service, do the following when calling the CreateService function:


Specify NULL for the lpServiceStartName parameter to run the service in the context of the LocalSystem account.
Specify the SERVICE_INTERACTIVE_PROCESS flag.
To determine whether a service is running as an interactive service, call the GetProcessWindowStation function to retrieve a handle to the window station, and the GetUserObjectInformation function to test whether the window station has the WSF_VISIBLE attribute.

However, note that the following registry key contains a value, NoInteractiveServices, that controls the effect of SERVICE_INTERACTIVE_PROCESS:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows


The NoInteractiveServices value defaults to 0, which means that services with SERVICE_INTERACTIVE_PROCESS are allowed to run interactively. When NoInteractiveServices is set to a nonzero value, no service started thereafter is allowed to run interactively, regardless of whether it has SERVICE_INTERACTIVE_PROCESS.

Important  All services run in Terminal Services session 0. Therefore, if an interactive service displays a user interface, it is visible only to the user who connected to session 0. Because there is no way to guarantee that the interactive user is connected to session 0, do not configure a service to run as an interactive service under Terminal Services or on a system that supports fast user switching (fast user switching is implemented using Terminal Services).
msdn
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 23-08-2012 19:32 » 

zubr, ты меня на одну мысль навёл. Стоит опробовать.

Цитата: Shouldercannon
А если это делать под LocalSystem как TeamViewer?
Token сессии - это не пользователь, это лишь права доступа к системным объектам и операциям (в данном случае, к сессии). Т.е. дочерний процесс будет запущен под LocalSystem, но подключен к сессии пользователя.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #7 : 24-08-2012 04:25 » new

Помнится в msdn была интересная статья на эту тему: http://www.microsoft.com/msj/0200/logon/logon.aspx
Но к сожалению линк уже не существует.

Но все таки на свете есть хорошие люди Улыбаюсь, вот линк на архив: http://web.archive.org/web/20070713011758/http://www.microsoft.com/msj/0200/logon/logon.aspx
« Последнее редактирование: 24-08-2012 04:27 от zubr » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines