INPUT недоступен из-за его уровня защиты

Я пытаюсь создать небольшое приложение, которое будет отправлять входные данные в игру. После некоторого поиска я нашел много ответов, которые предлагают использовать SendInput.

Ниже приведен код, над которым я работаю (в основном делаю много тестов, чтобы увидеть, что работает, отсюда и беспорядок). Я бы посоветовал вам игнорировать большую часть кода, строка, которая меня интересует, или я должен сказать, что вызывает проблемы со сборкой:

public static extern uint SendInput(
    uint nInputs,[MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);

Это дает мне ошибку:

«ВХОД» недоступен из-за его уровня защиты.

Я новичок в C# (и программировании для Windows), поэтому не могу понять, что мне делать, чтобы это исправить.

Любая помощь будет оценена по достоинству.

Заранее спасибо.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using WindowsInput;

namespace WindowsFormsApplication1
{
    [Flags]
    public enum KeyFlag
    {
        KeyDown = 0x0000,
        KeyUp = 0x0002,
        Scancode = 0x0008
    }


    internal static class VirtualKeyboard
    {

        public static void KeyDown(System.Windows.Forms.Keys key)
        {

            Console.WriteLine("Sending keybdevent: " + (byte)key);
            //keybd_event((byte)key, 0, 0, 0);
            /*INPUT[] InputData = new INPUT[2];
            Key ScanCode = Microsoft.DirectX.DirectInput.Key.W;

            InputData[0].type = 1; //INPUT_KEYBOARD
            InputData[0].wScan = (ushort)ScanCode;
            InputData[0].dwFlags = (uint)SendInputFlags.KEYEVENTF_SCANCODE;

            InputData[1].type = 1; //INPUT_KEYBOARD
            InputData[1].wScan = (ushort)ScanCode;
            InputData[1].dwFlags = (uint)(SendInputFlags.KEYEVENTF_KEYUP | SendInputFlags.KEYEVENTF_UNICODE);

            // send keydown
            if (SendInput(2, InputData, Marshal.SizeOf(InputData[1])) == 0)
            {
                System.Diagnostics.Debug.WriteLine("SendInput failed with code: " +
                Marshal.GetLastWin32Error().ToString());
            }*/
            //InputSimulator.SimulateKeyDown(VirtualKeyCode.VK_E);

            Console.WriteLine("Exit.....");
        }
        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
        public static void SendKey(short keyCode, KeyFlag keyFlag)
        {
            INPUT[] InputData = new INPUT[1];

            InputData[0].type = 1;
            InputData[0].ki.wScan = keyCode; // 0x14 = T for example
            InputData[0].ki.dwFlags = (int)keyFlag;
            InputData[0].ki.time = 0;
            InputData[0].ki.dwExtraInfo = IntPtr.Zero;

            SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT)));
        }

        public static void PressKey(short key)
        {
            SendKey(key, KeyFlag.KeyDown | KeyFlag.Scancode);
            SendKey(key, KeyFlag.KeyUp | KeyFlag.Scancode);
        }

        public static void KeyUp(System.Windows.Forms.Keys key)
        {
            //keybd_event((byte)key, 0, 0x7F, 0);
        }
    }
}

person eemerge    schedule 09.06.2015    source источник
comment
Где вы определили структуру INPUT?   -  person Ron Beyer    schedule 09.06.2015
comment
Я не. Я думал, что это связано с импортом dll.   -  person eemerge    schedule 09.06.2015
comment
Нет, так что это запутанная ошибка, вам нужно определить структуру INPUT.   -  person Ron Beyer    schedule 09.06.2015
comment
Вам нужно определить INPUT. См. этот ответ: stackoverflow.com/questions/6830651/sendinput-and-64bits   -  person Maxime Peloquin    schedule 09.06.2015


Ответы (2)


Структура INPUT должна иметь более высокий уровень доступа, например public, чтобы другие классы могли получить к ней доступ. См. модификаторы доступа.

public struct INPUT 
{  
   ...
}
person Cyral    schedule 09.06.2015
comment
внутренний или защищенный внутренний также будут работать, если INPUT находится в той же сборке, нет? - person David L; 09.06.2015
comment
internal будет работать, protected internal будет работать только для производных классов. (Это зависит от того, где определен INPUT, я предполагаю, основываясь на других вопросах, что это структура) - person Cyral; 09.06.2015
comment
Я попытаюсь просмотреть примеры, возможно, я пропустил момент, когда они определяют структуру. @DavidL: я тоже пробовал внутренне, та же проблема. Но это должно быть потому, что я не определил структуру... - person eemerge; 09.06.2015
comment
protected internal работает только для производных классов, если класс существует в другой сборке. Кажется вероятным, что структура существует в той же сборке, что и элемент управления формы, что делает ее правильным выбором. Но поскольку вы обновили свой язык ответов до такого, я бы сказал, что теперь он соответствует требованиям :). - person David L; 09.06.2015
comment
@eemerge Похоже, этот вопрос может иметь такие определения. - person Cyral; 09.06.2015
comment
@DavidL TIL, что protected internal означает производные классы ИЛИ кого-либо из сборки. Думал, что в одной сборке разрешены только производные классы. - person Cyral; 09.06.2015
comment
@Cyral Нет, умное маленькое предложение ИЛИ. Это сбило меня с толку однажды. - person David L; 09.06.2015
comment
@Cyral, спасибо за ссылку, я думаю, это должно помочь! - person eemerge; 09.06.2015

В C# вы должны явно пометить struct членов как public. В С++ они автоматически public. Поэтому вы должны пометить INPUT как public.

person Salah Akbari    schedule 09.06.2015