65.9K
CodeProject 正在变化。 阅读更多。
Home

从应用程序内部管理索引服务器

2005 年 7 月 2 日

8分钟阅读

viewsIcon

41062

downloadIcon

426

详细描述了如何以编程方式管理索引服务器,例如创建一个新的索引目录,然后为该目录添加要索引的文件夹。

引言

您可以通过 Microsoft 索引服务器在应用程序中提供强大的搜索功能。索引服务器可用于索引本地或网络文件系统上的文件,以及本地网站的文件。然后,您可以使用标准的 SQL 语法查询索引目录。 以下文章详细介绍了如何创建和配置自己的索引目录,然后在应用程序中进行搜索。本文重点介绍如何以编程方式管理索引服务器,例如创建一个新的索引目录,然后为该目录添加要索引的文件夹。

索引服务管理 API

.NET Framework 的当前版本不提供任何类型的以编程方式管理索引服务器的功能。但是,索引服务器提供了一个基于 COM 的 API,您可以使用它。在“添加引用”对话框的“COM”选项卡下,添加对“索引服务管理类型库 1.0”的引用。这将引用 windows\system32 文件夹中的“ciodm.dll”。接下来,导入“CIODMLib”命名空间,这将使您能够访问以下三个类型:

  • AdminIndexServerClass - 此类型用于管理索引服务器本身。它允许创建或删除目录、启动或停止索引服务等。
  • CatAdmClass - 此类型提供对现有索引目录的访问。您可以添加或删除搜索范围、启动或停止目录等。
  • ScopeAdm - 此类型提供对搜索范围的访问。您可以为搜索范围设置登录信息、启动完全或增量扫描等。

如何检索索引目录列表?

索引服务器可以有许多索引目录,您的应用程序始终会告诉索引服务器要搜索哪个目录。您可以使用 AdminIndexServerClass 类型枚举所有已定义的索引目录。首先,您需要创建一个 AdminIndexServerClass 类型的实例。然后,您可以调用 FindFirstCatalog() 来查找列表中的第一个目录。如果找到目录,则返回 true,否则返回 false。要查找下一个目录,您可以调用 FindNextCatalog(),它同样会返回 true(如果找到另一个目录),否则返回 false。如下面的示例所示,您首先调用 FindFirstCatalog(),然后在循环中调用 FindNextCatalog(),直到其中一个返回 false。每次调用后,您都可以调用 GetCatalog() 来获取列表中当前目录的引用。这将返回一个 object 类型的对象,您需要查询该对象上的适当接口。简单的类型转换将不起作用,因为您正在处理 COM 对象。您需要使用“as”关键字,后跟您要查找的接口。这将在底层查询该 COM 对象上的适当接口,如果不存在则返回 null,否则返回接口的引用。您要查找的接口是 ICatAdm 接口,它为您提供了对目录本身的访问。CatAdm 类型本身实现了 ICatAdm 接口。

