我有一个应用程序,我需要打印一个Excel文件到一个特定的打印机,而不是默认的打印机。
VB。我在网上找到了一个函数,可以让我这样做。
xlApp.ActivePrinter = FindPrinter("PrinterName")
, FindPrinter函数的代码为
Function FindPrinter(ByVal PrinterName As String) As String
Dim Arr As Object
Dim Device As Object
Dim Devices As Object
Dim Printer As String
Dim RegObj As Object
Dim RegValue As String
Const HKEY_CURRENT_USER = &H80000001
RegObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\.rootdefault:StdRegProv")
RegObj.EnumValues(HKEY_CURRENT_USER, "SoftwareMicrosoftWindows NTCurrentVersionDevices", Devices, Arr)
For Each Device In Devices
RegObj.getstringvalue(HKEY_CURRENT_USER, "SoftwareMicrosoftWindows NTCurrentVersionDevices", Device, RegValue)
Printer = Device & " on " & Split(RegValue, ",")(1)
If InStr(1, Printer, PrinterName, vbTextCompare) > 0 Then
FindPrinter = Printer
Exit Function
End If
Next
End Function
在c#中,我有这样的代码
public string FindPrinter(string PrinterName)
{
string FindPrinterRet = default;
var Arr = default(object);
var Devices = default(object);
string Printer;
object RegObj;
var RegValue = default(string);
const int HKEY_CURRENT_USER = int.MinValue + 0x00000001;
RegObj = Microsoft.VisualBasic.Interaction.GetObject(@"winmgmts:{impersonationLevel=impersonate}!\.rootdefault:StdRegProv");
RegObj.EnumValues(HKEY_CURRENT_USER, @"SoftwareMicrosoftWindows NTCurrentVersionDevices", Devices, Arr);
foreach (var Device in (IEnumerable)Devices)
{
RegObj.GetStringValue(HKEY_CURRENT_USER, @"SoftwareMicrosoftWindows NTCurrentVersionDevices", Device, RegValue);
Printer = Conversions.ToString(Operators.ConcatenateObject(Operators.ConcatenateObject(Device, " on "), Strings.Split(RegValue, ",")[1]));
if (Strings.InStr(1, Printer, PrinterName, Constants.vbTextCompare) > 0)
{
FindPrinterRet = Printer;
return FindPrinterRet;
}
}
return FindPrinterRet;
}
但是foreach循环之前的行会导致. enumvalues部分出现问题,因为c#不确定如何处理这个问题,RegObj也是如此。
据我所知,这些值只是系统的一部分。对象类。. NET,但是我找不到让它们在c#中工作的方法。
感谢每个花时间帮助我做这件事的人。
确切的误差是'object'没有包含'EnumValues'的定义,并且找不到可访问的扩展方法'EnumValues'接受'object'类型的第一个参数。
逐字翻译更像是:
static string? FindPrinter(string PrinterName)
{
const int HKEY_CURRENT_USER = int.MinValue + 0x00000001;
dynamic regObj = Interaction.GetObject(@"winmgmts:{impersonationLevel=impersonate}!\.rootdefault:StdRegProv")!;
regObj!.EnumValues(HKEY_CURRENT_USER, @"SoftwareMicrosoftWindows NTCurrentVersionDevices", out dynamic devices, out dynamic arr);
foreach (var device in devices)
{
regObj.GetStringValue(HKEY_CURRENT_USER, @"SoftwareMicrosoftWindows NTCurrentVersionDevices", device, out dynamic value);
var printer = $"{device} on {value.Split(',')[1]}";
if (printer.Contains(PrinterName, StringComparison.OrdinalIgnoreCase))
return printer;
}
return null;
}
无论你想做什么,都有更好的方法,从PrinterSettings.InstalledPrinters
,LocalPrintServer
类,到WMI。即使你坚持自己使用注册表,也有比这样使用COM更好的方法。
无需使用WMI打开注册表
public string FindPrinter(string PrinterName) {
string subkey = "Software\Microsoft\Windows NT\CurrentVersion\Devices";
var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(subkey);
var printers = key.GetValueNames();
foreach(var printer in printers)
{
if (printer == PrinterName) {
return key.GetValue(printer);
}
}
return null;
}