指定机器名时无法在自己的机器上查询SystemIndex
Can't query SystemIndex on my own machine when I specify the machine name
我正在尝试编写一个简单的程序来连接到远程计算机并查询索引状态。
这是在我的机器上执行此操作的代码。这工作正常。
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();
}
}
}
但是,当我在 "mycomputername.SystemIndex"
而不是 "SystemIndex"
上调用 GetCatalog
时,我得到
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in
IndexStatus.exe
Additional information: Exception from HRESULT: 0x80042103
Visual Studio 2015 是 运行 Windows 8.1 的管理员权限。目标计算机主要是 Windows 7 个系统,程序主要是 运行 来自 Windows 10 个系统。我正在使用 Microsoft.Search.Interop.dll 来自 Microsoft Windows 搜索 3.X 从 here 下载的 SDK。我关闭了防火墙以防与它有关,但显然不是。
我已经检查过,如果我完全像 "sdfd"
那样调用该函数,我会得到相同的异常。我发现 this:
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 docs这样说:
Currently Microsoft Windows Desktop Search (WDS) 3.0 supports only one
catalog and it is named 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));
至于"Interop type cannot be embedded"的错误信息,我找到了this question。有两个建议的解决方案:
将 Microsoft.Search.Interop 引用的 Embed Interop Types
属性 更改为 False
。
将CSearchManagerClass
更改为CSearchManager
。
第一种方案使程序编译通过,但影响可移植性。现在该程序不会 运行 在没有 .dll 的计算机上。第二个解决方案编译但抛出
An unhandled exception of type 'System.ArgumentException' occurred in
mscorlib.dll
Additional information: The type must be __ComObject or be derived
from __ComObject.
当我 运行 它针对我自己的机器时,在那个确切的行上。
但是还有一个问题,这个我就不知道了。当我 运行 它针对我同事的机器时(我是他计算机的管理员并且 Visual Studio 是 运行 管理员权限),我得到
An unhandled exception of type 'System.UnauthorizedAccessException'
occurred in mscorlib.dll
Additional information: Retrieving the COM class factory for remote
component with CLSID {7D096C5F-AC08-4F1F-BEB7-5C22C517CE39} from
machine computername failed due to the following error: 80070005
computername.
这确实让我有点害怕,因为我对 COM 几乎一无所知。我已经检查过他的计算机和我的计算机上是否启用了 DCOM。但是,当我尝试在组件服务中访问他的计算机时,它显示为 and DCOM Config is missing from the tree. And the same happens for other computers on the domain (even though I have admin rights on all workstations). This blog 表明这可能是防火墙问题,如果是,则无法克服。
你的两个答案绝对已经值得赏金,但如果你有任何建议或能够阐明正在发生的事情,我将非常感激。如果我做不到,也没关系,但我绝对想从中获取尽可能多的知识。
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
调用中抛出。
有关此的 PowerShell 版本,请参阅 my answer to your Super User question。
我正在尝试编写一个简单的程序来连接到远程计算机并查询索引状态。
这是在我的机器上执行此操作的代码。这工作正常。
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();
}
}
}
但是,当我在 "mycomputername.SystemIndex"
而不是 "SystemIndex"
上调用 GetCatalog
时,我得到
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in IndexStatus.exe
Additional information: Exception from HRESULT: 0x80042103
Visual Studio 2015 是 运行 Windows 8.1 的管理员权限。目标计算机主要是 Windows 7 个系统,程序主要是 运行 来自 Windows 10 个系统。我正在使用 Microsoft.Search.Interop.dll 来自 Microsoft Windows 搜索 3.X 从 here 下载的 SDK。我关闭了防火墙以防与它有关,但显然不是。
我已经检查过,如果我完全像 "sdfd"
那样调用该函数,我会得到相同的异常。我发现 this:
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 docs这样说:
Currently Microsoft Windows Desktop Search (WDS) 3.0 supports only one catalog and it is named 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));
至于"Interop type cannot be embedded"的错误信息,我找到了this question。有两个建议的解决方案:
将 Microsoft.Search.Interop 引用的
Embed Interop Types
属性 更改为False
。将
CSearchManagerClass
更改为CSearchManager
。
第一种方案使程序编译通过,但影响可移植性。现在该程序不会 运行 在没有 .dll 的计算机上。第二个解决方案编译但抛出
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: The type must be __ComObject or be derived from __ComObject.
当我 运行 它针对我自己的机器时,在那个确切的行上。
但是还有一个问题,这个我就不知道了。当我 运行 它针对我同事的机器时(我是他计算机的管理员并且 Visual Studio 是 运行 管理员权限),我得到
An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
Additional information: Retrieving the COM class factory for remote component with CLSID {7D096C5F-AC08-4F1F-BEB7-5C22C517CE39} from machine computername failed due to the following error: 80070005 computername.
这确实让我有点害怕,因为我对 COM 几乎一无所知。我已经检查过他的计算机和我的计算机上是否启用了 DCOM。但是,当我尝试在组件服务中访问他的计算机时,它显示为
你的两个答案绝对已经值得赏金,但如果你有任何建议或能够阐明正在发生的事情,我将非常感激。如果我做不到,也没关系,但我绝对想从中获取尽可能多的知识。
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
调用中抛出。
有关此的 PowerShell 版本,请参阅 my answer to your Super User question。