Код: Выделить всё
//Code
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Modify_Printer_Settings {
internal class Program {
//Class for OpenPrinter -> PRINTERDEFAULTS arugument
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal class PrinterDefault {
public IntPtr pDatatype;
public IntPtr 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;
}
//Win API Definitions
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, PrinterDefault pDefault);
[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.Ansi, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);
//Printer Access variables
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);
private static string printer = "Microsoft Print to PDF";
private static IntPtr PrinterHandle;
private static IntPtr pPrinterInfo;
private static IntPtr ptrDEVMODE;
private static PRINTER_INFO_2 sPrinter_Info = new PRINTER_INFO_2();
static void Main(string[] args) {
SetPrinterSettings();
}
private static void SetPrinterSettings() {
DEVMODE sDEVMODE;
sDEVMODE = GetPrinterSettings();
sDEVMODE.dmOrientation = 2; //Landscape
Marshal.StructureToPtr(sDEVMODE, ptrDEVMODE, true);
sPrinter_Info.pDevMode = ptrDEVMODE;
sPrinter_Info.pSecurityDescriptor = IntPtr.Zero;
Marshal.StructureToPtr(sPrinter_Info, pPrinterInfo, true);
int iRet = Convert.ToInt16(SetPrinter(PrinterHandle, 2, pPrinterInfo, 0));
if (iRet == 0) {
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
private static DEVMODE GetPrinterSettings() {
int iBytesNeeded, itmp;
DEVMODE sDEVMODE;
var pDefault = new PrinterDefault {
pDatatype = IntPtr.Zero,
pDevMode = IntPtr.Zero,
DesiredAccess = PRINTER_ACCESS_ADMINISTER
};
int iRet = Convert.ToInt32(OpenPrinter(printer, out PrinterHandle, pDefault));
if (iRet == 0) {
throw new Win32Exception(Marshal.GetLastWin32Error());
}
GetPrinter(PrinterHandle, 2, IntPtr.Zero, 0, out iBytesNeeded);
if (iBytesNeeded
Подробнее здесь: [url]https://stackoverflow.com/questions/79114725/c-sharp-access-denied-while-calling-getprinter-win-api[/url]