2013-04-15 3 views
0

Я пытаюсь записать устройство USB HID.Невозможно записать на USB-устройство HID

Мой код, используемый для работы на 32-битной XP, но для худых я пытаюсь на 64-битных ОС Windows 7. Я могу найти устройство, получить его путь, используйте CreateFile функцию win32 API, чтобы открыть дескриптор & передать это FileStream. Пока все кажется прекрасным. Затем я записываю данные в поток &, но устройство USB ничего не делает.

Как я могу узнать, почему это ничего не делает &, а затем надеемся сделать что-нибудь?

Это мой импорт подписи:

[DllImport("kernel32.dll", SetLastError = true)] 
    public static extern SafeFileHandle CreateFile(
     [MarshalAs(UnmanagedType.LPStr)] string name, 
     uint access, 
     int shareMode, 
     IntPtr security, 
     int creationFlags, 
     int attributes, 
     IntPtr template); 

Вызов функции:

var handle = usb.Win32Wrapper.CreateFile(path, usb.Win32Wrapper.GENERIC_READ | usb.Win32Wrapper.GENERIC_WRITE, 0, IntPtr.Zero, usb.Win32Wrapper.OPEN_EXISTING, usb.Win32Wrapper.FILE_FLAG_OVERLAPPED, IntPtr.Zero); 

Открытие FileStream к устройству:

_main = new FileStream(handle, FileAccess.Write, 1, true); 

и, наконец, запись в файл:

_main.Write(buffer,0,buffer.Length); 
+0

Try глядя на [эту тему] (http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/44ca52eb-a51e-4614-aeb9-fb072d4dab82/) – Icemanind

+0

Интересно. Я не получаю сообщение об ошибке, когда я вызываю CreateFile, и устройство HID не отображается как диск, но я отдам ему все, что вы никогда не знаете. –

+0

К сожалению, это не имело значения. Я также попытался удалить перекрытый флаг ввода-вывода. Это не имело значения. –

ответ

1

Трудно сказать, не зная специфики вашего устройства.

Вы подтвердили, что можете связаться с устройством (hidapi, HIDSharp и т. Д.)? Ничего не говорится о том, что USB HID-устройство не может отвечать NAKs до конца времени, и в этом случае ваша отправка никогда не завершится.

вопросы я столкнулся, когда я первый пытается общаться через HID (я использую Windows 7 на некоторое время, так что я не могу сказать, если XP имеет те же ограничения):

(1) Убедитесь, что вы включили байт идентификатора отчета. Даже если ваше устройство не поддерживает одно, Windows нуждается в идентификаторе отчета 0.

(2) В Windows ваш буфер должен быть такой же длины, как и максимальный отчет. Например, если ваш отчет равен 48 байтам, вам нужно записать 49 байтов (всегда начинать с идентификатора отчета). Кажется, я помню, что я написал ошибку при записи, если не сделал этого.

Поскольку вы упоминаете 64-разрядная ОС Windows ...

(3) Один 64-битный Windows, конкретных вопрос, который я столкнулся в том, что (как в .NET 2.0 и 4.0) 64-бит P/Invoke не обрабатывает структуру OVERLAPPED (или NativeOverlapped, если на то пошло), как blittable. Поэтому, если вы используете 'ref OVERLAPPED', он сделает копию, P/Invoke и скопируйте обратно. Операции с перекрытием предполагают, что память не перемещается, так что это реальная проблема. GetOverlappedResult будет ошибочным, вы получите тонкое повреждение памяти и т. Д. Вы можете решить эту проблему с помощью fixed() или stackalloc - это один напоминание ref T не идентично T *, даже если структура выделена в стеке.

Надеюсь, хотя бы один из этих трех решает вашу проблему.:)

Джеймс

+0

Полезно. Код работал на 32-битной XP. HID-устройство на самом деле является составным, поэтому вы получаете дескриптор обоих интерфейсов, вычисляете размер отчетов и отправляете соответствующее сообщение каждому интерфейсу. –

+0

Эй, интересно, может ли быть проблема с размером буфера 1 байта? Если FileStream вызывает WriteFile в блоках меньше размера отчета, Windows не понравится. – Zer

+0

"Report ID = 0" очень важно. Скажем, вы определяете размер отчета равным 64, ваш фактический массив должен быть 'hid_out [65]' и 'hid_out [0] = 0' –

-1

------------------------------- ------ ШТРИХ ПРИНТ ---------

