【问题标题】:Windows Service with WMI带有 WMI 的 Windows 服务
【发布时间】:2012-02-23 17:59:51
【问题描述】:

对于我的一位客户,我正在用 C# 编写一个 Windows 服务。它检查了很多东西,但它必须做的一件事是检查打印机端口(IP 地址)是否已经存在。如果是,将某些打印机连接到 IP 端口。如果没有,请创建端口并连接。

我使用 WMI 检查现有的打印机端口并创建它们。我还使用 WMI 将打印机连接到打印机端口。

在 Windows 7 上,这就像一个魅力。但是在我的(虚拟)XP 机器上,该服务似乎根本没有任何 WMI 权限。端口检查失败,创建失败。只给出了来自 ManagementException 的简单“拒绝访问”。

如果我制作一个小测试程序(C# 中的控制台应用程序),它也能像魅力一样工作。

我尝试在不同的帐户(本地系统、管理员、我的具有管理员权限的个人登录)下运行该服务,但似乎没有任何效果,而且我感觉您无法在 Windows XP 上的 Windows 服务中使用 WMI。

你们知道如何解决这个问题吗?或者这里有什么问题?

不知道去哪里找答案,所以在这里注册了一个账号,希望能和你一起找到正确的答案。

【问题讨论】:

    标签: c# windows service windows-xp wmi


    【解决方案1】:

    您使用的是 Win32_Printer 吗?在Win32_Printer 参考页面上,它说,

    备注

    Win32_Printer 类派生自 CIM_Printer。在为 Win32_Printer 实例调用 SWbemObject.Put_ 或 IWbemServices::PutInstance 之前,必须启用 SeLoadDriverPrivilege 权限(用于 Visual Basic 的 wbemPrivilegeLoadDriver 和用于脚本名字对象的 LoadDriver)。有关详细信息,请参阅特权常量和执行特权操作。下面的 VBScript 代码示例展示了如何在脚本中启用 SeLoadDriverPrivilege 权限。

    编辑:我知道 Windows Server 2003 和 Server 2008 在服务方面存在差异。在较旧的操作系统下(可能包括 XP),默认情况下不加载用户的配置文件。这在尝试使用 DPAPI API 时会出现问题。也许,在这种情况下正在发生类似的事情。只是猜测。

    编辑:确保在连接到 WMI 时启用模拟。 Win32_TCPIPPrinterPort 页面上有一个示例。

    ConnectionOptions options = new ConnectionOptions();
    options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
    
    ManagementScope scope = new ManagementScope(@"\\root\\cimv2", options);
    scope.Connect();
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where HostAddress = '" + printerPort + "'"); 
    

    【讨论】:

    • 是的,我使用的是 WIN32_Printer。但它适用于同一台 XP 计算机上的控制台应用程序。
    • 更正:我使用 WMI,它在 WMI 中引用 Win32_Printer '文件夹/类'。我不直接使用 Win32_Printer 来完成任务。
    • Win32_Printer 是一个 WMI 类。如果您没有使用 Win32_Printer,您使用的是哪个 WMI 类?
    • 嗯,也许我没有 WMI 和/或 C# 的经验来理解你的问题。我使用以下代码(示例): ManagementScope scope = new ManagementScope(@"\root\cimv2");范围.连接(); ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where HostAddress = '" + printerPort + "'");
    • 我尝试使用第二次编辑中描述的模拟:仍然无法正常工作。同样的错误:访问被拒绝。从控制台应用程序工作.....
    【解决方案2】:

    您可以尝试两件事,首先您可以尝试在 ConnectionOptions 上设置一些凭据

    ConnectionOptions options = new ConnectionOptions();
    options.Username = userName;
    options.Password = password;
    options.EnablePrivileges = true;
    

    另一种方法是将整个代码包装在一些模拟技巧中,但我肯定会先尝试查看 ConnectionOptions。

    如果你想尝试模拟位,我不久前写了一篇关于它的博文。 http://beddet.wordpress.com/2011/09/25/remote-controlling/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-29
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多