我想使用以下代码在某个时间访问键盘的状态。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Input;
namespace some.any
{
public class ANY_CLASS
{
[STAThread] //seems to do nothing here
public static short ThisIsCalledByAnExternalProgram()
{
try
{
if (Keyboard.IsKeyDown(Key.LeftAlt))
{
return 1;
}
else
{
return 0;
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return 2;
}
}
}
此代码需要一些 dll 才能编译:WindowsBase.dll 和 PresentationCore.dll
键盘需要一个 STA 线程,通常我会将 [STAThread] 属性写入主函数并且它会工作,但此代码将用作 dll,所以我不能这样做。我的函数 ThisIsCalledByAnExternalProgram() 必须作为 STA 运行,但它没有。
我如何让这段代码作为 dll 工作?
编辑:当您在 STAThread 标记的方法中调用 ThisIsCalledByAnExternalProgram() 时会发生什么?
当我用我的外部程序调用该函数时,我得到一个异常: System.InvalidOperationException: ...调用线程必须是 STA,因为许多 UI 组件都需要这个。堆栈是:
System.Windows.Input.InputManager..ctor()
System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
ThisIsCalledByAnExternalProgram()
编辑#3:我误读了这个问题 - ...在标记的 STAThread 内...我目前无法尝试这个。假设它通过并工作 - 这仍然不能解决问题,因为我无法控制调用程序。
编辑#2:使用 Win32 钩子:由于可移植性,我想留在 .net 中。所有全局钩子变量最终都依赖于虚拟机下面的机器,我想使用准备好的c#键盘类。
它在不同的上下文中工作 - 这是一个简短的演示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
//Requires WindowsBase.dll
//Requires PresentationCore.dll
namespace KeyBoardDemo
{
class Program
{
[STAThread]
static void Main(string[] args)
{
while (true)
{
if (Keyboard.IsKeyDown(Key.LeftAlt))
{
Console.WriteLine("LEFT ALT IS PRESSED");
}
else
{
Console.WriteLine("LEFT ALT IS NOT PRESSED");
}
}
}
}
}