当前位置: 移动技术网 > IT编程>开发语言>.net > .NET实现可交互的WINDOWS服务的实例代码

.NET实现可交互的WINDOWS服务的实例代码

2017年12月12日  | 移动技术网IT编程  | 我要评论

无盐女美男多多,以琳网,摇头dj

  这几天想做个文件监控服务,看了一下网上的关于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
{
    publicclass service1 : system.serviceprocess.servicebase
    {
        ///
        /// 必需的设计器变量。
        ///
private system.componentmodel.container components =null;
        thread threadform =null;
        public service1()
        {
            // 该调用是 windows.forms 组件设计器所必需的。
            initializecomponent();

            // todo: 在 initcomponent 调用后添加任何初始化
        }

        #region 组件设计器生成的代码
        ///
        /// 设计器支持所需的方法 - 不要使用代码编辑器
        /// 修改此方法的内容。
        ///
privatevoid initializecomponent()
        {
            //
            // service1
            //
this.servicename ="jadewatchservice";

        }
        #endregion
        [stathread]
        staticvoid main()
        {
            system.serviceprocess.servicebase.run(new service1());

        }
        ///
        /// 清理所有正在使用的资源。
        ///
protectedoverridevoid dispose(bool disposing)
        {
            if (disposing)
            {
                if (components !=null)
                {
                    components.dispose();
                }
            }
            base.dispose(disposing);
        }

        ///
        /// 设置具体的操作,以便服务可以执行它的工作。
        ///
protectedoverridevoid onstart(string[] args)
        {
            threadform =new thread(new threadstart(formshow));
            threadform.start();
        }

        ///
        /// 停止此服务。
        ///
protectedoverridevoid 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")]
        staticexternint getdesktopwindow();

        [dllimport("user32.dll")]
        staticextern intptr getprocesswindowstation();

        [dllimport("kernel32.dll")]
        staticextern intptr getcurrentthreadid();

        [dllimport("user32.dll")]
        staticextern intptr getthreaddesktop(intptr dwthread);

        [dllimport("user32.dll")]
        staticextern intptr openwindowstation(string a, bool b, int c);

        [dllimport("user32.dll")]
        staticextern intptr opendesktop(string lpszdesktop, uint dwflags,
        bool finherit, uint dwdesiredaccess);

        [dllimport("user32.dll")]
        staticextern intptr closedesktop(intptr p);

        [dllimport("rpcrt4.dll", setlasterror =true)]
        staticextern intptr rpcimpersonateclient(int i);


        [dllimport("rpcrt4.dll", setlasterror =true)]
        staticextern intptr rpcreverttoself();

        [dllimport("user32.dll")]
        staticextern intptr setthreaddesktop(intptr a);

        [dllimport("user32.dll")]
        staticextern intptr setprocesswindowstation(intptr a);
        [dllimport("user32.dll")]
        staticextern intptr closewindowstation(intptr a);
    }
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网