[
Advertise | Submit Code | About us | Contact us | Link us
]
Go!
Membership Services
Login
Register

Home
C# General

General

C# Language

Design & Architecture

Algorithms

Database

Security

Active Directory

COM Interop

Remoting
C# Windows Forms

General

Combo and List boxes

Miscellaneous Controls

Button Controls

Edit Controls
Cutting Edge

ASP.NET 2.0

Visual Studio 2005

Windows Longhorn

SQL Server 2005
C# Multimedia and GDI+

General

DirectX

GDI+

Audio
Internet & Web

General

Images and multimedia

Database

Utilities

Security

ASP.NET Controls

Design and Architecture

Webservices
.NET

General

Design & Architecture

Algorithms

Database

Security

Active Directory

COM Interop

Remoting

ADO.NET

XML.NET

Tools

Enterprise

IDE
Visual Basic .NET

VB.NET General

VB.NET Controls
General Reading

.NET Books Review

Product Showcase

Book Chapters

Business Design & Strategy
Community

Discuss

Job Board

Discussion

CodeXchange
DeveloperLand

Advertise

Submit Code

About us

Contact us

Link us
Miscellaneous

Favorite Links

Downloads

Programming Sites

Top Stories
Regular Expressions

E-Mail

Date/Time
Home > C# General > General
Administrate Indexing Server from within your application
Posted by on Friday, July 01, 2005 (EST)

Describes in detail how you can programmatically administrate Indexing Server, for example create a new Indexing catalog and then add folders to be indexed by this catalog.

This article has been viewed: 5,731 times
Technology: General.

IndexingServerAdmin_VS_2003.zip (87.81 KB)
IndexingServerAdmin_VS_2005_Beta2.zip (91.84 KB)

Contents

Introduction

You can leverage Microsoft Indexing Server to provide powerful search capabilities within your application. Indexing Server can be used to index files on your local or network file system as well as files of your local web site. You can then query the Indexing catalog using a standard SQL syntax. The following [^] article describes in details how you can create and configure your own Indexing catalog and then search it from within your application. This article concentrates on how you can programmatically administrate Indexing Server, for example create a new Indexing catalog and then add folders to be indexed by this catalog.

Top Go to Table of Contents

The Indexing Service Administration API

Current versions of the .NET framework do not provide any types to programmatically administrate the Indexing Server. But Indexing Server provides a COM based API you can use. Add a reference to the "Indexing Service Administration Type Library 1.0" which you find under the COM tab of the "Add Reference" dialog. This references the "ciodm.dll" in the windows\system32 folder. Next import the namespace "CIODMLib" which will give you access to three types:

  • AdminIndexServerClass [^] - This type is used to administrate the Indexing Server itself. It allows to create or remove catalogs, start or stop the Indexing service, etc.
  • CatAdmClass [^] - This type provides access to an existing Indexing catalog. You can add or remove search scopes, start or stop the catalog, etc.
  • ScopeAdm [^] - This type provides access to a search scope. You can set logon information for the scope, start a full or incremental scan, etc.

Top Go to Table of Contents

How to retrieve the list of Indexing catalogs?

Indexing Server can have many Indexing catalogs and your application always tells Indexing Server which catalog to search. You can use the AdminIndexServerClass type to enumerate all defined Indexing catalogs. First you need to create an instance of the type AdminIndexServerClass. Then you call FindFirstCatalog() to find the first catalog in the list. It returns true if it finds a catalog otherwise false. To find the next catalog you call FindNextCatalog() which again returns true when it found another catalog or otherwise false. As the example below shows you first call FindFirstCatalog() and then in a loop FindNextCatalog() till one of them return false. Each time you then call GetCatalog() to get a reference to the current catalog in the list. This returns an object of the type object and you need to query for the appropriate interface on that object. Simple type casting will not work as you are working with COM objects. You need to use the "as" keyword followed by the interface you are looking for. Underneath this will query for the appropriate interface on that COM object and return null if not present or a reference to the interface. The interface you are looking for is the ICatAdm interface which provides you access to the catalog itself. The CatAdm type itself implements also the ICatAdm interface.

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);
}

As the example above shows the ICatAdm interface provides a number of properties about the catalog. You can obtain the name, the location, if the catalog is up to date or not, etc. The example above adds each found catalog to a list view.

Top Go to Table of Contents

