У меня есть только базовые знания C#, но мне нужно изменить настройки принтера, такие как ориентация/копии. Я написал код, как показано ниже, но выдает ошибку «Доступ запрещен». Я предоставил доступ «Управление этим принтером» вошедшему в систему пользователю, но все равно получаю эту ошибку. Пожалуйста, помогите решить проблему. Для этого примера я использую принтер Microsoft Print to PDF, так как драйвер принтера не установлен.
//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]
У меня есть только базовые знания C#, но мне нужно изменить настройки принтера, такие как ориентация/копии. Я написал код, как показано ниже, но выдает ошибку «Доступ запрещен». Я предоставил доступ «Управление этим принтером» вошедшему в систему пользователю, но все равно получаю эту ошибку. Пожалуйста, помогите решить проблему. Для этого примера я использую принтер Microsoft Print to PDF, так как драйвер принтера не установлен.
[code]//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; }
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