protected void FillCatalogList(ListView ListOfCatalogs)
{
    AdminIndexServerClass Admin = new AdminIndexServerClass();
    
    // remove any existing item in the catalog list
    ListOfCatalogs.Items.Clear();
    
    // finds the first catalog in the list
    bool FoundCatalog = Admin.FindFirstCatalog();
    
    // loop through all catalogs present
    while (FoundCatalog)
    {
        // gets the object representing the current catalog
        ICatAdm Catalog = Admin.GetCatalog() as ICatAdm;
        
        // adds the catalog details to the list view
        ListViewItem Item = 
               ListOfCatalogs.Items.Add(Catalog.CatalogName);
        Item.SubItems.Add(Catalog.CatalogLocation);
        Item.SubItems.Add(Catalog.IsUpToDate.ToString());
        Item.SubItems.Add(Catalog.DocumentsToFilter.ToString());
        Item.SubItems.Add(Catalog.FilteredDocumentCount.ToString());
        Item.SubItems.Add(Catalog.DelayedFilterCount.ToString());
        Item.SubItems.Add(Catalog.FreshTestCount.ToString());
        Item.SubItems.Add(Catalog.IndexSize.ToString());
        Item.SubItems.Add(Catalog.PctMergeComplete.ToString());
        Item.SubItems.Add(Catalog.PendingScanCount.ToString());
        Item.SubItems.Add(Catalog.PersistentIndexCount.ToString());
        Item.SubItems.Add(Catalog.QueryCount.ToString());
        Item.SubItems.Add(Catalog.StateInfo.ToString());
        Item.SubItems.Add(Catalog.TotalDocumentCount.ToString());
        Item.SubItems.Add(Catalog.UniqueKeyCount.ToString());
        Item.SubItems.Add(Catalog.WordListCount.ToString());
        
        // finds the next catalog in the list
        FoundCatalog = Admin.FindNextCatalog();
    }
    
    // select the first catalog in the list
    if (ListOfCatalogs.Items.Count > 0)
        ListOfCatalogs.SelectedIndices.Add(0);
}

如上例所示,ICatAdm 接口提供了许多关于目录的属性。您可以获取名称、位置、目录是否是最新的等等。上例会将找到的每个目录添加到列表视图中。

如何启动、停止、暂停或继续索引服务器?

AdminIndexServerClass 提供了四个方法来启动、停止、暂停和继续索引服务。它还提供了方法来检查服务是否正在运行或已暂停。

  • Start() - 启动索引服务。
  • Stop() - 停止索引服务。
  • Pause() - 暂停索引服务。
  • Continue() - 继续暂停的索引服务。
  • IsRunning() - 如果索引服务正在运行,则返回 true
  • IsPaused() - 如果索引服务已暂停,则返回 true

如何添加或删除索引目录?

您可以使用 AddCatalog() 方法添加新目录。您需要提供新目录的名称以及目录的创建位置。您需要重新启动索引服务才能使用新创建的目录。以下示例显示了一个对话框,允许用户输入新目录的名称和位置。然后调用 AddCatalog,然后询问用户是否重新启动索引服务以便目录可用。最后,它调用上面所示的方法重新查询已定义的目录列表 - FillCatalogList()

private void AddCatalog_Click(object sender, EventArgs e)
{
    // the dialog to create a new catalog
    AddNewCatalog AddNew = new AddNewCatalog();
    
    // we want to create the catalog
    if (AddNew.ShowDialog(this) == DialogResult.OK)
    {
        AdminIndexServerClass Admin = 
                        new AdminIndexServerClass();
        
        // create the new catalog
        Admin.AddCatalog(AddNew.NewCatalogName, 
                         AddNew.NewCatalogLocation);
        
        // restart the service for the new catalog to function
        if (MessageBox.Show(this, RestartService, this.Text,
                  MessageBoxButtons.YesNo, 
                  MessageBoxIcon.Question) == DialogResult.Yes)
        {
            Admin.Stop();
            Admin.Start();
        }
        
        // refresh the list of catalogs
        FillCatalogList(ListOfCatalogs);
    }
}

您可以调用 RemoveCatalog() 来删除现有目录。您需要提供目录的名称。您还需要先停止索引服务才能删除任何目录。下面的示例询问用户是否要删除当前选定的目录。如果用户确认,它会停止索引服务,删除目录,然后再次启动索引服务。之后,它再次调用 FillCatalogList() 来刷新列表视图中的目录列表。

private void RemoveCatalog_Click(object sender, EventArgs e)
{
    string CatalogName = ListOfCatalogs.SelectedItems[0].Text;
    
    // ask the user to confirm the deletion of the catalog
    if (MessageBox.Show(this, ConfirmDeleteCatalog, CatalogName,
                     MessageBoxButtons.YesNo, 
                     MessageBoxIcon.Question) == DialogResult.Yes)
    {
        AdminIndexServerClass Admin = new AdminIndexServerClass();
        
        Admin.Stop();
        Admin.RemoveCatalog(CatalogName, true);
        Admin.Start();
        
        // refresh the list of catalogs
        FillCatalogList(ListOfCatalogs);
    }
}

