65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows 服务与桌面交互的替代方法,适用于操作系统 > XP

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (14投票s)

2010 年 9 月 17 日

CPOL

3分钟阅读

viewsIcon

117838

downloadIcon

4433

Windows 服务与桌面交互的替代方法,适用于操作系统 > XP

Windows 服务在与桌面交互时,在 XP 中运行良好,但当我们更改应用程序到 Vista 或高于 XP 的版本时,它并不会像我们期望的那样工作。

问题

当我们把解决方案迁移到 Windows 7 操作系统时,它在会话 0 中运行。因此你会得到一条消息

被交互式服务对话框检测阻止

本文可以为上述问题提供一个解决方案。

提问

1) 为什么我希望 Windows 服务与桌面交互,这并不是它们的设计目的?

答案:是的,没错!Windows 服务并非设计用于与桌面交互。但在引入 WCF 服务之后,我们可以将它们托管在 Windows 服务中,我们可能需要从 WCF 服务中运行 EXE 文件

但在阅读本文之前,请先阅读

注意

在实施此解决方案之前,请注意您的要求并处理所有安全问题。

引言

Windows 服务

Microsoft Windows 服务,以前称为 NT 服务,使您能够创建在自己的 Windows 会话中运行的长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动,并且 不显示任何用户界面。这些特性使得服务非常适合在服务器上使用,或者在您需要长时间运行的功能而不干扰在同一台计算机上工作的其他用户时使用。您还可以以特定用户帐户的安全上下文中运行服务,该帐户与登录用户或默认计算机帐户不同。有关服务和 Windows 会话的更多信息

步骤 1
  • 打开 Visual Studio 2010
  • 文件 -> 新建 -> 项目 ->
  • 模板 VisualC# -> Windows
  • 项目 -> Windows 服务
  • 名称:InteractDesktopDemo
  • 确定 ß

1.jpg

第二步

打开 Service1.cs,在设计器模式下右键单击并选择添加安装程序。

设置安装程序的属性,默认情况下,我们得到

  1. serviceProcessInstaller
  2. serviceInstaller1

转到解决方案资源管理器项目。

Installer.designer.cs

添加以下代码

private void InitializeComponent()
{
      this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
      this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
     //
      // serviceProcessInstaller1
     if (System.Environment.OSVersion.Version.Major <= 5)
     this.serviceProcessInstaller1.Account =
		System.ServiceProcess.ServiceAccount.LocalSystem;
     this.serviceProcessInstaller1.Password = null;
     this.serviceProcessInstaller1.Username = null;
     //
    // serviceInstaller1
    //
    this.serviceInstaller1.ServiceName = "Service1";
    //
    // ProjectInstaller
    //
   this.Installers.AddRange(new System.Configuration.Install.Installer[] {
   this.serviceProcessInstaller1,
   this.serviceInstaller1});
}

解释

它将检查操作系统版本,如果操作系统高于 Windows XP,则它将要求输入用户名和密码,在输入凭据后,服务将在该系统帐户下运行。如果是 XP 或低于 XP,则 Windows 服务将在本地系统帐户下运行。

步骤 3

添加一个安装程序

转到解决方案资源管理器,右键单击添加新项目 Installer.cs

2.jpg

并添加以下代码

protected override void OnCommitted(IDictionary savedState)
     {
      base.OnCommitted(savedState);
     try
        {
         ServiceController nService = new ServiceController("Service1");
         nService.Start();
         }
    catch (Exception ie)
      {
       StreamWriter sw;
       sw = File.AppendText("C:\\sashidhar.txt");
       sw.WriteLine(ie.Message);
       sw.Close();
      }
     }

解释

上述代码处理在 EXE 文件/Windows 服务安装后触发的 oncommitted 事件。它有助于服务在安装后自动启动。

步骤 4

添加对 Microsoft.Win32.TaskScheduler 的引用,这对于创建任务计划程序很有用。

可以在 http://taskscheduler.codeplex.com/ 找到 DLL。

protected override void OnStart(string[] args)
     {
       try
        {
          if (System.Environment.OSVersion.Version.Major > 5)
            {
              //New Functionality
              // Get the service on the local machine
              TaskService ts = new TaskService();
              // Create a new task definition and assign properties
             TaskDefinition td = ts.NewTask();
             td.Principal.RunLevel = TaskRunLevel.Highest;
             td.RegistrationInfo.Description = "Does something";
            // Create a trigger that will fire the task when you are creating a new one 
            // or changing the task
             td.Triggers.Add(new RegistrationTrigger { Delay = TimeSpan.FromSeconds(1) });
            // Create an action that will launch Notepad whenever the trigger fires
            td.Actions.Add(new ExecAction("notepad"));
            // Register the task in the root folder
           ts.RootFolder.RegisterTaskDefinition(@"ssd", td);
        }
        else
        {
          //For Xp the Windows Service to interact with Desktop
          ServiceDesktopPermission();
         System.Diagnostics.Process.Start("notepad.exe");
        }
     }
     catch (Exception ie)
      {
       StreamWriter sw;
       sw = File.AppendText("C:\\Sashidhar.txt");
       sw.WriteLine(ie.Message);
       sw.Close();
      }
 }

解释

上述代码的行为取决于操作系统,对于低于 XP 或 XP 的操作系统。 Windows 服务将在 localSystem 帐户中运行,并检查与桌面的交互。而在 windows 7 中,它会在任务计划程序中创建一个任务,并且任务计划程序与桌面交互。 请确保在具有运行任务计划程序权限的管理员帐户或帐户中运行 Windows 服务。

static public void ServiceDesktopPermission()
    {
       try
        {
            ConnectionOptions coOptions = new ConnectionOptions();
            coOptions.Impersonation = ImpersonationLevel.Impersonate;
            // CIMV2 is a namespace that contains all of the core OS and hardware classes.
            // CIM (Common Information Model) which is an industry standard for describing
            // data about applications and devices so that administrators and software
            // management programs can control applications and devices on different
           // platforms in the same way, ensuring interoperability across a network.
           ManagementScope mgmtScope = new ManagementScope(@"root\CIMV2", coOptions);
           mgmtScope.Connect();
           ManagementObject wmiService;
           wmiService = new ManagementObject("Win32_Service.Name='" + "Service1" + "'");
           ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
           InParam["DesktopInteract"] = true;
           wmiService.InvokeMethod("Change", InParam, null);
          }
         catch (Exception ex)
          {
             //TODO: Log this error
              StreamWriter sw;
             sw = File.AppendText("C:\\Sashidhar.txt");
             sw.WriteLine("Trying to open Service");
              sw.Close();
          }
     }

解释

对于使 Windows 服务与桌面交互的操作系统 Windows XP 或更低版本。

安装

打开 Visual Studio 命令提示符并键入

installutil <Path of the exe File>

安装时,提供管理员凭据,如下所示

sd.jpg

卸载

打开 Visual studio 命令提示符并键入

installutil/u <Path of the exe File>

参考文献

待续!使用 WCF 服务和 WindowServices!

© . All rights reserved.