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);
???????????
??? }


}

轉載于:https://www.cnblogs.com/mutuan/p/3959847.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375641.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375641.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375641.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

error: default argument given for parameter 4

原因&#xff1a;定義函數的時候參數部分有默認值&#xff0c;如下&#xff1a; int classA::print(int a 0) {std::cout << a << std::endl; }分析&#xff1a;聲明函數時參數可以有默認值&#xff0c;定義時不能。

python2.7虛擬環境virtualenv安裝及使用

一 、虛擬環境virtualenv安裝 1. 安裝virtualenv 將Python的目錄添加到系統環境變量后&#xff0c;在命令行輸入&#xff1a; pip install virtualenv C:\Users\heroicai\Desktop>pip install virtualenv2. 建立虛擬環境 在桌面上建立建立一個虛擬環境myenv,輸入:virtualenv…

Io 異常: The Network Adapter could not establish the connection

Io 異常: The Network Adapter could not establish the connection 這個異常的出現一般與數據庫和你的PC的設置有關 這種異常的出現大致上有下面幾種&#xff1a; 1。IP錯誤。 在設置URL時錯誤&#xff0c;例如&#xff1a;jdbc:oracle:thin:192.168.0.36:1521:sharp 數據庫服…

git 刪除tag

git tag -d v1.0如果 tag 已經在遠程分支&#xff0c;還需執行一句git push origin :refs/tags/v1.0另&#xff1a;打 tag 的時候最好加上 description&#xff0c;防止出現未知的錯誤&#xff0c;如 Jenkins 集成的時候生成的包名不對等。

leetcode 的shell部分4道題整理

對shell的某些細節還不是十分熟悉&#xff0c;借鑒了好多別人的東西 1. Word Frequency此題很簡單&#xff0c;只要能排序就可以cat words.txt |tr -s " " "\n" sort | unique -c | sort -r | awk {print $2" "$1}2. Valid Phone Numbers cat …

Mysql操作集錦

mysql安裝成功后可以看到已經存在mysql、information_schema和test這個幾個數據庫&#xff0c;information_schema庫中有一個名為COLUMNS的表&#xff0c;這個表中記錄了數據庫中所有表的字段信息。知道這個表后&#xff0c;獲取任意表的字段就只需要一條select語句即可。 例如…

shadows a parameter

原因&#xff1a;函數內聲明變量與參數名相同。 如&#xff1a; void print(int hello) {int hello;std::cout << hello << std::endl; }解決辦法&#xff1a;改變參數參數名或者局部變量名

iOS 9之WatchKit for WatchOS 2

金田&#xff08;github示例源碼&#xff09; 自AppleWatch發行的同時就可以為AppWatch開發相應的應用程序&#xff0c;不過最初的版本&#xff0c;能開發的功能極為有限&#xff0c;所以也只是有少數的App廠商為Apple定制了App&#xff0c;所以迄今為止&#xff0c;Apple Stor…

創建響應式布局的10款優秀網格工具集錦

在這篇文章中&#xff0c;我們為您呈現了一組優秀的網格工具清單。如果我們錯過了任何沒有列出在這個清單上的東西&#xff0c;請分享給我們。如果網頁設計和開人員采用了正確的工具集&#xff0c;并基于一個靈活的網格架構&#xff0c;以及能夠把響應圖像應用到到設計之中&…

expected initializer before

原因&#xff1a;某個地方缺少分號 如&#xff1a; void print(int a) {int b ///wrong herestd::cout << a << std::endl; }解決&#xff1a;重點排查報錯行前幾行的變量聲明等。

memcpy、memmove、memset、memchr、memcmp、strstr詳解

第一部分  綜述 memcpy、memmove、memset、memchr、memcmp都是C語言中的庫函數&#xff0c;在頭文件string.h中。memcpy和memmove的作用是拷貝一定長度的內存的內容&#xff0c;memset用于緩沖區的填充工作&#xff0c;memchr用于字符的查找工作&#xff0c;memcmp用于比較內…

21分鐘 MySQL 入門教程(轉載)

鏈接&#xff1a;http://www.cnblogs.com/mr-wid/archive/2013/05/09/3068229.html轉載于:https://www.cnblogs.com/hxb316/p/3966731.html

Maven倉庫詳解

轉載自&#xff1a;Maven入門指南④&#xff1a;倉庫 1 . 倉庫簡介 沒有 Maven 時&#xff0c;項目用到的 .jar 文件通常需要拷貝到 /lib 目錄&#xff0c;項目多了&#xff0c;拷貝的文件副本就多了&#xff0c;占用磁盤空間&#xff0c;且難于管理。Maven 使用一個稱之為倉庫…

c++ 從 string 到 short

string test"1234"; short *p reinterpret_cast<short*>(const_cast<char*>(test.c_str()));從 short 到 char * char *q reinterpret_cast<char*>(const_cast<short*>(p));還可以利用 memcpy 這個函數 #include <cstring>short a…

JavaScript02

JavaScript02 如果<head>標簽中包含的外部文件很多&#xff0c;那么這將直接導致頁面展示速度很慢。因為html只有當<body>元素開始之后&#xff0c;才會開始頁面展示動作&#xff0c;因此&#xff0c;最直接的解決辦法就是&#xff0c;將一部分不是頁面加載之后立刻…

.NET使用NPOI讀取Word模板并替換關鍵字并下載

NPOI 是 POI 項目的 .NET 版本。POI是一個開源的Java讀寫Excel、WORD等微軟OLE2組件文檔的項目。 使用 NPOI 你就可以在沒有安裝 Office 或者相應環境的機器上對 WORD/EXCEL 文檔進行讀寫 NPOI下載地址&#xff1a;http://npoi.codeplex.com/ 以下代碼僅供參考&#xff0c;請根…

中間件、MetaQ入門學習

目錄 1. 中間件技術 2. MetaQ中間件 3. MetaQ編程實踐 1. 中間件技術 0x1: 中間件簡介 中間件(Middleware)是提供系統軟件和應用軟件之間連接的軟件&#xff0c;以便于軟件各部件之間的溝通&#xff0c;特別是應用軟件對于系統軟件的集中的邏輯&#xff0c;在現代信息技術應用框…

MyBatis 入門到精通(二) SQL語句映射XML文件

MyBatis 真正強大之處就在這些映射語句&#xff0c;也就是它的魔力所在。對于它的強大功能&#xff0c;SQL 映射文件的配置卻非常簡單。 如果您比較SQL 映射文件配置與JDBC 代碼&#xff0c;您很快可以發現&#xff0c;使用SQL 映射文件配置可以節省95%的代碼量。MyBatis 被創建…

Monitoring the process execution and memory consumption in its lifetime

<?xml version"1.0" encoding"utf-8"?> Monitoring the process execution and memory consumption in its lifetimeMonitoring the process execution and memory consumption in its lifetime Recently, I am working on a research project whi…

設置和清除LD_LIBRARY_PATH

"" 設置 export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/the/path/you/want/setexport LD_LIBRARY_PATH/the/path/you/want/set "" 查看設置 echo $LD_LIBRARY_PATH "" 清除 unset LD_LIBRARY_PATH