如何检索目录的搜索范围列表?

每个目录都有搜索范围,即包含在目录中的文件夹。搜索范围可以是包含的(默认)或排除的,这意味着该文件夹将不包含在目录中。使用排除项,您可以定义应从此目录中排除的子文件夹。列出目录的所有搜索范围的工作方式与列出索引服务器的所有目录非常相似。首先,通过在 AdminIndexServerClass 类型的实例上调用 GetCatalogByName() 方法来获取目录的引用。这将返回一个 object 类型的对象,您需要使用“as”关键字查询 ICatAdm 接口。

private ICatAdm GetCatalog(string CatalogName)
{
    AdminIndexServerClass Admin = new AdminIndexServerClass();
    
    // find the catalog by name
    return Admin.GetCatalogByName(CatalogName) as ICatAdm;
}

接下来,您在 ICatAdm 接口上调用 FindFirstScope() 来获取第一个搜索范围,如果找到则返回 true,否则返回 false。您在 ICatAdm 接口上调用 FindNextScope() 来查找后续搜索范围,如果找到则返回 true,否则返回 false。您再次在循环中执行此操作,直到返回 false。每次您调用 GetScope() 来获取当前搜索范围的引用。这同样会返回一个 object 类型的对象,您通过“as”关键字查询 IScopeAdm 接口。然后,该接口提供了有关搜索范围本身的属性列表。

private void FillScopeList(string CatalogName)
{
    // remove any existing item in the scope list
    ListOfScopes.Items.Clear();
    
    // get a handle to the newly selected catalog
    ICatAdm Catalog = GetCatalog(CatalogName);
    
    // search for the first scope item
    bool FoundScope = Catalog.FindFirstScope();
    
    // loop through all the scope items
    while (FoundScope)
    {
        // get a handle to the current scope item
        IScopeAdm Scope = Catalog.GetScope() as IScopeAdm;
        
        // create a new list view item and set its values
        ListViewItem Item = ListOfScopes.Items.Add(Scope.Alias);
        Item.SubItems.Add(Scope.ExcludeScope.ToString());
        Item.SubItems.Add(Scope.Logon);
        Item.SubItems.Add(Scope.Path);
        Item.SubItems.Add(Scope.VirtualScope.ToString());
        
        // search for the next scope item
        FoundScope = Catalog.FindNextScope();
    }
    
    // select the first scope in the list
    if (ListOfScopes.Items.Count > 0)
        ListOfScopes.SelectedIndices.Add(0);
}

上面的示例会将目录的所有搜索范围添加到列表视图中。这包括搜索范围的路径以及它是否为排除项。仅当此目录索引网站时,才会设置 VirtualScope

如何启动、停止、暂停或继续目录?

您可以启动、停止、暂停或继续单个目录。首先,您需要通过在 AdminIndexServerClass 类型的实例上调用 GetCatalogByName 来获取目录的引用。然后,您再次查询 ICatAdm 接口。ICatAdm 接口还提供了用于检查目录是否正在运行或已暂停的方法。

  • StartCatalog() - 启动索引目录。
  • StopCatalog() - 停止索引目录。
  • PauseCatalog() - 暂停索引目录。
  • ContinueCatlog() - 继续暂停的索引目录。
  • IsCatalogRunning() - 如果索引目录正在运行,则返回 true
  • IsCatalogPaused() - 如果索引目录已暂停,则返回 true

如何向目录添加或删除搜索范围?

