5

我正在尝试编写一个简单的程序来连接到远程机器并查询索引状态。

这是在我的机器上执行的代码。这工作正常。

using System;
using Microsoft.Search.Interop;

namespace IndexStatus
{
    class Program
    {
        static void Main(string[] args)
        {
            CSearchManager manager = new CSearchManager();
            CSearchCatalogManager catalogManager = manager.GetCatalog("SystemIndex");
            _CatalogPausedReason pReason;
            _CatalogStatus pStatus;
            Console.WriteLine(catalogManager.NumberOfItems().ToString());
            int plIncrementalCount;
            int plNotificationQueue;
            int plHighPriorityQueue;
            catalogManager.NumberOfItemsToIndex(out plIncrementalCount, out plNotificationQueue, out plHighPriorityQueue);
            Console.WriteLine(plIncrementalCount.ToString());
            Console.WriteLine(plNotificationQueue.ToString());
            Console.WriteLine(plHighPriorityQueue.ToString());
            catalogManager.GetCatalogStatus(out pStatus, out pReason);
            Console.WriteLine(pStatus.ToString() + " " + pReason.ToString());
            Console.ReadLine();
        }
    }
}

但是,当我打电话GetCatalog"mycomputername.SystemIndex"不是"SystemIndex",我得到

IndexStatus.exe 中出现“System.Runtime.InteropServices.COMException”类型的未处理异常

附加信息:HRESULT 异常:0x80042103

在此处输入图像描述

Visual Studio 2015 在 Windows 8.1 上以管理员权限运行。目标计算机主要是 Windows 7 系统,程序主要从 Windows 10 系统运行。我正在使用从此处下载的 Microsoft Windows Search 3.X SDK 中的 Microsoft.Search.Interop.dll 。我关闭了防火墙以防万一,但显然不是。

我已经检查过,如果我在完全无意义的情况下调用函数,例如"sdfd". 我发现了这个

MSS_E_CATALOGNOTFOUND - 0x80042103 - (8451) WindowsSearchErrors.h

The specified catalog was not found. Check to see if it was deleted, or if there are errors in your application code.

我尝试使用“localhost”而不是机器名,但这没有帮助。

MSDN 文档是这样说的:

目前 Microsoft Windows 桌面搜索 (WDS) 3.0 仅支持一个目录,名为 SystemIndex。

我不确定如何理解这一点。也许该方法无法在不同的机器之间进行选择?如果是这样,除了使用 PsExec 之类的东西之外,还有其他方法可以连接到远程目录并进行这些查询吗?

Re Ben N 的回答:这对我来说开始变得很深,但我更着迷而不是害怕。:) 经过几次修改后,您的代码对我有用:

CSearchManagerClass manager = System.Runtime.InteropServices.Marshal.CreateWrapperOfType(comManager, typeof(CSearchManagerClass));无法在 Visual Studio 2015 上编译,并会出现以下错误:

在此处输入图像描述 在此处输入图像描述

第二个错误很容易通过添加一个演员来修复:

CSearchManagerClass manager = (CSearchManagerClass)System.Runtime.InteropServices.Marshal.CreateWrapperOfType(comManager, typeof(CSearchManagerClass));

至于“无法嵌入互操作类型”的错误信息,我发现了这个问题。有两种建议的解决方案:

  • Embed Interop Types将 Microsoft.Search.Interop 引用的属性更改为False.

  • 更改CSearchManagerClassCSearchManager

第一个解决方案使程序可以编译,但它会影响可移植性。现在该程序将无法在没有 .dll 的计算机上运行。第二种解决方案编译但抛出

mscorlib.dll 中出现“System.ArgumentException”类型的未处理异常

附加信息:类型必须是 __ComObject 或派生自 __ComObject。

当我在我自己的机器上运行它时,就在那条线上。

但是还有另一个问题,这个我不知道。当我在同事的机器上运行它时(我是他计算机上的管理员,并且 Visual Studio 以管理员权限运行),我得到

mscorlib.dll 中出现“System.UnauthorizedAccessException”类型的未处理异常

附加信息:由于以下错误,从计算机计算机名检索具有 CLSID {7D096C5F-AC08-4F1F-BEB7-5C22C517CE39} 的远程组件的 COM 类工厂失败:80070005 计算机名。

这确实让我有点害怕,因为我对 COM 几乎一无所知。我检查了他的电脑和我的电脑上是否启用了 DCOM。但是当我尝试在组件服务中访问他的计算机时,它显示为 a在此处输入图像描述并且树中缺少 DCOM 配置。域中的其他计算机也会发生同样的情况(即使我在所有工作站上都​​拥有管理员权限)。该博客表明这可能是防火墙问题,如果是,则无法克服。

您的两个答案都绝对值得赏金,但是如果您有任何建议或能够阐明正在发生的事情,我将不胜感激。如果我不能让它工作,那很好,但我肯定想从中获取尽可能多的知识。

4

1 回答 1

1

GetCatalog不支持联系远程机器,但我们可以使用 COM 创建一个搜索管理器对象,该对象引用目标计算机上的服务。

// Assume targetMachine has the name of the target computer
Guid guid = new Guid("{7D096C5F-AC08-4F1F-BEB7-5C22C517CE39}");
Type managerType = Type.GetTypeFromCLSID(guid, targetMachine, true);
var comManager = Activator.CreateInstance(managerType);
CSearchManagerClass manager = (CSearchManagerClass)System.Runtime.InteropServices.Marshal.CreateWrapperOfType(comManager, typeof(CSearchManagerClass));

然后,您应该能够manager像本地机器的管理员一样使用它。如果在联系远程计算机时出现问题,COMException将在CreateInstance通话中抛出 a。

对于 PowerShell 版本,请参阅我对您的超级用户问题的回答

于 2016-07-07T17:04:08.630 回答