Grałem z projektem z codeproject, który zasadniczo monitoruje aktywność drukowania na komputerze. Jednak nie działa poprawnie w konfiguracji 64-bitowej. Poniższa część kodu była problemem. Ten kod jest wywoływany po każdym wydrukowaniu.Jak poprawnie zdefiniować PRINT_NOTIFY_INFO_DATA?
Debugowanie pokazuje, że wartość [i] pola jest zawsze równa 0. W 32-bitowym jednak działa poprawnie. Myślę, że PRINTER_NOTIFY_INFO_DATA nie jest poprawnie zdefiniowany. Obecnie używam następującego kodu. Czy ktokolwiek może to naprawić, aby działał poprawnie również w wersji 64-bitowej?
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO
{
public uint Version;
public uint Flags;
public uint Count;
}
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO_DATA_DATA
{
public uint cbBuf;
public IntPtr pBuf;
}
[StructLayout(LayoutKind.Explicit)]
public struct PRINTER_NOTIFY_INFO_DATA_UNION
{
[FieldOffset(0)]
private uint adwData0;
[FieldOffset(4)]
private uint adwData1;
[FieldOffset(0)]
public PRINTER_NOTIFY_INFO_DATA_DATA Data;
public uint[] adwData
{
get
{
return new uint[] { this.adwData0, this.adwData1 };
}
}
}
// Structure borrowed from http://lifeandtimesofadeveloper.blogspot.com/2007/10/unmanaged-structures-padding-and-c-part_18.html.
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO_DATA
{
public ushort Type;
public ushort Field;
public uint Reserved;
public uint Id;
public PRINTER_NOTIFY_INFO_DATA_UNION NotifyData;
}
Testowałem wydruk przy użyciu sterownika MS XPS. Artykuł projektu Code to Here
Uratowałeś mi życie, thanx milion. –
Dodatkowo upewnij się, że odpowiednie projekty są skonfigurowane do budowania plików wykonywalnych x86 !!! –
Kilka rzeczy do zapamiętania na ten temat. 1) Marshal.OffsetOf() zwraca obiekt IntPtr, który według mojej wiedzy nie może być bezpośrednio rzutowany na długi. Musisz użyć metody IntPtr.ToInt32(). 2) Ten kod może potencjalnie spowodować awarię twojego kodu, jeśli PRINTER_NOTIFY_INFO.Count wynosi 0. Oznacza to, że nie ma żadnych struktur na liście aData []. Deklarując to w opisany sposób, gwarantujesz co najmniej 1 obiekt w tablicy. Jeśli count ma wartość 0, oznacza to potencjalne uszkodzenie segmentacji. Zadeklarowałbym aData jako IntPtr zamiast tego, ponieważ tak naprawdę w niezarządzanym kodzie jest to po prostu wskaźnik. – Ultratrunks