How to start, stop, pause or continue Indexing Server?

The AdminIndexServerClass provides four methods to start, stop, pause and continue the Indexing service. It also provides methods to find out if the service is running or paused:

  • Start() - starts the Indexing service
  • Stop() - stops the Indexing service
  • Pause() - pauses the Indexing service
  • Continue() - continues a paused Indexing service
  • IsRunning() - returns true if the Indexing service is running
  • IsPaused() - returns true if the Indexing service is paused

Top Go to Table of Contents

How to add or remove an Indexing catalog?

You can add a new catalog with the method AddCatalog(). You need to pass along the name of the new catalog as well as the folder location where the catalog will be created. You need to restart the Indexing service before you can use a newly created catalog. The following example shows a dialog so the user can enter the name and location of a new catalog. Next it calls AddCatalog and then asks the user whether to restart the Indexing service so the catalog becomes usable. Finally it calls the method shown above to re-query the list of defined catalogs - 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);
 }
}

You can call RemoveCatalog() to remove an existing catalog. You need to pass along the name of the catalog. You also need to first stop the Indexing service to be able to remove any catalog. The example below asks if the user wants to delete the currently selected catalog. If the user confirms it stops the Indexing services, deletes the catalog and then starts the Indexing service again. Afterwards it calls again FillCatalogList() to refresh the list of catalogs in the list view.

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);
 }
}

Top Go to Table of Contents

How to retrieve the list of search scopes of a catalog?

Each catalog has search scopes, which are the folders which are included in the catalog. A search scope can be inclusive (by default) or exclusive, meaning this folder will not be included in the catalog. With exclusive you can define sub-folders which should be excluded by this catalog. Listing all search scopes of catalog works very similar as listing all catalogs of the Indexing Server. First obtain a reference to the catalog itself by calling the method GetCatalogByName() on an instance of the type AdminIndexServerClass. This returns again an object of the type object and you need to query for the ICatAdm interface using the "as" keyword.

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

Next you call FindFirstScope() on the ICatAdm interface to get the first search scope which returns true if one is found otherwise false. You call FindNextScope() on the ICatAdm interface to find subsequent search scopes which again returns true when one is found otherwise false. You do this again in a loop till one returns false. Each time you call GetScope() to obtain a reference to the current search scope. This returns again an object of the type object and you query for the IScopeAdm interface via the "as" keyword. That interface then provides a list of properties about the search scope itself:

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);
}

The example above adds all search scopes of a catalog to a list view. This includes the path of the search scope and whether it is exclusive. The VirtualScope is only set if this catalog indexes a web site.

Top Go to Table of Contents

How to start, stop, pause or continue a catalog?

You can also start, stop, pause or continue an individual catalog itself. First you need to get a reference to the catalog by calling GetCatalogByName on an instance of the type AdminIndexServerClass. Then you query again for the ICatAdm interface. The ICatAdm interface also provides methods to find out if the catalog is running or paused:

  • StartCatalog() - starts the Indexing catalog
  • StopCatalog() - stops the Indexing catalog
  • PauseCatalog() - pauses the Indexing catalog
  • ContinueCatlog() - continues a paused Indexing catalog
  • IsCatalogRunning() - returns true if the Indexing catalog is running
  • IsCatalogPaused() - returns true if the Indexing catalog is paused

Top Go to Table of Contents

How to add or remove a search scope to a catalog?

First you need to obtain again a reference to the catalog and then call the method AddScope(). You pass along the folder to index and true if the search scope is exclusive or false if it is inclusive. The example below shows first a dialog so the user can enter the folder of the search scope and select if it is exclusive or inclusive. Next it gets the name of the currently selected catalog, obtains the catalog object for it and then adds the search scope by calling AddScope() on the catalog object. It then asks the user if a full scan for it should be performed. In that case it gets a reference to the newly created search scope by calling GetScopeByPath() on the catalog object and then calls Rescan() on it passing along true for a full scan. Finally it calls the method FillScopeList() to refresh the list of search scopes in the list view.

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);
 }
}

Adding or removing search scopes does not require stopping or restarting the catalog service. To remove a search scope you call the method RemoveScope() on the catalog object and pass along the path of the search scope. The example below asks if the user wants to delete the currently selected search scope. If the user confirms it deletes the search scope and afterwards it calls again FillScopeList() to refresh the list of search scopes in the list view.

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);
 }
}

