次のコードを使用して、特定の時間のキーボードの状態にアクセスしたいと考えています。
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: ...多くの UI コンポーネントがこれを必要とするため、呼び出しスレッドは STA でなければなりません。スタックは次のとおりです。
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");
}
}
}
}
}