当我指定机器名时,无法在我自己的机器上查询SystemIndex

Mic*_*sny 5 c# windows windows-search

我正在尝试编写一个简单的程序,它将连接到远程计算机并查询索引状态.

这是在我的机器上执行的代码.这很好用.

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,当我打电话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.
Run Code Online (Sandbox Code Playgroud)

我试图使用"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));
Run Code Online (Sandbox Code Playgroud)

至于"Interop type can not embedded"错误信息,我发现了这个问题.有两种建议的解决方案:

  • 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 computername.

这确实让我感到害怕,因为我对COM几乎一无所知.我已经检查过他的计算机和我的DCOM已启用.但是,当我尝试在组件服务中访问他的计算机时,它显示为在此输入图像描述树中缺少DCOM配置.对于域中的其他计算机也是如此(即使我对所有工作站都拥有管理员权限).这个博客表明它可能是一个防火墙问题,如果是,它不是一个可以克服的东西.

你的两个答案肯定都值得肯定,但如果你有任何建议或者能够对正在发生的事情有所了解,我将非常感激.如果我不能使它工作,那很好,但我肯定希望从中获取尽可能多的知识.

Ben*_*n N 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));
Run Code Online (Sandbox Code Playgroud)

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

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