【发布时间】:2011-12-09 15:28:15
【问题描述】:
我找到了多个使用 c# 建立与远程计算机的 WMI 连接的在线教程。这些教程描述了如下过程:
ConnectionOptions cOpts = new ConnectionOptions();
ManagementObjectCollection moCollection;
ManagementObjectSearcher moSearcher;
ManagementScope mScope;
ObjectQuery oQuery;
mScope = new ManagementScope(String.Format("\\\\{0}\\{1}", host.hostname, "ROOT\\CIMV2"), cOpts);
oQuery = new ObjectQuery("Select * from Win32_OperatingSystem");
moSearcher = new ManagementObjectSearcher(mScope, oQuery);
moCollection = moSearcher.Get();
快乐路径案例 - 连接到本地主机,或使用适当的凭据连接到远程主机 - 工作正常。我正在做一个项目,当当前登录的帐户无权访问我们尝试连接的远程主机时,我们需要支持这种情况。也就是说,我们需要抓住这种情况,提醒用户注意错误的凭据,并提示他们再次提供凭据。
当我在我的 ConnectionOptions 对象中指定在远程计算机上没有上下文的凭据时,我对 moSearcher.Get() 的调用会无限期地挂起(似乎)。同样,对 ManagementScope 中的 Connect() 函数的调用以相同的方式挂起。
我们有类似的逻辑来在 c++ 中执行等效的 WMI 命令,我可以报告如果提供了不正确的凭据,这些命令几乎会立即返回。返回适当的“访问被拒绝”消息。我现在用于测试目的的主机与我们在测试现有 c++ 逻辑时使用的主机相同,因此我没有理由相信 WMI 在我们的环境中配置不正确。
我已经在 c# 中搜索了围绕 WMI 连接的超时问题。我已经探索了 ConnectionOptions 和 moSearcher.Options 的 Timeout 属性。我还查看了可以与 ManagementObjectSearcher 实例关联的 EnumerationOptions 对象的 ReturnImmediately 属性。这些选项对我来说没有达到预期的效果。
我想我可以在一个单独的线程中执行这些 WMI 命令,并用监视代码包围该线程,如果它在合理的时间内没有返回,则将其杀死。这似乎是相当多的工作将推给 c# WMI 例程的所有消费者,我希望有一种更简单的方法。另外,我不确定以这种方式杀死一个未完成的线程是否会正确清理 WMI 连接。
ping 远程主机对我没有任何好处,因为知道主机已启动并正在运行并不能告诉我我拥有的凭据是否合适(以及 c# WMI 调用是否会挂起)。还有其他方法可以针对远程主机验证凭据吗?
总是有可能我缺少一个明显的标志或 API,因为我认为其他人已经遇到了这个问题。任何信息/帮助将不胜感激。感谢您阅读这篇冗长的文章。
【问题讨论】: