简体   繁体   English

我如何编写使用C#键盘类的dll函数

[英]How can i write a dll function that uses the C# Keyboard Class

I want to use the following code to access the state of the keyboard at a certain time. 我想使用以下代码在特定时间访问键盘的状态。

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;
         }
    }
}

This code requires some dlls to compile: WindowsBase.dll and PresentationCore.dll 此代码需要一些dll进行编译:WindowsBase.dll和PresentationCore.dll

Keyboard requires a STA Thread, normally i would write the [STAThread] attribute to the main function and it would work, but this code will be used as a dll, so i can not do that. 键盘需要STA线程,通常我会写的[STAThread]属性的主要功能和它的工作,但是这个代码将被用来作为一个dll,所以我不能做到这一点。 My function ThisIsCalledByAnExternalProgram() would have to run as an STA but it doesnt. 我的功能ThisIsCalledByAnExternalProgram()将不得不为STA运行,但它不。

How do i get this code to work as a dll? 我如何获得此代码以dll的形式工作?

EDIT: What happens when you call ThisIsCalledByAnExternalProgram() within a STAThread flagged method? 编辑:什么,当你调用发生ThisIsCalledByAnExternalProgram()一个STAThread内标记的方法?

When i call the function with my external program i get an exception: System.InvalidOperationException: ...The calling thread must be STA, because many UI components require this. 当我打电话的功能与我的外部程序我得到一个异常:System.InvalidOperationException:...调用线程必须为STA,因为许多UI组件都需要这个。 Stack is: 堆栈为:

System.Windows.Input.InputManager..ctor()
System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
ThisIsCalledByAnExternalProgram()

EDIT#3: I misread the question - ...within a STAThread flagged... i can currently not try this one. EDIT#3:我误解了问题-...在STAThread中标记为......我目前无法尝试此问题。 suppose it passes and works - this would still not solve the problem since i have no control over the calling program. 假设它可以通过并且可以工作-由于我无法控制调用程序,因此这仍然无法解决问题。

EDIT#2: Use a Win32 hook: I want to stay within .net because of portability. 编辑#2:使用Win32挂钩:由于可移植性,我想留在.net内。 All global hook variants are in the end dependent on the machine below the virtual machine, i want to use the prepared Keyboard class of c#. 最终,所有全局钩子变体都取决于虚拟机下方的计算机,我想使用准备好的c#键盘类。

It works in a different context - here is a short demo: 它在不同的上下文中工作-这是一个简短的演示:

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");
                }
            }
        }
    }
}

Consider using a hook, instead of using winform classes just for input. 考虑使用钩子,而不是仅将winform类用于输入。 This article is a great explanation of doing that with just C# with some pinvoking; 本文很好地解释了仅使用C#进行一些修改的情况。 it provides a input library (.dll) as well that may suit your needs. 它还提供了一个可能适合您需要的输入库(.dll)。 The article's scope is mainly global hooks but it also discusses using application specific hooks. 本文的范围主要是全局挂钩,但也讨论了使用特定于应用程序的挂钩。

http://www.codeproject.com/KB/cs/globalhook.aspx http://www.codeproject.com/KB/cs/globalhook.aspx

I found a solution to my Problem, but it feels like a Workaround. 我找到了解决问题的方法,但是感觉像是一种解决方法。

A) I have to get around the static property so i can create new Threads. A)我必须避开静态属性,以便创建新的线程。 B) I have to ensure STA before using Keayboard. 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.

相关问题 C#:如何将类传递给单独dll中的函数 - C#: How can I pass a class to a function in separate dll 如何将 function 传递给 C# class dll,这是我从另一个 C# 应用程序调用的? function 在调用 dll 的应用程序中定义 - How can I pass a function to a C# class dll, that I am calling from another C# app? The function is defined in the app where the dll is called 如何将这个不安全的 DLL 调用重构为在 C# 中使用 IntPtr 的调用 - How can I refactor this unsafe DLL call into one that uses IntPtr in C# 如何编写一个函数来返回从C#中的基类派生的任何对象? - How can I write a function that returns any object derived from a base class in C#? 如何在C#中编写SNMP代理或SNMP扩展代理DLL - How can I write an SNMP agent or SNMP extension agent DLL in C# 如何设计一个包装器 class 来使用 C++ 应用程序以使用 C# Z5884E40D796370BE39AZ109ADF? - How can I design a wrapper class for consuming a C++ application to use a C# DLL? 我可以将 c# class 重定向到另一个 dll 吗? - Can I redirect a c# class to another dll? 如何在 C++/CLI DLL 中从 C# 应用程序调用 function? - How can I call a function from C# app in a C++/CLI DLL? 如何调用接受来自 C# 的 stringstream 类型参数的 C++ DLL 函数? - How can I call a function of a C++ DLL that accepts a parameter of type stringstream from C#? 在Delphi中使用C#DLL仅使用第一个函数参数 - Using a C# DLL in Delphi only uses the first function parameter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM