[英]How can i write a dll function that uses the C# Keyboard Class
我想使用以下代碼在特定時間訪問鍵盤的狀態。
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的形式工作?
編輯:什么,當你調用發生ThisIsCalledByAnExternalProgram()一個STAThread內標記的方法?
當我打電話的功能與我的外部程序我得到一個異常:System.InvalidOperationException:...調用線程必須為STA,因為許多UI組件都需要這個。 堆棧為:
System.Windows.Input.InputManager..ctor()
System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
ThisIsCalledByAnExternalProgram()
EDIT#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");
}
}
}
}
}
考慮使用鈎子,而不是僅將winform類用於輸入。 本文很好地解釋了僅使用C#進行一些修改的情況。 它還提供了一個可能適合您需要的輸入庫(.dll)。 本文的范圍主要是全局掛鈎,但也討論了使用特定於應用程序的掛鈎。
我找到了解決問題的方法,但是感覺像是一種解決方法。
A)我必須避開靜態屬性,以便創建新的線程。 B)在使用Keayboard之前,我必須確保STA。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Input;
using System.Threading;
namespace some.any
{
public class ANY_CLASS
{
static STAKeyBoard mSTAKeyBoard = new STAKeyBoard();
public static short ThisIsCalledByAnExternalProgram()
{
try
{
if (mSTAKeyBoard.IsKeyDown(Key.LeftAlt))
{
return 1;
}
else
{
return 0;
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return 2;
}
}
class STAKeyBoard
{
private Thread mKeyBoardReadThread = null;
private Boolean mKeyState = false;
private Key mKeyOfInterest;
private string running = "ONLY ONE REQUEST";
public Boolean IsKeyDown(Key KeyOfInterest)
{
lock (running)
{
mKeyOfInterest = KeyOfInterest;
mKeyBoardReadThread = new Thread(new ThreadStart(GetKeyState));
mKeyBoardReadThread.SetApartmentState(ApartmentState.STA);
mKeyBoardReadThread.Start();
mKeyBoardReadThread.Join(1000);
mKeyBoardReadThread.Abort();
mKeyBoardReadThread = null;
return mKeyState;
}
}
private void GetKeyState()
{
mKeyState = Keyboard.IsKeyDown(mKeyOfInterest);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.