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

由于个人需要,想找一个键盘记录的程序,从网上下载了很多,多数都是需要注册的,另外也多被杀软查杀。于是决定自己写一个,如果作为一个windows应用程序,可以实现抓取键盘的记录。想要实现随系统启动的话,其中一种方法就是要作为windows服务,把代码直接写到服务里边并不能抓取到键盘的记录,从网上翻阅资料及查看msdn才知道:

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

服务程序一般使用的是LocalSystem帐户,拥有自己的window station,和Default桌面,这个window station是不能于用户交互的,也就是说,你不能在上面显示窗口,它也不接受用户的鼠标、键盘等输入。

我们使用用户帐户登录以后,看到的桌面,是WinSta0(window station)下的Default(desktop).
WinSta0下有3个桌面:
WinLogon :以Logon对话框的形式出现.当用户登录以后,WinLogon.exe切换到Default desktop.
Default :这是Explorer.exe和所有用户程序窗口出现的地方,也就是我们通常使用windows看见的地方.应用程序就运行在这个桌面上
Screen saver :系统空闲的时候,运行屏保的桌面.

当你在“计算机管理”中选择一个服务,修改属性,选择“登录”标签页的“允许服务与桌面交互”,那么该服务就使用的是WinSta0(window station)下的Default(desktop). 你也就可以与你的服务进行交互操作了。这时,你能获取default的桌面位图,因为线程的桌面就是WinSta0下的Default。要想同时获得Winlogon桌面位图,应该先把线程的桌面设置成Winlogon。

此部分代码公布如下:

//Service1.Designer.cs文件

using System.Threading;

namespace KeyBoard
{
    partial class Service1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        Thread threadForm = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

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

        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            //
            // Service1
            //
            this.ServiceName = "Service1";

        }

        #endregion

    }
}

//Service1.cs文件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;

 

namespace KeyBoard
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        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;

            MouseKeyBoard f=new MouseKeyBoard(); //此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);
           
    }


}

嵌入式开发实战:从零开始交叉编译Linux内核(ARM架构) 交叉编译是嵌入式系统开发中的核心技术,它允许开发者在高性能的x86主机上为ARM、MIPS等不同指令集架构的目标设备生成可执行代码。其原理在于使用专门的交叉编译工具链,该工具链中的编译器、链接器等工具运行在主机上,但生成的目标代码适用于特定的嵌入式CPU架构。这项技术的核心价值在于解决了嵌入式设备自身计算资源有限、编译耗时过长甚至无法完成编译的痛点,极大地提升了开发效率。在物联网、智能硬件、路由器、NAS等ARM架构设备的系统定制、驱动开发和内核优化场景中,交叉编译是必不可少的实践。本文将聚焦于ARMv7- 阅读详情

相关推荐

c# 通过Windows服务启动外部程序

1. 新建一个Windows服务应用程序    创建项目——》Visual C# 左侧的"+"——》Windows ——》Windows 服务(右侧模板)——》输入名称,确定创建项目 2. 设置Windows服务的属性(Windows服务里没有窗体,所以点击左侧设计器里空白的地方即可在右侧属性栏里看到属性)    这里属性是控制服务器是否可以停止,暂停,继续等等的操作。根据需要选择

daming_ocean的专栏 1万+

C# WIN服务实现窗体

