项目笔记---Windows Service调用Windows API问题
2015-03-06 16:08
357 查看
概要
此文来自于最近一个“诡异”的Windows API调用发现Windows Service在调用某些Windows API的过程中失效,在经过漫长的Baidu,之后终于在StackOverFlow上找到了答案,今天希望把这个问题记录下来,方便大家Baidu -。-需求是什么?
internal class Win32API { #region Constant private const uint KEYEVENTF_EXTENDEDKEY = 0x1; private const uint KEYEVENTF_KEYUP = 0x2; #endregion #region Public Property public static IServiceLog Log { get; set; } #endregion #region External Import /// <summary> /// Keybd_events the specified b vk. /// </summary> /// <param name="bVk">The b vk.</param> /// <param name="bScan">The b scan.</param> /// <param name="dwFlags">The dw flags.</param> /// <param name="dwExtraInfo">The dw extra information.</param> [System.Runtime.InteropServices.DllImport("user32.dll")] static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); /// <summary> /// Messages the box. /// </summary> /// <param name="h">The h.</param> /// <param name="m">The m.</param> /// <param name="c">The c.</param> /// <param name="type">The type.</param> /// <returns></returns> [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern int MessageBox(int h, string m, string c, int type); /// <summary> /// Gets the focus. /// </summary> /// <returns></returns> [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern IntPtr GetFocus(); #endregion #region Public Method /// <summary> /// Sends the key. /// </summary> /// <param name="str">The string.</param> public static void SendKey(string str) { var charray = str.ToCharArray(); for (int i = 0; i < charray.Length; i++) { CharToInt(charray[i]); } KeyBoardDo(13, 0); } #endregion #region Private Method /// <summary> /// Keys the board do. /// </summary> /// <param name="key">The key.</param> private static void KeyBoardDo(int[] key) { foreach (int k in key) { keybd_event((byte)k, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0); } foreach (int k in key) { keybd_event((byte)k, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); } } /// <summary> /// Keys the board do. /// </summary> /// <param name="key">The key.</param> /// <param name="sheft">The sheft.</param> private static void KeyBoardDo(int key, int sheft) { Log.WriteInfo("KeyBoard Simulate Char: " + key); if (sheft == 16) { keybd_event((byte)sheft, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); System.Threading.Thread.Sleep(10); } keybd_event((byte)key, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); System.Threading.Thread.Sleep(10); keybd_event((byte)key, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); System.Threading.Thread.Sleep(10); if (sheft == 16) { keybd_event((byte)sheft, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); System.Threading.Thread.Sleep(10); } } /// <summary> /// Characters to int. /// </summary> /// <param name="ch">The ch.</param> /// <returns></returns> private static int CharToInt(char ch) { int chint = 32; int sheft = 16; switch (ch) { case '0': chint = 48; KeyBoardDo(chint, 0); break; case '1': chint = 49; KeyBoardDo(chint, 0); break; case '2': chint = 50; KeyBoardDo(chint, 0); break; case '3': chint = 51; KeyBoardDo(chint, 0); break; case '4': chint = 52; KeyBoardDo(chint, 0); break; case '5': chint = 53; KeyBoardDo(chint, 0); break; case '6': chint = 54; KeyBoardDo(chint, 0); break; case '7': chint = 55; KeyBoardDo(chint, 0); break; case '8': chint = 56; KeyBoardDo(chint, 0); break; case '9': chint = 57; KeyBoardDo(chint, 0); break; case 'A': chint = 65; KeyBoardDo(chint, sheft); break; case 'B': chint = 66; KeyBoardDo(chint, sheft); break; case 'C': chint = 67; KeyBoardDo(chint, sheft); break; case 'D': chint = 68; KeyBoardDo(chint, sheft); break; case 'E': chint = 69; KeyBoardDo(chint, sheft); break; case 'F': chint = 70; KeyBoardDo(chint, sheft); break; case 'G': chint = 71; KeyBoardDo(chint, sheft); break; case 'H': chint = 72; KeyBoardDo(chint, sheft); break; case 'I': chint = 73; KeyBoardDo(chint, sheft); break; case 'J': chint = 74; KeyBoardDo(chint, sheft); break; case 'K': chint = 75; KeyBoardDo(chint, sheft); break; case 'L': chint = 76; KeyBoardDo(chint, sheft); break; case 'M': chint = 77; KeyBoardDo(chint, sheft); break; case 'N': chint = 78; KeyBoardDo(chint, sheft); break; case 'O': chint = 79; KeyBoardDo(chint, sheft); break; case 'P': chint = 80; KeyBoardDo(chint, sheft); break; case 'Q': chint = 81; KeyBoardDo(chint, sheft); break; case 'R': chint = 82; KeyBoardDo(chint, sheft); break; case 'S': chint = 83; KeyBoardDo(chint, sheft); break; case 'T': chint = 84; KeyBoardDo(chint, sheft); break; case 'U': chint = 85; KeyBoardDo(chint, sheft); break; case 'V': chint = 86; KeyBoardDo(chint, sheft); break; case 'W': chint = 87; KeyBoardDo(chint, sheft); break; case 'X': chint = 88; KeyBoardDo(chint, sheft); break; case 'Y': chint = 89; KeyBoardDo(chint, sheft); break; case 'Z': chint = 90; KeyBoardDo(chint, sheft); break; case 'a': chint = 65; KeyBoardDo(chint, 0); break; case 'b': chint = 66; KeyBoardDo(chint, 0); break; case 'c': chint = 67; KeyBoardDo(chint, 0); break; case 'd': chint = 68; KeyBoardDo(chint, 0); break; case 'e': chint = 69; KeyBoardDo(chint, 0); break; case 'f': chint = 70; KeyBoardDo(chint, 0); break; case 'g': chint = 71; KeyBoardDo(chint, 0); break; case 'h': chint = 72; KeyBoardDo(chint, 0); break; case 'i': chint = 73; KeyBoardDo(chint, 0); break; case 'j': chint = 74; KeyBoardDo(chint, 0); break; case 'k': chint = 75; KeyBoardDo(chint, 0); break; case 'l': chint = 76; KeyBoardDo(chint, 0); break; case 'm': chint = 77; KeyBoardDo(chint, 0); break; case 'n': chint = 78; KeyBoardDo(chint, 0); break; case 'o': chint = 79; KeyBoardDo(chint, 0); break; case 'p': chint = 80; KeyBoardDo(chint, 0); break; case 'q': chint = 81; KeyBoardDo(chint, 0); break; case 'r': chint = 82; KeyBoardDo(chint, 0); break; case 's': chint = 83; KeyBoardDo(chint, 0); break; case 't': chint = 84; KeyBoardDo(chint, 0); break; case 'u': chint = 85; KeyBoardDo(chint, 0); break; case 'v': chint = 86; KeyBoardDo(chint, 0); break; case 'w': chint = 87; KeyBoardDo(chint, 0); break; case 'x': chint = 88; KeyBoardDo(chint, 0); break; case 'y': chint = 89; KeyBoardDo(chint, 0); break; case 'z': chint = 90; KeyBoardDo(chint, 0); break; case ';': chint = 186; KeyBoardDo(chint, 0); break; case '=': chint = 187; KeyBoardDo(chint, 0); break; case ',': chint = 188; KeyBoardDo(chint, 0); break; case '-': chint = 189; KeyBoardDo(chint, 0); break; case '.': chint = 190; KeyBoardDo(chint, 0); break; case '/': chint = 191; KeyBoardDo(chint, 0); break; case '`': chint = 192; KeyBoardDo(chint, 0); break; case '[': chint = 219; KeyBoardDo(chint, 0); break; case ']': chint = 221; KeyBoardDo(chint, 0); break; case '\'': chint = 222; KeyBoardDo(chint, 0); break; } return chint; } #endregion }
View Code
同样的代码在Windows Service调用没有任何效果,原因就出在这里:Session 0 Isolation,简而言之就是在Win XP以及之前的windows服务(系统服务和用户编写的服务)都运行在最高权限的Session 0 中,但是在Vista以及之后的系统中用户所编写的服务被隔离开,为的是系统安全性考虑,被隔离开的服务中受影响的是一些基于图形界面的系统调用都将失效,如“User32.dll”中的MessageBox调用,同时也包含本文中的模拟键盘的keybd_event调用。
有兴趣的朋友可以自行测试下,原理很简单,这里就不给出更多的代码了。
注:Vista之后系统服务权限图。
结语
说点题外话,其实这个问题就是一句话的事:Win7下Windows服务不能调用键盘模拟事件,为什么在百度搜来搜去,基本没有什么有价值的信息,包括CSDN等等。后来,不得不开着FQ软件去Google,或者再去StackOverFlow提问,搜索问题,这里也不去抱怨什么,只希望作为码农的我以及跟我一样的人能更熟练的掌握英语,Happy To Search On Google.引用
Session 0 Isolation: https://msdn.microsoft.com/en-us/library/windows/hardware/dn653293(v=vs.85).aspxStackOverFlow Discuss:http://stackoverflow.com/questions/16959963/how-to-reset-windows-idle-timer-through-a-windows-service
相关文章推荐
- 项目笔记---Windows Service调用Windows API问题
- Windows Service中调用Winform程序之log4net问题.
- Windows Service中调用WebService时(StreamReaderl类的文件读取问题)
- Windows Service 项目中 Entity Framework 无法加载的问题
- Spring + Shiro 项目 + HttpSessionListener 【调用springService问题】&【Session失效问题】
- windows下的动态链接问题(.dll文件的编写与调用)
- 没头没尾--项目开发笔记:项目问题的阶段性总结,下一步…………
- Spring事务配置笔记(实现不同Service间调用事务)
- [转]小问题: windows组件调用失败,无法加载安装安装程序:Wbemupgd.dll
- windows sharepoint service 3.0 wss3 URL 映射问题,差点把网站废掉
- [转]解决 Windows XP Service Pack 2 中 Windows 防火墙的设置问题
- Windows Service 初始化代码中追加断点问题
- [-项目随笔-] 问题:在windows和linux下运行正常,solaris出现中文问题~
- windows命令行下随时随地调用csc编译器的方法(解决dos下编译.net程序找不到CSC的问题)
- c#中windows窗体调用问题
- 学习笔记:使用Web Service Software Factory开发简易留言本服务以及Mobile调用实现-1.创建Service
- 移动项目开发笔记(Asp.net控件之间的方法的互相调用)
- 关于卸载windows service后再重新安装遇到的特殊问题
- 调试状态下Windows Service与Timer处理事件的问题
- Windows service安装项目