gpt4 book ai didi

c# - VSTO 打印机 API

转载 作者:行者123 更新时间:2023-11-30 18:15:13 29 4
gpt4 key购买 nike

尝试使用以下代码示例,它在 WinForm 应用程序中运行良好,但在 VSTO 中运行不佳。是否有某种允许访问的权限?

可以设置默认打印机,但不能获取或设置打印机设置。

从插件中获取以下异常:

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.' http://www.pinvoke.net/default.aspx/winspool.SetDefaultPrinter

http://www.pinvoke.net/default.aspx/winspool/OpenPrinter.html

visual studio 项目模板是 {Word/Outlook} 2013 和 2016 VSTO 加载项

string name = @"\\{printer server name}\{printer name}";
PRNsettings p = new PRNsettings();

var v = p.ChangePrinterSetting(name, new PrinterData { colour = 1, copies = 1, duplex = 1, source = 7 });

public class PrinterData
{
public PrinterData()
{
copies = -1;
colour = -1;
duplex = -1;
source = -1;
}

public int copies { get; set; }
public int colour { get; set; }
public int duplex { get; set; }
public int source { get; set; }
}

public class PRNsettings
{
private IntPtr hPrinter = new System.IntPtr();
private PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();
private PRINTER_INFO_2 pinfo = new PRINTER_INFO_2();
private DEVMODE dm;
private IntPtr ptrDM;
private IntPtr ptrPrinterInfo;
private int sizeOfDevMode = 0;
private int lastError;
private int nBytesNeeded;
private long nRet;
private int intError;
private System.Int32 nJunk;
private IntPtr yDevModeData;

[DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern Int32 GetLastError();

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

[DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,

[MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg, IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);
[DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel, IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded);

[DllImport("winspool.drv", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, PRINTER_DEFAULTS pDefault);

[DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);

[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);

[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_DEFAULTS
{
public int pDatatype;
public int pDevMode;
public int DesiredAccess;
}

[StructLayout(LayoutKind.Sequential)]
private struct PRINTER_INFO_2
{
[MarshalAs(UnmanagedType.LPStr)] public string pServerName;
[MarshalAs(UnmanagedType.LPStr)] public string pPrinterName;
[MarshalAs(UnmanagedType.LPStr)] public string pShareName;
[MarshalAs(UnmanagedType.LPStr)] public string pPortName;
[MarshalAs(UnmanagedType.LPStr)] public string pDriverName;
[MarshalAs(UnmanagedType.LPStr)] public string pComment;
[MarshalAs(UnmanagedType.LPStr)] public string pLocation;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.LPStr)] public string pSepFile;
[MarshalAs(UnmanagedType.LPStr)] public string pPrintProcessor;
[MarshalAs(UnmanagedType.LPStr)] public string pDatatype;
[MarshalAs(UnmanagedType.LPStr)] public string pParameters;
public IntPtr pSecurityDescriptor;
public Int32 Attributes;
public Int32 Priority;
public Int32 DefaultPriority;
public Int32 StartTime;
public Int32 UntilTime;
public Int32 Status;
public Int32 cJobs;
public Int32 AveragePPM;
}

private const short CCDEVICENAME = 32;
private const short CCFORMNAME = 32;

[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)]
public string dmFormName;
public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public uint dmMediaType;
}

private const int DM_DUPLEX = 0x1000;
private const int DM_IN_BUFFER = 8;
private const int DM_OUT_BUFFER = 2;
private const int PRINTER_ACCESS_ADMINISTER = 0x4;
private const int PRINTER_ACCESS_USE = 0x8;
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);

public int returnSource;
public int returnDuplex;
public int returnColor;
public int returnCopies;

public bool SetDefault(string name)
{
try
{
return SetDefaultPrinter(name);
}
catch (Exception) { return false; }
}

public bool ChangePrinterSetting(string PrinterName, PrinterData PS)
{
try
{
dm = this.GetPrinterSettings(PrinterName);

// Sent back to allow reset of the settings back to original.
returnSource = dm.dmDefaultSource;
returnDuplex = dm.dmDuplex;
returnColor = dm.dmColor;
returnCopies = dm.dmCopies;

if (PS.source > -1)
dm.dmDefaultSource = (short)PS.source;

if (PS.duplex > -1)
dm.dmDuplex = (short)PS.duplex;

if (PS.colour > -1)
dm.dmColor = (short)PS.colour;

if (PS.copies > -1)
dm.dmCopies = (short)PS.copies;

Marshal.StructureToPtr(dm, yDevModeData, true);
pinfo.pDevMode = yDevModeData;
pinfo.pSecurityDescriptor = IntPtr.Zero;

Marshal.StructureToPtr(pinfo, ptrPrinterInfo, false);
lastError = Marshal.GetLastWin32Error();
nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));

// Error
if (nRet == 0)
return false;

if (hPrinter != IntPtr.Zero)
ClosePrinter(hPrinter);

return Convert.ToBoolean(nRet);
}
catch (Exception) { return false; }
}

public DEVMODE GetPrinterSettings(string PrinterName)
{
PrinterData PData = new PrinterData();
DEVMODE dm;

const int PRINTER_ACCESS_ADMINISTER = 0x4;
const int PRINTER_ACCESS_USE = 0x8;
const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);

PrinterValues.pDatatype = 0;
PrinterValues.pDevMode = 0;
PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
nRet = Convert.ToInt32(OpenPrinter(PrinterName,
out hPrinter, PrinterValues));

GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out nBytesNeeded);

Marshal.AllocCoTaskMem(nBytesNeeded);
ptrPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded);
nRet = Convert.ToInt32(GetPrinter(hPrinter, 2, ptrPrinterInfo, nBytesNeeded, out nJunk));
pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure(ptrPrinterInfo, typeof(PRINTER_INFO_2));

IntPtr Temp = new IntPtr();

if (pinfo.pDevMode == IntPtr.Zero)
{
IntPtr ptrZero = IntPtr.Zero;
sizeOfDevMode = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrZero, ref ptrZero, 0);
ptrDM = Marshal.AllocCoTaskMem(sizeOfDevMode);

int i = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrDM, ref ptrZero, DM_OUT_BUFFER);
pinfo.pDevMode = ptrDM;
}

intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero, ref Temp, 0);

yDevModeData = Marshal.AllocHGlobal(intError);
intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, yDevModeData, ref Temp, 2);
dm = (DEVMODE)Marshal.PtrToStructure(yDevModeData, typeof(DEVMODE));

return dm;
}
}

最佳答案

如果您在为 AnyCPU 或 x64 构建时遇到此错误,您可能会发现我在这里的回答很有帮助: WinSpool OpenPrinter Access Denied - building for AnyCPU\x64

关于c# - VSTO 打印机 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48768005/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com