首先,您需要获取目录的引用,然后调用 AddScope() 方法。您需要提供要索引的文件夹,如果搜索范围是排除的,则为 true,如果是包含的,则为 false。下面的示例显示了一个对话框,允许用户输入搜索范围的文件夹并选择它是排除还是包含。接下来,它获取当前选定目录的名称,获取其目录对象,然后通过在 Catalog 对象上调用 AddScope() 来添加搜索范围。然后,它询问用户是否应为其执行完全扫描。在这种情况下,它通过在 Catalog 对象上调用 GetScopeByPath() 来获取新创建的搜索范围的引用,然后调用其上的 Rescan() 并传递 true 以进行完全扫描。最后,它调用 FillScopeList() 方法来刷新列表视图中的搜索范围列表。

private void AddScope_Click(object sender, EventArgs e)
{
    string CatalogName = ListOfCatalogs.SelectedItems[0].Text;
    
    // the dialog to create a new scope
    AddNewScope AddNew = new AddNewScope();
    
    // we want to create the scope
    if (AddNew.ShowDialog(this) == DialogResult.OK)
    {
        // get the catalog handle
        ICatAdm Catalog = GetCatalog(CatalogName);
        
        // create the new scope
        Catalog.AddScope(AddNew.Path, AddNew.ExcludeFolder, 
                                                 null, null);
        
        // ask the user if we want to scan the new search scope
        if (MessageBox.Show(this, PerformFullScan, this.Text,
                    MessageBoxButtons.YesNo, 
                    MessageBoxIcon.Question) == DialogResult.Yes)
        {
            // get a reference to the search scope we just added
            IScopeAdm Scope = 
                Catalog.GetScopeByPath(AddNew.Path) as IScopeAdm;
            
            // to a full scan
            Scope.Rescan(true);
        }
        
        // refresh the list of scopes
        FillScopeList(ListOfCatalogs.SelectedItems[0].Text);
    }
}

添加或删除搜索范围不需要停止或重新启动目录服务。要删除搜索范围,您需要在 Catalog 对象上调用 RemoveScope() 方法,并传递搜索范围的路径。下面的示例询问用户是否要删除当前选定的搜索范围。如果用户确认,它会删除搜索范围,然后再次调用 FillScopeList() 来刷新列表视图中的搜索范围列表。

private void RemoveScope_Click(object sender, EventArgs e)
{
    string CatalogName = ListOfCatalogs.SelectedItems[0].Text;
    string ScopePath = 
         ListOfScopes.SelectedItems[0].SubItems[3].Text
    
    // ask the user to confirm the deletion of the search scope
    if (MessageBox.Show(this, ConfirmDeleteScope, ScopePath,
                 MessageBoxButtons.YesNo, 
                 MessageBoxIcon.Question) == DialogResult.Yes)
    {
        // get the catalog handle
        ICatAdm Catalog = GetCatalog(CatalogName);
        
        // delete the selected scope
        Catalog.RemoveScope(ScopePath);
        
        // refresh the list of scopes
        FillScopeList(ListOfCatalogs.SelectedItems[0].Text);
    }
}

摘要

索引服务器的管理 API 非常简单。AdminIndexServerClass 类型使您能够完全控制索引服务器本身。ICatAdm 接口和 CatAdm 类型提供了对每个目录的完全控制。IScopeAdm 接口和 ScopeAdm 类型提供了对每个搜索范围的完全控制。这使得您能够非常轻松地以编程方式添加新的目录和搜索范围,或删除现有的目录和搜索范围。您还可以选择强制对搜索范围进行完全或部分扫描,以便您的应用程序可以立即获得添加或更改。有关索引服务器 API 的更多详细信息,请参阅 MSDN 帮助。随附的示例应用程序提供了使用相同 API 的索引服务器的示例管理界面。如果您对本文或该主题有任何意见,请通过 klaus_salchner@hotmail.com 与我联系。我想知道您是否学到了新东西。如果您对该主题或本文有任何疑问,请与我联系。

© . All rights reserved.