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

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

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

  那么来看一下如果才能实现一个可交互的服务呢。步骤与实现基本的服务一样(各位可自行参考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, );
if ( hwinstaUser == IntPtr.Zero )
{
RpcRevertToSelf();
return;
}
SetProcessWindowStation( hwinstaUser );
IntPtr hdeskUser = OpenDesktop( "Default", , false, );
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 );
}
}

.NET实现可交互的WINDOWS服务(转载自CSDN"烈火蜓蜻")的更多相关文章

  1. C# 通过服务启动窗体(把窗体添加到服务里)实现用户交互的windows服务[转发]

    由于个人需要,想找一个键盘记录的程序,从网上下载了很多,多数都是需要注册的,另外也多被杀软查杀.于是决定自己写一个,如果作为一个windows应用程序,可以实现抓取键盘的记录.想要实现随系统启动的话, ...

  2. 使用Topshelf创建Windows服务[转载]

    概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的 ...

  3. [转]安装openoffice,并且配置为windows服务

    [转]安装openoffice,并且配置为windows服务 http://blog.csdn.net/zzzz3621/article/details/18400277 下载windows reso ...

  4. windows服务与自启动程序的区别(转载)

    转载:http://blog.csdn.net/anddy926/article/details/8464142 在客户端服务器项目实践中,作为服务端必须保持程序的24小时不间断运行,需要做一个监控, ...

  5. [转]Windows服务“允许服务与桌面交互”的使用和修改方法

    上一篇文章是纯 C# 代码的形式勾上 “允许服务与桌面交互” 选项的 本文转载自:http://blog.csdn.net/lanruoshui/article/details/4756408 描述: ...

  6. 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

        在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...

  7. [转]解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

    服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...

  8. 设置c#windows服务描述及允许服务与桌面交互的几种方法(转)

    方法一: 在ProjectInstaller.cs重写 install() ,Uninstall()方法 public override void Install(IDictionary stateS ...

  9. C#穿透session隔离———Windows服务启动UI交互程序

    在Windows服务里面启动其他具有界面的应用程序,需要穿透session隔离,尝试了很多种方法,都可行,现在一一列举下来,并写下几个需要注意的地方. 需要注意的地方 首先要将服务的Account属性 ...

随机推荐

  1. MySQL 插入或更新

    MySQL DML 记录 数据操纵语言DML(Data Manipulation Language),用户通过它可以实现对数据库的基本操作. 记录一些遇到的语法,以便随时查阅. 插入或更新 ON DU ...

  2. URL中加号(+)转义问题

    URL中加号(+)转义问题 前端通过URL传入一个参数,在后台日志中发现参数中的加号变成了空格. 前端传入a+b 后台日志a b 可以看到,+ 变成了空格. 先说结论 HTTP为了避免歧义,一些字符传 ...

  3. Java基础—继承

    继承是面向对象的核心特征之一,是由已有类创建新类的机制.利用继承机制,可以先创建一个具有共性的一般类,然后根据该一般类创建具有特殊性的新类,新类继承一般类的属性和方法,并根据需要增加自己的新属性和方法 ...

  4. Fixing the train-test resolution discrepancy

  5. java Hibernate 用法

    Hibernate 用法总结: import java.io.Serializable; import java.sql.SQLException; import java.util.Collecti ...

  6. 2020-05-11:redis 10G 内存开一个实例 和redis 1G内存开10个实例有什么区别

    福哥答案2020-05-11: 此答案不完善,仅供参考.开10个实例相对更占资源,在多核下能充分利用资源.

  7. 2020-04-10:有一个 API 服务,后端只使用了数据库来持久化数据,平时在 API 网关上监控到响应时间平均值大约为10ms,现在突然上涨到 5s,而且一直居高不下。请简单描述一下你排查这个问题的思路。

    福哥答案2020-04-11: 1 排查api服务 是否是有大量请求 2 查看mysql的系统情况 cpu 磁盘io 连接数 还是要先定位问题出现在哪个环节    

  8. k8s 安装 istio 的坑

    本文针对于二进制部署的k8s安装istio1.67版本 没有设置admin.conf的小伙伴请参考 https://www.cnblogs.com/Tempted/p/13469772.html 1. ...

  9. LDA线性判别分析原理及python应用(葡萄酒案例分析)

    目录 线性判别分析(LDA)数据降维及案例实战 一.LDA是什么 二.计算散布矩阵 三.线性判别式及特征选择 四.样本数据降维投影 五.完整代码 结语 一.LDA是什么 LDA概念及与PCA区别 LD ...

  10. 笔试算法稳了,GitHub 50k Star《labuladong的算法小抄》

    秋招算法有救了!!! 前不久在 GitHub 出现了一个手把手带你刷 LeetCode 的项目:fucking-algorithm. 该项目此前在 GitHub 开源后,连续多次霸榜 GitHub T ...