积极答复者
有关OOB模式的问题

问题
-
我大致描述一下我的需要:我们老板想要用silverlight开发一个考试系统,当学生进入考试时,为了防止作弊,silverlight需要全屏,但是在浏览器中运行的silverlight全屏后,文本输入会有问题(听说Silverlight5中会有改进),但是现在只能用OOB模式才能解决这个问题。但是还有问题,全屏后需要禁止Ctrl+ESC、Alt+ESC、ALT+TAB、Window、Ctrl+Alt+Del,就是怕学生切换页面作弊,大家知道,silverlight本身权限不够,用OOB模式可以提升权限,且可以和com交互,我想通过com去修改注册表来屏蔽这些组合键,但还是未达到效果。不知道哪位大牛有没有这方面的经验,还望指教。
using (dynamic WShell = AutomationFactory.CreateObject("WScript.Shell")) { try { WShell.RegWrite(@"HKEY_CURRENT_USER\Control Panel\Desktop\CoolSwitch", "1", "REG_SZ"); ////禁用任务管理器 WShell.RegWrite(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\system\DisableTaskMgr", "1", "REG_DWORD"); ////禁用win键 //WShell.RegWrite(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoWinKeys", "1", "REG_DWORD"); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
以上代码只有将用户账户控制设为最低,且用silverlight工程作为起始工程运行时才能生效,一旦有web工程作为起始工程或发布后就会提示权限不够的异常:“试图执行未经授权的操作”。
另外,我原先做过C/S类似的功能,可以用键盘钩子去禁用这些组合键,但是需要拿到主程序的句柄,我在silverlight中同样试过,就是这个句柄拿不到,貌似权限不够,不知道能不能通过com去拿这个句柄?关键现在我对com不熟,网上只有几个有限的例子,不知哪位大牛能不能给我提供一些资料,现在这谢过了!
public class KeyboardHook { public delegate int KeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); static int hKeyboardHook = 0; KeyboardProc KeyboardHookProcedure; /// <summary> /// 钩子函数,需要引用空间(using System.Reflection;) /// 线程钩子监听键盘消息设为2,全局钩子监听键盘消息设为13 /// 线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14 /// </summary> public const int WH_KEYBOARD = 13; public const int WH_MOUSE_LL = 14; public struct KeyboardMSG { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; public int VK_CONTROL; public int VK_MENU; public int VK_DELETE; } /// <summary> /// kernel32.dll是Windows 95,Windows 98和Windows Me中使用的32位动态链接库文件。 /// kernel32.dll是负责内存管理、输入输出以及中断等工作。启动Windows系统之后, /// kernel32.dll就会被装载到不会被其他应用程序影响的受保护的内存空间中。在某些时候, /// 会出现invalid page fault(IPF)错误信息,这是由于其他应用程序视图访问kernel32.dll /// 所在的受保护内存空间引起的。不过有时,特定的某些程序也能引起这种错误。 /// </summary> /// <returns></returns> [DllImport("kernel32")] public static extern int GetCurrentThreadId(); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, KeyboardProc lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(int idHook); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name); private int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0) { KeyboardMSG m = (KeyboardMSG)Marshal.PtrToStructure(lParam, typeof(KeyboardMSG)); if ((int)m.vkCode == 91 || (int)m.vkCode == 92 || (int)m.vkCode == 10) return 1; if (((int)m.vkCode == 46) && ((int)m.vkCode == 17) && ((int)m.vkCode == 18)) return 2; if ((int)m.vkCode == 20) return 1; } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } // 安装钩子 public void KeyMaskStart() { try { if (hKeyboardHook == 0) { // 创建HookProc实例 KeyboardHookProcedure = new KeyboardProc(KeyboardHookProc); Module module = Assembly.GetExecutingAssembly().GetModules()[0]; // 设置线程钩子 hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProcedure, GetModuleHandle(module.Assembly.FullName), 0); // 如果设置钩子失败 if (hKeyboardHook == 0) { KeyMaskStop(); throw new Exception("SetWindowsHookEx failed."); } } } catch (Exception e) { MessageBox.Show(e.Message); } } // 卸载钩子 public void KeyMaskStop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (!(retKeyboard)) { throw new Exception("UnhookWindowsHookEx failed."); } } }
文中这一句会报错:
// 设置线程钩子
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProcedure,
GetModuleHandle(module.Assembly.FullName), 0);安全透明方法“FullScreen.KeyBoardHook.KeyMaskStart()”尝试通过方法“FullScreen.KeyBoardHook.GetModuleHandle(System.String)”调用本机代码失败。方法必须是安全关键或安全可靠关键,才能调用本机代码。
- 已更改类型 魔笛法 2010年9月27日 10:28