Pregunta

Estoy tratando de código para un sistema de punto de venta que permite una fijación "de caja registradora". Código se proporciona en el manual para abrir el cajón de dinero (en C ++ usando IOCTL). Desde que estoy de codificación en C # .NET, es posible llevar a cabo algo similar desde el interior de C # o voy a tener que escribir código no administrado?

¿Soy capaz de obtener un identificador para "\\. \ ADVANSYS" desde dentro de C #? ¿Es necesario utilizar DLLImport?

agradecería que alguien me podría apuntar en la dirección correcta.

// IOCTL Codes
#define GPD_TYPE 56053
#define ADV_OPEN_CTL_CODE CTL_CODE(GPD_TYPE, 0x920, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define ADV_STATUS_CTL_CODE CTL_CODE(GPD_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
void OpenDrawer(UCHAR uWhichDrawer) // uWhichDrawer = 1 => CD#1, uWhichDrawer = 2 => CD#2
{
    HANDLE hFile;
    BOOL bRet
    UCHAR uDrawer = uWhichDrawer;

    // Open the driver
    hFile = CreateFile(TEXT("\\\\.\\ADVSYS"),
    GENERIC_WRITE | GENERIC_READ,
    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if (m_hFile == INVALID_HANDLE_VALUE)
    {
        AfxMessageBox("Unable to open Cash Drawer Device Driver!");
        return;
    }

    // Turn on the Cash Drawer Output (Fire the required solenoid)
    bRet = DeviceIoControl(hFile, ADV_CD_OPEN_CTL_CODE,
    &uDrawer, sizeof(uDrawer),
    NULL, 0,
    &ulBytesReturned, NULL);

    if (bRet == FALSE || ulBytesReturned != 1)
    {
        AfxMessageBox("Failed to write to cash drawer driver");
        CloseHandle(hFile);
        return;
    }
    CloseHandle(hFile);
}
¿Fue útil?

Solución

El C ++ está plagado de errores, no está seguro de si lo hizo bien. Lo mejor que puede hacer es declarar Dispositivo () con los tipos de argumentos alterados por lo que es fácil de llamada. También hay que P / Invoke CreateFile PORQUE FileStream no puede dispositivos abiertos. Debería ser similar a esto:

using System;
using System.IO;
using System.ComponentModel;
using System.Runtime.InteropServices;

class Program {
    static void Main(string[] args) {
        IntPtr hdl = CreateFile("\\\\.\\ADVSYS", FileAccess.ReadWrite,
            FileShare.None, IntPtr.Zero, FileMode.Open,
            FileOptions.None, IntPtr.Zero);
        if (hdl == (IntPtr)(-1)) throw new Win32Exception();
        try {
            byte drawer = 1;
            bool ok = DeviceIoControl(hdl, CTLCODE, ref drawer, 1, IntPtr.Zero,
                0, IntPtr.Zero, IntPtr.Zero);
            if (!ok) throw new Win32Exception();
        }
        finally {
            CloseHandle(hdl);
        }
    }
    // P/Invoke:
    private const uint CTLCODE = 0xdaf52480;
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CreateFile(string filename, FileAccess access,
          FileShare sharing, IntPtr SecurityAttributes, FileMode mode,
          FileOptions options, IntPtr template
    );
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool DeviceIoControl(IntPtr device, uint ctlcode,
        ref byte inbuffer, int inbuffersize,
        IntPtr outbuffer, int outbufferSize,
        IntPtr bytesreturned, IntPtr overlapped
    );
    [DllImport("kernel32.dll")]
    private static extern void CloseHandle(IntPtr hdl);
}

Otros consejos

Se puede usar Pinvoke ;

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
internal static extern bool DeviceIoControl([In] SafeFileHandle hDevice, [In] int dwIoControlCode, [In] IntPtr lpInBuffer, [In] int nInBufferSize, [Out] IntPtr lpOutBuffer, [In] int nOutBufferSize, out int lpBytesReturned, [In] IntPtr lpOverlapped);

Este ejemplo posible que también ayuda.

Hay un montón de código listo para esto en pinvoke.net con un montón de ejemplos también.

http://www.pinvoke.net/default.aspx/kernel32.DeviceIoControl

escribió:

Parecía que el GPD_TYPE 56053 como se especifica en la documentación que se Había no era correcta

Se puede publicar el valor apropiado de GPD_TYPE

Las mejores regadrs!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top