.NET实现可交互的WINDOWS服务

  这几天想做个文件监控服务,看了一下网上的关于WINDOWS服务的文章,数量都不少,都只讲了如何做一个最基本的服务,却没有讲述如何与用户进行交互。查看了MSDN,看一下关于服务的描述:

   Windows 服务应用程序在不同于登录用户的交互区域的窗口区域中运行。窗口区域是包含剪贴板、一组全局原子和一组桌面对象的安全对象。由于 Windows 服务的区域不是交互区域,因此 Windows 服务应用程序中引发的对话框将是不可见的,并且可能导致程序停止响应。同样,错误信息应记录在 Windows 事件日志中,而不是在用户界面中引发。

   .NET Framework 支持的 Windows 服务类不支持与交互区域(即登录用户)进行交互。同时,.NET Framework 不包含表示区域和桌面的类。如果 Windows 服务必须与其他区域进行交互,则需要访问非托管的 Windows API。

  也就是说我们要实现可交互的服务(比如我们想给服务在运行时做一些参数设置等),那我们一定要using System.Runtime.InteropServices

  那么来看一下如果才能实现一个可交互的服务呢。步骤与实现基本的服务一样(各位可自行参考MSDN或网上google一下).

  在实现OnStart时要注意,这里可不能弹出一个FORM什么的。这样做是没有任何反应的。我们可以在这个方法里运行一个线程。该线程需要访问窗口区域对象或桌面对象,当然 framework里是没有提供这些的,要访问非托管代码的。

  来看一下代码,再运行试一下。

using System;

using System.
Collections;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.ServiceProcess;

using System.Threading;

using System.Runtime.InteropServices;

namespace FileWatchService