private int PrintBarcode(string barcode, string printFormat, int printCount) 
    { 
     string text = "B400,50,1,1,2,1,150,B,"; 
     if (printFormat != null) 
     { 
      text = printFormat; 
     } 
     string barcod = string.Concat(new object[] 
     { 
      text, 
      Convert.ToChar(34), 
      barcode, 
      Convert.ToChar(34), 
      "\n" 
     }); 

     string printerName= ConfigurationManager.AppSettings["PrinterName"]; 

     int x = 100; 
     int y = 0; 
     using (EtiquetaTestCommand1 etiquetaTestCommand = new EtiquetaTestCommand1(new Size(500, 750), 19, new Point(x, y), printCount, barcod)) 
     { 
      string commandString = ((ICommand)etiquetaTestCommand).GetCommandString(); 


      //var sb1 = new StringBuilder(); 
      // sb1.AppendLine(); 
      // sb1.AppendLine("N"); 
      // sb1.AppendLine("Q750,19"); 
      // sb1.AppendLine("q500"); 
      // sb1.AppendLine("R100,0"); 
      // sb1.AppendLine(barcod); 
      // sb1.AppendLine("P1"); 

      RawPrinterHelper.SendStringToPrinter(printerName, commandString.ToString()); 


     } 

---------------------------------- EtiquetaTestCommand1 --------------------------

internal sealed class EtiquetaTestCommand1 : Label, IDisposable 
{ 
    private Bitmap _bmp; 

    internal EtiquetaTestCommand1(Size size, int gapLength, Point referencePoint, int numberCopies, string barcod) : base(size, gapLength, referencePoint, numberCopies, barcod) 
    { 
     int x = 5; 
     int y = 5; 
     ((IComplexCommand)this).AddCommand(BarCodeCommand.Code128ModeABarCodeCommand(x, y, barcod)); 
    } 

    ~EtiquetaTestCommand1() 
    { 
     this.Dispose(false); 
    } 

    private void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
     } 
    } 

    void IDisposable.Dispose() 
    { 
     this.Dispose(true); 
    } 
} 

---------------- ------ PrinterName ---------------

<add key="PrinterName" value="ZDesigner LP 2844"/> 

----------------- SendStringToPrinter ----------------------

public class RawPrinterHelper 
    { 
     // Structure and API declarions: 
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
     public class DOCINFOA 
     { 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pDocName; 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pOutputFile; 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pDataType; 
     } 
     [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); 

     [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool ClosePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); 

     [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool EndDocPrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool StartPagePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool EndPagePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); 

     // SendBytesToPrinter() 
     // When the function is given a printer name and an unmanaged array 
     // of bytes, the function sends those bytes to the print queue. 
     // Returns true on success, false on failure. 
     public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) 
     { 
      Int32 dwError = 0, dwWritten = 0; 
      IntPtr hPrinter = new IntPtr(0); 
      DOCINFOA di = new DOCINFOA(); 
      bool bSuccess = false; // Assume failure unless you specifically succeed. 

      di.pDocName = "My C#.NET RAW Document"; 
      di.pDataType = "RAW"; 

      // Open the printer. 
      if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) 
      { 
       // Start a document. 
       if (StartDocPrinter(hPrinter, 1, di)) 
       { 
        // Start a page. 
        if (StartPagePrinter(hPrinter)) 
        { 
         // Write your bytes. 
         bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); 
         EndPagePrinter(hPrinter); 
        } 
        EndDocPrinter(hPrinter); 
       } 
       ClosePrinter(hPrinter); 
      } 
      // If you did not succeed, GetLastError may give more information 
      // about why not. 
      if (bSuccess == false) 
      { 
       dwError = Marshal.GetLastWin32Error(); 
      } 
      return bSuccess; 
     } 

     public static bool SendFileToPrinter(string szPrinterName, string szFileName) 
     { 
      // Open the file. 
      FileStream fs = new FileStream(szFileName, FileMode.Open); 
      // Create a BinaryReader on the file. 
      BinaryReader br = new BinaryReader(fs); 
      // Dim an array of bytes big enough to hold the file's contents. 
      Byte[] bytes = new Byte[fs.Length]; 
      bool bSuccess = false; 
      // Your unmanaged pointer. 
      IntPtr pUnmanagedBytes = new IntPtr(0); 
      int nLength; 

      nLength = Convert.ToInt32(fs.Length); 
      // Read the contents of the file into the array. 
      bytes = br.ReadBytes(nLength); 
      // Allocate some unmanaged memory for those bytes. 
      pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); 
      // Copy the managed byte array into the unmanaged array. 
      Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); 
      // Send the unmanaged bytes to the printer. 
      bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength); 
      // Free the unmanaged memory that you allocated earlier. 
      Marshal.FreeCoTaskMem(pUnmanagedBytes); 
      return bSuccess; 
     } 
     public static bool SendStringToPrinter(string szPrinterName, string szString) 
     { 
      IntPtr pBytes; 
      Int32 dwCount; 
      // How many characters are in the string? 
      dwCount = (szString.Length + 1) * Marshal.SystemMaxDBCSCharSize; 
      // Assume that the printer is expecting ANSI text, and then convert 
      // the string to ANSI text. 
      pBytes = Marshal.StringToCoTaskMemAnsi(szString); 
      // Send the converted ANSI string to the printer. 
      SendBytesToPrinter(szPrinterName, pBytes, dwCount); 
      Marshal.FreeCoTaskMem(pBytes); 
      return true; 
     } 
    } 
+0

Не могли бы вы добавить некоторые комментарии, которые пропустил опрос и почему ваше решение работает !? Благодарю. –

Смежные вопросы