Member 14150748 Ответов: 1

Как прослушивать сообщения устройства, подключенные через USB с помощью приложения C#?


Приветствую вас! это опять я!

Этот вопрос довольно сложен, потому что я сделаю все возможное, чтобы объяснить его: как я уже упоминал в предыдущем вопросе, я работаю в управлении сканером на C#, используя DLL C++, отправленную поставщиком. Согласно руководству API, существуют определенные сообщения, отправляемые при определенных условиях. Например: после запуска сканера он должен отправить сообщение DEVICE_CONNECTED (со значением 0), а затем изменить его состояние.

Эти значения сообщений определены в файле .dll

Мой вопрос заключается в следующем: как я могу поймать эти сообщения с помощью моего проекта C#?

Что я уже пробовал:

Я искал информацию о передаче сообщений и обнаружил, что существует WndProc, который обрабатывает сообщения Windows. Тогда я попробовал сделать это:

private const int DEVICE_CONNECTED = 0;
/*<<<<< Some code >>>>>*/     [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
    if (m.Msg == DEVICE_CONNECTED)
       listBox1.Items.Add("Connected");
    base.WndProc(ref m);
}


Конечно, это не удается. Полагаю, мне нужно как-то определить источник сообщений. Читая дальше, есть еще одна вещь, называемая WMI, но после проверки информации в MicrosoftDocs... Я чувствую, что они говорят по-китайски или что-то в этом роде...

Итак, есть ли хорошие guindance? Предложения?

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


///////////////////////////////////

Отредактированный:

Итак, после долгих поисков я выяснил, где я могу получить это сообщение.

Ранее я импортировал другую функцию из этой библиотеки dll:

[DllImport(path, EntryPoint = "?StartUp@@YGKPAUHWND__@@I@Z")]
public static extern int StartUp(IntPtr HWMD, uint StMsg);


Это позволяет мне включить сканер.

внутри дома .dll определяется следующим образом:

DWORD StartUp( HWND Handle, UINT SorterMessage )


А в руководстве написано: "HWND Handle – дескриптор окна назначения сообщений приложения."

Итак, если я неправильно понял correrctly (английский не является моим основным языком) Я получил указатель, откуда я должен получить эти сообщения.

Теперь возникает другой вопрос: как я могу использовать этот указатель?

Попробовал следовать этому примеру, который я нашел на другом форуме:

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct MSG
{
    public IntPtr hwnd;
    public int message;
    public IntPtr wParam;
    public IntPtr lParam;
    public int time;
    public int pt_x;
    public int pt_y;
};

[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern bool GetMessage([In, Out] ref MSG msg, IntPtr hWnd, int uMsgFilterMin, int uMsgFilterMax);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr DispatchMessage([In] ref MSG msg);

MSG msg = new MSG();
while (GetMessage(ref msg, IntPtr.Zero, 0, 0))
    DispatchMessage(ref msg);


Попробовал подражать ему Вот так:

// Added a constructor inside of the struct:
public MSG(IntPtr hwndPtr)
{
    hwnd = hwndPtr;
    message = -1;
    wParam = new IntPtr();
    lParam = new IntPtr();
    time = 0;
    pt_x = 0;
    pt_y = 0;
}

// Left the dll imports like in their example (although I fixed the path)

// Calling the method in my main
int ID, st;
ID = Class1.StartUp(hwnd, 10); // Just used 10 like in the API's manual
Console.WriteLine("Turning on device");
MSG msg = new MSG(hwnd);
while(Class1.GetMessage(ref msg, IntPtr.Zero, 0, 0))
    Class1.DispatchMessage(ref msg);
Console.WriteLine(msg.message);

do { Class1.GetState(ID, out st); }
while (st != (int) DevStates.chgParams);
Console.WriteLine("Device on");


Но теперь я получаю пустой ответ. После печати "включение устройства" курсор просто мигает, и программа не продвигается вперед. Он как будто чего-то ждет.

Что я упускаю?

Gerry Schmitz

Было бы полезно, если бы вы сказали, какую "марку" / модель сканера вы используете.

"Моя машина не заводится". Это газ, электричество, пропан или Флинстоуны ...

Member 14150748

Я отправлю его, но потом удалю эту реплику позже или завтра, для уверенности

Это видение Панини X.

Gerry Schmitz

Поставщик предоставляет ПК "приложение" для взаимодействия с устройством; в чем смысл вашего кода? Проверка сканирования-это не то, что требует "настройки".

Member 14150748

Дело в том, что клиент требует определенных функций. Кроме того, поставщик просто предоставляет демонстрационное программное обеспечение для тестирования сканера. Если нет необходимости в программировании они не будут отправлять dll

1 Ответов

Рейтинг:
6

Member 14150748

Решил ее (наконец-то)

Вот как я это сделал:


1) используется windows forms, так как она имеет класс "Message"
2) импортировал .dll, над которой я работал, чтобы сделать вещи проще, поместила все методы в класс "ScanMgr".

using ...
using APIcsharp;

class ScanMgr
{
  int ID = 0;

  public string startUp(IntPtr hwmd, uint wmApp)
  {
    int state;
    ID = NativeAPI.StartUp(hwmd, wmApp);
    if(ID != 0)
    {
      do { NativeAPI.GetState(ID, out state); }
      while(state == (int)(DevStates.StartingUp)); // DevStates is a enum, ok? :P
      return "Device on";
    }
    return "Error turning on";
  }

  /* Other stuff to do */
}


3) затем определяется метод переопределения для сообщений

public partial class Form1 : Form
{
  const uint wm_channel = 0x8000 + 1;
  ScanMgr scanner = new ScanMgr();

  public Form1()
  { InitializeComponent(); }

  private void StartBtn_Click(object sender, EventArgs e)
  { log.Items.Add(scanner.startUp(this.Handle, wm_channel)); }

  /* Other stuff yadda yadda */

  protected override void WndProc(ref Message m)
  {
    base.WndProc(ref m);
    if(m.Msg == wm_channel)
    { /* To do stuff with m.WParam and m.LParam */ }
  }
}


Nirav Prabtani

Поздравление,

Отметьте это как решенное для решения credibilit, это поможет и другим тоже

Maciej Los

5ed!