使用方法要注意的是 安装服务后 设置服务让可以与用户交互。 protected override void OnStart(string[] args)        {            Thread _TestForm = new Thread(new ThreadStart(StartListen));            _TestForm.Start();

Zgke 6611

c#制作简单启动画面

声明:代码照搬自SharpDevelop源码。   启动画面是程序启动加载组件时一个让用户稍微耐心等待的提示框。一个好的软件在有启动等待需求时必定做一个启动画面。启动画面可以让用户有心理准备来接受程序加载的缓慢,还可以让用户知道加载的进度和内容。本文只是记录最简单的构架。 VS2010创建一个C# Windows窗体应用程序,将主窗体改名为FormMain,再创建一个窗体起名为SplashS

每天进步一点点... 1万+

c# 通过Windows服务启动Winform程序

在服务器上,实现windows服务启动winform程序

weixin_40565908的博客 3448

windows服务程序启动运行一个程序,弹出窗口

windows服务启动应用程序,windows服务默认在Session 0,不在当前桌面,启动的程序默认也在那个Session 0,所以你看不到程序界面, 用CreateProcessAsUser启动应用程序才可以看到界面

设置c#windows服务描述及允许服务与桌面交互的3种方法

设置c#windows服务描述及允许服务与桌面交互的3种方法

使用C#创建Windows服务

本文属于原创,转载请注明出处,谢谢! 一、开发环境 操作系统:Windows 10 X64 开发环境:VS2015 编程语言:C# .NET版本:.NET Framework 4.0 目标平台:X86 二、创建Windows Service 1、新建一个Windows Service,并将项目名称改为“MyWindowsService”,如下图所示: 2、在解决方案资源管理器...

weixin_30945039的博客 815

混合动作空间在强化学习中的创新应用:PDQN与MPDQN算法解析

本文深入解析了强化学习中处理混合动作空间的PDQN与MPDQN算法。针对既有离散选择又有连续调节的复杂决策场景,PDQN通过参数化深度Q网络,巧妙结合DQN与DDPG进行交替优化;MPDQN则进一步改进,为每个离散动作提供专属参数评估以减少干扰。文章通过游戏、自动驾驶等实例阐述了其应用价值与面临的挑战。

efc123456的博客 864

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

C#WINDOWS服务交互的实现的前言:这几天想做个文件监控服务,看了一下网上的关于WINDOWS服务的文章,数量都不少,都只讲了如何做一个最基本的服务,却没有讲述如何与用户进行交互。查看了MSDN,看一下关于服务的描述: WINDOWS服务交互应用程序在不同于登录用户的交互区域的窗口区域中运行。窗口区域是包含剪贴板、一组全局原子和一组桌面对象的安全对象。由于 WINDOWS服务交互的区域不

大新软件老杨 1488

Ubuntu 24.04 + RTX 5090 部署 OpenVLA-OFT:从环境配置到机器人任务评估实战

本文详细记录了在Ubuntu 24.04 LTS系统上,为全新RTX 5090显卡配置CUDA 12.8+与PyTorch 2.7.1+开发环境,并成功部署OpenVLA-OFT视觉语言模型进行机器人任务评估的完整实战流程。文章重点解决了驱动安装、依赖版本冲突、路径设置等核心难题,为在最新硬件上运行先进AI机器人模型提供了可靠的避坑指南和性能观察。

n8m7b6v5c4的博客 595

adas硬件_ADAS智能辅助驾驶系统硬件在环(HIL)测试之硬件介绍

这篇主要分享的是ADAS融合系统的HIL测试系统的硬件结构及其作用,其主要包括上位机、机柜、雷达模拟器系统、雷达暗箱系统以及视频暗箱。 上位机 上位机主要运行HIL测试系统的相关软件,测试人员所有的前期准备工作与测试操作均在上面进行,并监控测试结果,其通过网口实现与NI实时机的通信,上位机将VeriStand项目工程下载至NI实时机运行。机柜 机柜主要由可编程电源...

weixin_39580748的博客 2242

C#——Windows窗体

MDI窗体用于同时显示多个文档,每个文档显示在各自的窗口中,MDI窗体中通常包含子菜单的窗口菜单,用于再窗口或文档之间进行切换。如果要在项目中添加一个新窗体,可以在项目名称上右击,在弹出的快捷键菜单中选择“添加”->“windows窗体”或者“添加”->“新建项”命令。在“新添加项”对话框中,选择“Windows窗体”,输入窗体名称,单击“添加”按钮,添加windows窗体。另一种是使用继承选择器创建继承窗体。删除窗体,在要删除的窗体名称上右击,在弹出的快捷菜单中选择“删除”命令,即可删除窗体。

2401_86294292的博客 4972

mybaits-plus通用CRUD详解及代码案例

文章目录mybaitsplus通用CRUD插入操作方法定义测试用例mybaitsplus主键生成策略设置自增主键设置输入主键:UUID:ID_WORKER_STR:ID_WORKER:更新操作根据id更新方法定义:方法步骤根据条件更新方法定义:更新步骤:根据条件更新(可以更新NULL)删除操作根据id删除方法定义:删除步骤:根据 entity 条件删除方法定义:删除步骤:根据ID 批量删除方法定义:删除步骤:查询操作根据id查询方法定义:查询步骤:根据id批量查询方法定义:查询步骤:根据 entity 条件

流楚丶格念的博客 3405

C#学习教程12——Windows窗体应用程序

C#学习教程,适合新手小白,附带学习源码。

Kint的博客 5万+

初探802.11协议(6)——Wi-Fi 6新特性简介

Wi-Fi 6新机制(特性)介绍

FanFF的博客 1522

学Simulink——基于直流电机的建模与控制场景实例:他励直流电机的起动与制动过程仿真

直流电机在工业控制、电动车辆、自动化设备中广泛应用。其中,他励直流电机(Separately Excited DC Motor)因其励磁绕组与电枢绕组分别供电,具有良好的调速性能和启动特性,常用于需要平稳启动和精确控制的场合。在实际应用中,电机的启动过程和制动过程对电网、机械系统以及电机本身都具有重要影响。因此,仿真分析他励直流电机的启动与制动特性,是电机控制设计的重要环节。本文将详细介绍如何使用构建一个他励直流电机的启动与制动过程仿真模型,并通过仿真分析其动态响应。本文详细介绍了如何使用构建一个。

xiaoheshang_123的博客 227

C#学习笔记四 Windows窗体应用程序

窗体是程序与用户交互的可视界面,窗体也是对象,窗体类定义了生成窗体的模版,实例化一个窗体类就产生了一个窗体。.NET框架类库的System.Windows.Forms命名空间中定义的Form类是所有窗体类的基类。1、常用属性属性:图标、标题、位置、背景等可在窗体属性面板设置,也可以代码实现。(1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体。(2)WindowS

TJT999 3万+

点云从入门到精通技术详解100篇-基于 CBCT 与口内扫描数据的牙齿点云配准

口扫生成的三维牙模型只包含牙冠结构,容易受到唾液、食物残留等杂质的干扰。像精度,但其扫描成本较高,在公立医院的普及率较低。此外,口扫探入式的体。完整、精确的牙齿信息,有助于医生更好地进行数字化辅助诊疗,提高手术的预。可以表示上颌骨、下颌骨、牙冠以及牙根的位置和形状,但其扫描分辨率较低,精配准前实现粗略的预配准来确定点云间的初始位置,为精配准提供良好的配准。该算法通过计算点对间的距离确定源点云中的某一点在目标点云中的对应。算两点之间的欧氏距离,运算量较大,而且由于算法只考虑点集间的距离而忽略。

getusushu的博客 1640

C# WinForm界面设计教程(C# Windows窗体应用程序)

WinForm 是 Windows Form 的简称,是基于 .NET Framework 平台的客户端(PC软件)开发技术,一般使用 C# 编程。C# WinForm 编程需要创建「Windows窗体应用程序」项目。 .NET 提供了大量 Windows 风格的控件和事件,我们可以直接拿来使用,上手简单,开发快速。 Windows 窗体应用程序是 C# 语言中的一个重要应用,也是 C# 语言最常见的应用。这套 C# WinForm 教程将教会大家如何使用 WinForm 进行界面设计,并绑定对应的事件,开

weixin_42715287的博客 8829

SwiftUI 5 教程之 SwiftData使用入门(教程含源码)

对我来说,记住日期很难。是的,您可以设置该日期的提醒,但该提醒无法产生紧迫感。让我们创建一个应用程序,我们可以在其中添加将来发生的事件。如果我们可以在主应用程序上看到所有即将发生的活动,那就太好了。也许将它们添加到小部件上以营造紧迫感。对于任何事件,我们需要跟踪哪些事情?我们将在下一篇文章中添加更多属性,其中我们将讨论迁移。现在,这就是我们所需要的。开始吧。

iCloudEnd的博客 987

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C#开发一个混合Windows服务和Windows窗体的程序

很多时候,我们希望服务程序可以直接运行,或者可以响应一些参数,这时候,混合Windows服务和Windows窗体的程序就排上用场了。要实现同时支持Windows服务和Windows窗体,需要在启动的第一步时判断当前运行环境是否为服务模式,可以从以下几个方面进行判断: 会话ID:Process.SessionId,获取当前进程的SessionId,为0则可以是服务模式(谢谢1楼提醒); 当前用户...

weixin_41019077的博客 301

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C# Windows 窗体编程入门详解

通过学习 WinForms 框架的开发技术,你会发现很多乐趣,可以实现自己真正想要的各种 Web 无法实现的功能,实现各种桌面工具。从中领略开发带来的快乐和成就。

张赐荣的技术博客 7087

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

使用C#创建Windows服务 并发布Windows 服务

一、开发环境 操作系统:Windows 10 X64 开发环境:VS2015 编程语言:C# .NET版本:.NET Framework 4.0 目标平台:X86 二、创建Windows Service 注:Windows Service目前配置文件似乎只能是绝对路径,相对路径时需要去操作系统根目录下操作。 1、新建一个Windows Service,并将项目名称改为“MyWind...

Andrewniu的博客 4079
上一篇: 推荐同学来公司的烦恼
下一篇: JAVA中防止SQL注入(过滤特殊字符方案)
wangguoping
博客等级 码龄19年 1粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值