{

public class Service1 : System.ServiceProcess.ServiceBase

{

///

/// 必需的设计器变量。

///

private System.ComponentModel.
Container components = null;

Thread threadForm = null;

public Service1()

{

// 该调用是 Windows.Forms 组件设计器所必需的。

InitializeComponent();

// TODO: 在 InitComponent 调用后添加任何初始化

}

#region 组件设计器生成的代码

///

/// 设计器支持所需的方法 - 不要使用代码编辑器

/// 修改此方法的内容。

///

private void InitializeComponent()

{

//

// Service1

//

this.ServiceName = "JadeWatchService";

}

#endregion

[STAThread]

static void Main()

{

System.ServiceProcess.ServiceBase.Run(new Service1());

}

///

/// 清理所有正在使用的资源。

///

protected override void Dispose(bool disposing)

{

if (disposing)

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose(disposing);

}

///

/// 设置具体的操作,以便服务可以执行它的工作。

///

protected override void OnStart(string[] args)

{

threadForm = new Thread(new ThreadStart(FormShow));

threadForm.Start();

}

///

/// 停止此服务。

///

protected override void OnStop()

{

if (threadForm != null)

{

if (threadForm.IsAlive)

{

threadForm.Abort();

threadForm = null;

}

}

}

void FormShow()

{

GetDesktopWindow();

IntPtr hwinstaSave = GetProcessWindowStation();

IntPtr dwThreadId = GetCurrentThreadId();

IntPtr hdeskSave = GetThreadDesktop(dwThreadId);

IntPtr hwinstaUser = OpenWindowStation("WinSta0", false, 33554432);

if (hwinstaUser == IntPtr.Zero)

{

RpcRevertToSelf();

return;

}

SetProcessWindowStation(hwinstaUser);

IntPtr hdeskUser = OpenDesktop("Default", 0, false, 33554432);

RpcRevertToSelf();

if (hdeskUser == IntPtr.Zero)

{

SetProcessWindowStation(hwinstaSave);

CloseWindowStation(hwinstaUser);

return;

}

SetThreadDesktop(hdeskUser);

IntPtr dwGuiThreadId = dwThreadId;

Form1 f = new Form1(); //此FORM1可以带notifyIcon,可以显示在托盘里,用户可点击托盘图标进行设置

System.Windows.Forms.
Application.Run(f);

dwGuiThreadId = IntPtr.Zero;

SetThreadDesktop(hdeskSave);

SetProcessWindowStation(hwinstaSave);

CloseDesktop(hdeskUser);

CloseWindowStation(hwinstaUser);

}

[DllImport("user32.dll")]

static extern int GetDesktopWindow();

[DllImport("user32.dll")]

static extern IntPtr GetProcessWindowStation();

[DllImport("
kernel32.dll")]

static extern IntPtr GetCurrentThreadId();

[DllImport("user32.dll")]

static extern IntPtr GetThreadDesktop(IntPtr dwThread);

[DllImport("user32.dll")]

static extern IntPtr OpenWindowStation(string a, bool b, int c);

[DllImport("user32.dll")]

static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags,

bool fInherit, uint dwDesiredAccess);

[DllImport("user32.dll")]

static extern IntPtr CloseDesktop(IntPtr p);

[DllImport("rpcrt4.dll", SetLastError = true)]

static extern IntPtr RpcImpersonateClient(int i);

[DllImport("rpcrt4.dll", SetLastError = true)]

static extern IntPtr RpcRevertToSelf();

[DllImport("user32.dll")]

static extern IntPtr SetThreadDesktop(IntPtr a);

[DllImport("user32.dll")]

static extern IntPtr SetProcessWindowStation(IntPtr a);

[DllImport("user32.dll")]

static extern IntPtr CloseWindowStation(IntPtr a);

}

}

时间: 2024-10-26 15:50:55

.NET实现可交互的WINDOWS服务的相关文章

艾伟:.NET实现可交互的WINDOWS服务

这几天想做个文件监控服务,看了一下网上的关于WINDOWS服务的文章,数量都不少,都只讲了如何做一个最基本的服务,却没有讲述如何与用户进行交互.查看了MSDN,看一下关于服务的描述: Windows 服务应用程序在不同于登录用户的交互区域的窗口区域中运行.窗口区域是包含剪贴板.一组全局原子和一组桌面对象的安全对象.由于 Windows 服务的区域不是交互区域,因此 Windows 服务应用程序中引发的对话框将是不可见的,并且可能导致程序停止响应.同样,错误信息应记录在 Windows 事件日志中

Visual Basic .NET 代码示例:与 Windows 服务交互 (2003年2月17日)

Visual Basic .NET 代码示例:与 Windows 服务交互 (2003年2月17日) 此示例显示了如何通过代码控制已安装的 Windows 服务. http://www.microsoft.com/china/msdn/library/dnvssamp/html/vbcs_InteractingwithaWindowsService.asp

vista和win7在windows服务中交互桌面权限问题解决方法:穿透Session 0 隔离_C#教程

Windows 服务在后台执行着各种各样任务,支持着我们日常的桌面操作.有时候可能需要服务与用户进行信息或界面交互操作,这种方式在XP 时代是没有问题的,但自从Vista 开始你会发现这种方式似乎已不起作用. Session 0 隔离实验 下面来做一个名叫AlertService 的服务,它的作用就是向用户发出一个提示对话框,我们看看这个服务在Windows 7 中会发生什么情况. using System.ServiceProcess; using System.Windows.Forms;

设置Windows服务允许进行桌面交互,实现屏幕监控

默认情况下,Windows服务基于安全考虑,是不允许任何服务程序和桌面进行交互的,也就是说,使用任何的Windows Form 的很多特性将会莫名奇妙的不起作用,如进行屏幕截图,或者使用System.Windows.Form.Timer对象也不行.由于Windows服务具有难以调试的特点,如果不注意这点,你反复检查自己的代码,都很难发现问题的所在的,我开始就是摸索了很久才发现,呵呵. Windows服务的优点有:1. 能够自动运行.2. 不要求用户交互.3. 在后台运行. 一般情况下,Windo

用C#开发Windows服务监控系统使用

window|监控 摘要 本文将向你展示如何用C#开发一个Windows服务来记录系统使用情况. 每一个人都想知道他们每天在什么时间启动和关闭自己的系统,以及系统每天运行了多少时间.如果用一个DataGrid控件来显示系统启动.关闭及所消耗的时间将是一个不错的主意. 在本文中,我提供了一种方法来实现这一目标-使用C#开发一个Windows服务.其实,每个人都了解一点Windows服务.但是,为了介绍之目的,我仅尽可能少得解释一下Windows服务.然后,我们来讨论如何设计一个这样的应用程序. 一

使用srvany.exe将程序安装成windows服务的详细教程

srvany.exe介绍 srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说srvany只是其注册程序的服务外壳,这个特性对于我们 来说非常实用,我们可以通过它让我们的程序以SYSTEM账户启动,或者实现随机器启动而自启动,也可以隐藏不必要的窗口,比如说控制台窗口等等. 资源下载 你可以通过下载并安装Microsoft Windows Resource Kits 获得或者直接在本文

Windows服务编写(Windows Service,system权限)程序显示界面与用户交互(xp,win7通用)_C#教程

1.VC2008中编写"Windows服务"(Windows Service)程序 源码资源下载:/201604/yuanma/TestService_jb51.rar vc2008下新建一个 ATL 项目-> 选择创建一个"服务"类型的ATL 项目TestService,将生成如下代码, class CTestServiceModule : public CAtlServiceModuleT< CTestServiceModule, IDS_SERVI

C#通过创建Windows服务启动程序的方法详解_C#教程

本文实例讲述了C#通过创建Windows服务启动程序的方法.分享给大家供大家参考,具体如下: 1. 新建一个Windows服务应用程序 创建项目-->Visual C# 左侧的"+"-->Windows -->Windows 服务(右侧模板)-->输入名称,确定创建项目 2. 设置Windows服务的属性(Windows服务里没有窗体,所以点击左侧设计器里空白的地方即可在右侧属性栏里看到属性) 这里属性是控制服务器是否可以停止,暂停,继续等等的操作.根据需要选择

使用PowerShell找到可写的Windows服务并利用

本文讲的是使用PowerShell找到可写的Windows服务并利用,从DidierStevens的博客学到了一些技巧,本文将要对其中涉及到的技巧进行测试总结,并开源一个powershell脚本,用来寻找可被替换的服务,实现自动化利用. 0x01 简介 本文将要介绍以下内容: · 使用c#编写可供Windows服务调用的程序 · psexec的-i参数使用技巧 · sc命令使用技巧 · 通过powershell获取服务对应的可执行文件路径 · 自动化利用脚本开发细节 0x02 使用c#编写可供W