You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中使用WMI获取打印机状态时遭遇NotFound错误问题

问题分析与解决方案

你的.NET Core项目中使用WMI查询Win32_Printer时,即便传入正确的打印机名称仍报“Not Found”错误,可从以下几个方向排查解决:

1. 查询语句的转义与语法问题

直接用字符串拼接生成WMI查询时,若打印机名称包含单引号、空格或特殊字符,会导致语法错误,直接查不到结果。比如名称为Mike's Printer时,拼接后的语句会出现单引号冲突,触发查询失败。

解决方式:使用参数化查询或手动转义特殊字符:

// 方法1:手动转义单引号
string escapedPrinterName = printerName.Replace("'", "''");
string query = $"SELECT * from Win32_Printer WHERE NAME = '{escapedPrinterName}'";

// 方法2:参数化查询(更安全)
string query = "SELECT * from Win32_Printer WHERE NAME = @printerName";
var searcher = new ManagementObjectSearcher();
searcher.Query = new ObjectQuery(query);
var parameters = new ManagementBaseObject();
parameters["printerName"] = printerName;
searcher.Query.Parameters.Add(parameters);

2. WMI访问权限限制

.NET Core默认运行权限可能不足以读取WMI打印机信息,尤其是非管理员身份运行时;若查询远程打印机,还需目标机器开启WMI服务并配置对应权限。

解决方式:

  • 尝试以管理员身份启动程序,验证是否能正常查询。
  • 远程查询场景:在目标机器的「计算机管理」→「服务和应用程序」→「WMI控制」中,给当前用户分配WMI远程访问权限,同时确保目标机器的WMI服务(Winmgmt)处于运行状态。

3. 打印机名称匹配偏差

Win32_Printer的Name字段可能和系统显示的打印机名称不一致,比如网络打印机的Name会包含完整路径(如\\print-server\HP-LaserJet),而你传入的是本地简化名称。

解决方式:先枚举所有打印机,确认目标打印机的真实Name值:

var searcher = new ManagementObjectSearcher("SELECT Name, DeviceID FROM Win32_Printer");
foreach (var printer in searcher.Get())
{
    _logger.LogInformation($"真实Name: {printer["Name"]}, DeviceID: {printer["DeviceID"]}");
}

用查询到的真实Name作为参数传入方法,再测试查询效果。

4. .NET Core的WMI兼容性问题

.NET Core对传统WMI的支持不如.NET Framework完善,部分场景下会出现查询异常。可改用微软推荐的Microsoft.Management.Infrastructure(MMI)库替代System.Management。

示例代码(MMI实现):

using Microsoft.Management.Infrastructure;

public async Task<Response> PrinterStateByName(string sessionId, string printerName)
{
    try
    {
        var cimSession = CimSession.Create(null); // 本地会话
        var escapedName = printerName.Replace("'", "''");
        var query = $"SELECT * FROM Win32_Printer WHERE Name = '{escapedName}'";
        var printers = cimSession.QueryInstances(@"root\cimv2", "WQL", query);
        
        foreach (var printer in printers)
        {
            string name = printer.CimInstanceProperties["Name"].Value.ToString();
            string status = printer.CimInstanceProperties["Status"].Value?.ToString();
            bool isDefault = (bool)printer.CimInstanceProperties["Default"].Value;
            bool isOnline = !(bool)printer.CimInstanceProperties["WorkOffline"].Value;
            bool isOutOfPaper = (bool)printer.CimInstanceProperties["OutOfPaper"].Value;

            _logger.LogInformation($"Printer Name: {name}");
            _logger.LogInformation($"Printer State: {status}");
            _logger.LogInformation($"Is Printer Default: {isDefault}");
            _logger.LogInformation($"Online state: {isOnline}");
            _logger.LogInformation($"Out of the Paper: {isOutOfPaper}");
        }
    }
    catch (CimException e)
    {
        _logger.LogError($"Error during getting informations about: {e.Message}");
    }

    var result = await _mediator.Send(new SendPrinterStateByName_Command(printerName));
    return new Response(false, result, null, sessionId);
}

注:需先安装NuGet包Microsoft.Management.Infrastructure。

5. 异步代码的小问题

你的方法标记为async Task<Response>,但调用_mediator.Send时未加await,会导致返回结果时任务未完成,可能引发逻辑异常,建议修正为:

var result = await _mediator.Send(new SendPrinterStateByName_Command(printerName));

内容的提问来源于stack exchange,提问作者Petr Barabáš

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:08:13