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. 关于import android.support.v4.app.ContextCompat;找不到contextcompat的解决方法

    android迁移到了androidx,那么相关库的import就有问题了,需要转变为androidx的,这里比如 import android.support.v4.app.ContextCompa ...

  2. 极简 Node.js 入门 - 2.1 Path

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  3. 2020-04-09:TCP的四次挥手中为什么要有TIME_WAIT状态?

    TIME_WAIT状态存在有两个原因.<1>可靠终止TCP连接.如果最后一个ACK报文因为网络原因被丢弃,此时server因为没有收到ACK而超时重传FIN报文,处于TIME_WAIT状态 ...

  4. Kinect+unity 实现体感格斗闯关小游戏

    文章目录 项目地址 1 项目概况 1.1 项目简介 1.2 项目目的 1.3 主要技术 2 设计 2.1 基本概念 2.2 框架 2.3 算法 2.4 模型 2.5 调查问卷 3 实现 3.1 技术难 ...

  5. Linux中.bashrc与.bash_profile的对比

    如果你平时在命令行上花费了大量时间,那么你可能会萌生出希望定制 Shell 环境的想法.今天本文就和大家讲解该如何实现你们的这个想法.其实可以通过创建别名.向环境变量 $PATH 添加新目录或更改 S ...

  6. 多次调用Promise的then会返回什么?

    //做饭 function cook(){ console.log('开始做饭.'); var p = new Promise(function(resolve, reject){ //做一些异步操作 ...

  7. Maven报错Missing artifact jdk.tools:jdk.tools:jar:1.7

    1.eclipse中Maven项目的pom文件报错: 2.解决方法: 直接在pom.xml中加上一个依赖项目: <dependency>      <groupId>jdk.t ...

  8. RPC 框架 Dubbo 从理解到使用(一)

    技术架构演变 单一应用架构 通俗地讲,"单体应用(monolith application)"就是将应用程序的所有功能都打包成一个独立的单元.当网站流量很小时,只需一个应用,将所有 ...

  9. PythonCrashCourse 第二章习题

    2.3 个性化消息:将用户的姓名存到一个变量中,并向该用户显示一条消息.显示的消息应非常简单,如"Hello Eric, would you like to learn some Pytho ...

  10. Java之reflection(反射机制)——通过反射操作泛型,注解

    一.反射操作泛型(Generic) Java采用泛型擦除机制来引入泛型.Java中的泛型仅仅是给编译器Javac使用的,确保数据的安全性和免去强制类型转换的麻烦.但是编译一旦完成,所有和泛型有关的类型 ...