Top Go to Table of Contents

Summary

The administrative API of Indexing Server is very simple. The AdminIndexServerClass type gives you full control over the Indexing Server itself. The ICatAdm interface and CatAdm type provide full control over each catalog. The IScopeAdm interface and ScopeAdm type provide full control over each search scope. This makes it very easy for you to add new catalogs and search scopes or remove existing catalogs and search scopes programmatically. You have also the ability to force a full or partial scan of search scopes so that additions or changes are available to your application instantly. Refer to the MSDN help [^] for more details about the Indexing Server API. The enclosed sample application provides a sample administrative interface to Indexing Server using the very same API. If you have comments on this article or this topic, please contact me @ klaus_salchner@hotmail.com [^]. I want to hear if you learned something new. Contact me if you have questions about this topic or article.

Top Go to Table of Contents

About Klaus Salchner

Klaus Salchner has worked for 14 years in the industry, nine years in Europe and another five years in North America. As a Senior Enterprise Architect with solid experience in enterprise software development, Klaus spends considerable time on performance, scalability, availability, maintainability, globalization/localization and security. The projects he has been involved in are used by more than a million users in 50 countries on three continents.

Klaus calls Vancouver, British Columbia his home at the moment. His next big goal is doing the New York marathon in 2005. Klaus is interested in guest speaking opportunities or as an author for .NET magazines or Web sites. He can be contacted at klaus_salchner@hotmail.com or http://www.enterprise-minds.com.

Enterprise application architecture and design consulting services are available. If you want to hear more about it contact me! Involve me in your projects and I will make a difference.

Click here if you want to know more about .

Other articles that may interest you

  • Write a Word Add-In – Part 0
  • Write a Word Add-In – Part I
  • Lengthy Operations on Single Thread in .NET Application
  • Learning Draughts
  • Exceptions and Performance
  • Average Rating :

    Discussion Forums
    Got a programming related question? Hopefully someone has the answer... Want to help out other developers? Visit our discussion forums.

    Sponsored by:

    New Articles

  • Exceptions and Performance
    Almost every time exceptions are mentioned in mailing lists and newsgroups, people say they're really expensive.Let's examine that claim, shall we?

  • Creating multilingual websites - Part 1
    Extend the existing globalization capabilities of .NET to create flexible and powerful multilingual web sites. First, create a custom ResourceManager, and then create custom localized-capable server controls to easily deploy multilingual functionality.

  • Parameter passing in C#
    Many people have become fairly confused about how parameters are passed in C#, particularly with regard to reference types. This page should help to clear up some of that confusion

  • Most Popular Articles

  • LDAP, IIS and WinNT Directory Services
    This article explains how to use .NET Directory Services to retrieve and search directory objects, create new directory objects and edit or delete existing directory objects. Describes Active Directory Application Mode (ADAM) and how to use the IIS, WinNT and LDAP directory (ADSI) provider.

  • An in-depth look at WMI and instrumentation, Part II
    WMI stands for Windows Management Instrumentation and, as the name indicates, is about managing your IT infrastructure this article is the second part of a two-part series.

  • An in-depth look at WMI and instrumentation, Part I
    WMI stands for Windows Management Instrumentation and, as the name indicates, is about managing your IT infrastructure this article provides an in-depth look at WMI and MOM 2005

  • New Books

  • Murach's ASP.NET 2.0 Upgrader's Guide: VB Edition
    What’s new and how to use it! That’s what this book delivers if you’re a VB developer who’s interested in upgrading from ASP.NET 1.x to ASP.NET 2.0.

  • C# in easy steps
    Learn to program with Microsoft’s premier programming language. No previous programming knowledge is assumed. With numerous easy-to-follow examples, this title explains the essentials of object-oriented programming with C#.

  • Murach's ASP.NET web programming with VB.NET
    Murach's ASP.NET web programming with VB.NET by Doug Lowe and Anne Prince is a in depth training and reference book for ASP.NET programming using VB.NET. The book builds upon Murach's previous books and covers more advanced concepts for programming ASP.NET pages.

  • Got Code?

    if you have any article , source code , or anything else you'd like to share with this community that you think others might find useful, please submit it here and we will gladly make it available on this site. submit@developerland.com.
    Partners

    All articles are copyrighted by their individual authors unless otherwise specified , everything else Copyright ©2004-2006 DeveloperLand