/*--------------------------------------------------------------------------
Project : Word Automation
Component : Automation
Module : Word Automation
Description : This class is used for word automation. Aupport almost all the
versions. Only tested with 2000 and 2003
Log
Date Author Comment
16-Aug-2007 Prathapachandran Created
--------------------------------------------------------------------------*/
using System;
using System.IO;
using System.Reflection;
using System.Collections;
namespace Automation
{
/// <summary>
/// Cass for automating word.
/// </summary>
public class WordAutomation
{
#region Member Functions
/// <summary>
/// Constructor
/// </summary>
public WordAutomation()
{
}
/// <summary>
/// Function to create a word document.
/// </summary>
/// <param name="fileName">Name of word</param>
/// <param name="wordApplication">Word application</param>
/// <param name="isReadonly">open mode</param>
/// <returns>If word document exist, return word doc object
/// else return null</returns>
public object CreateWordDoc(object fileName,
object wordApplication, bool isReadonly)
{
object wordDocument = null;
if (File.Exists(fileName.ToString()) && wordApplication != null)
{
object readOnly = isReadonly;
object isVisible = true;
object missing = System.Reflection.Missing.Value;
object wordDocuments = GetProperty("Documents",wordApplication);
// Open a given Word document.
wordDocument = InvokeMember("Open",wordDocuments,
new object[]{fileName, missing,
isReadonly, missing, missing, missing,
missing, missing, missing, missing,
missing, isVisible});
}
return wordDocument;
}
/// <summary>
/// Function to create a word application
/// </summary>
/// <returns>Returns a word application</returns>
public object CreateWordApplication()
{
string message = "Failed to create word application. Check whether"
+ " word installation is correct.";
Type wordType = Type.GetTypeFromProgID("Word.Application");
if (wordType == null)
{
throw new Exception(message);
}
object wordApplication = Activator.CreateInstance(wordType);
if (wordApplication == null)
{
throw new Exception(message);
}
return wordApplication;
}
/// <summary>
/// Function to close a word document.
/// </summary>
/// <param name="wordDocument">Document Object to close</param>
/// <param name="canSaveChange">Need to save changes or not</param>
/// <returns>True if successfully closed.</returns>
public bool CloseWordDoc(object wordDocument, bool canSaveChange)
{
bool isSuccess = false;
if (wordDocument != null)
{
object saveChanges = null;
if (canSaveChange)
{
saveChanges = -1; // Save Changes
}
else
{
saveChanges = 0; // No changes
}
InvokeMember("Close",wordDocument,new object[]{saveChanges});
isSuccess = true;
}
return isSuccess;
}
/// <summary>
/// Function to close word application
/// </summary>
/// <param name="wordApplication">Word application to close</param>
/// <returns>True if successfully closed</returns>
public bool CloseWordApp(object wordApplication)
{
bool isSuccess = false;
if (wordApplication != null)
{
object saveChanges = -1; // Save changes
InvokeMember("Quit",wordApplication,new object[]{saveChanges});
isSuccess = true;
}
return isSuccess;
}
/// <summary>
/// Function to get the word count from the document. Entire word should
/// match.
/// </summary>
/// <param name="wordDoc">Document to search</param>
/// <param name="word">Word to search</param>
/// <returns>Count of the word</returns>
public int GetWordCount(object wordDoc, string word)
{
int count = 0;
do
{
if (wordDoc == null)
{
break;
}
if (word.Trim().Length == 0)
{
break;
}
InvokeMember("Activate",wordDoc);
object content = GetProperty("Content",wordDoc);
// Get the count from direct text inside the document.
count+= GetCountFromRange(
content,wordDoc,word);
object comments = GetProperty("Comments",wordDoc);
object count1 = GetProperty("Count", comments);
int rangeCount = (int)count1;
for(int i = 1; i <= rangeCount;)
{
object comment = InvokeMember("Item",
comments, new object[] { i });
object range = GetProperty("Range", comment);
count+= GetCountFromRange(
range,wordDoc,word);
break;
}
object sections = GetProperty("Sections",wordDoc);
object last = GetProperty("Last",sections);
object headers = GetProperty("Headers",last);
rangeCount = (int)GetProperty("Count", headers);
for (int i = 1; i <= rangeCount; i++)
{
object header = InvokeMember("Item",
headers, new object[] { i });
object range = GetProperty("Range", header);
count+= GetCountFromRange(
range,wordDoc,word);
}
object footers = GetProperty("Footers",last);
rangeCount = (int)GetProperty("Count", footers);
for (int i = 1; i <= rangeCount; i++)
{
object footer = InvokeMember("Item",
footers, new object[] { i });
object range = GetProperty("Range", footer);
count+= GetCountFromRange(
range,wordDoc,word);
}
object shapes = GetProperty("Shapes",wordDoc);
rangeCount = (int)GetProperty("Count", shapes);
for (int i = 1; i <= rangeCount; i++)
{
object shape = InvokeMember("Item",
shapes, new object[] { i });
object textFrame = GetProperty("TextFrame",shape);
int hasText = (int)GetProperty("HasText",textFrame);
if (hasText < 0)
{
object range = GetProperty("TextRange", textFrame);
count+= GetCountFromRange(
range,wordDoc,word);
}
}
}
while(false);
return count;
}
/// <summary>
/// Function to get word count from a given range.
/// </summary>
/// <param name="range">Range</param>
/// <param name="wordDocument">Document to search</param>
/// <param name="word">Word to search</param>
/// <returns>Count of words</returns>
private int GetCountFromRange(
object range, object wordDocument,string word)
{
int count = 0;
object missing = System.Reflection.Missing.Value;
object matchAllWord = true;
object item = 1; // Goto Page
object whichItem = 1;// First page
InvokeMember("GoTo",wordDocument,new object[]{item, whichItem});
object find = GetProperty("Find",range);
InvokeMember("ClearFormatting",find);
SetProperty("Forward",find,true);
SetProperty("Text",find,word);
SetProperty("MatchWholeWord",find,true);
InvokeMember("Execute",find);
bool found = (bool)GetProperty("Found",find);
while (found)
{
++count;
InvokeMember("Execute",find);
found = (bool)GetProperty("Found",find);
}
return count;
}
/// <summary>
/// Function to find and replace a given text.
/// </summary>
/// <param name="wordDoc">Word Document</param>
/// <param name="findText">Text for finding</param>
/// <param name="replaceText">Text for replacing</param>
/// <param name="wordApplication">Word Application</param>
/// <returns>True if successfully replaced.</returns>
public bool FindReplace(object wordDoc,object wordApplication,
string findText, string replaceText)
{
bool isSuccess = false;
do
{
if (wordDoc == null)
{
break;
}
if (wordApplication == null)
{
break;
}
if (replaceText.Trim().Length == 0)
{
break;
}
if (findText.Trim().Length == 0)
{
break;
}
object content = GetProperty("Content",wordDoc);
ReplaceRange(content,wordDoc,wordApplication,findText,replaceText);
object comments = GetProperty("Comments",wordDoc);
object count1 = GetProperty("Count", comments);
int rangeCount = (int)count1;
for(int i = 1; i <= rangeCount; i++)
{
object comment = InvokeMember("Item",
comments, new object[] { i });
object range = GetProperty("Range", comment);
ReplaceRange(range,wordDoc,wordApplication,findText,replaceText);
}
object sections = GetProperty("Sections",wordDoc);
object last = GetProperty("Last",sections);
object headers = GetProperty("Headers",last);
rangeCount = (int)GetProperty("Count", headers);
for (int i = 1; i <= rangeCount; i++)
{
object header = InvokeMember("Item",
headers, new object[] { i });
object range = GetProperty("Range", header);
ReplaceRange(range,wordDoc,wordApplication,findText,replaceText);
}
object footers = GetProperty("Footers",last);
rangeCount = (int)GetProperty("Count", footers);
for (int i = 1; i <= rangeCount; i++)
{
object footer = InvokeMember("Item",
footers, new object[] { i });
object range = GetProperty("Range", footer);
ReplaceRange(range,wordDoc,wordApplication,findText,replaceText);
}
object shapes = GetProperty("Shapes",wordDoc);
rangeCount = (int)GetProperty("Count", shapes);
for (int i = 1; i <= rangeCount; i++)
{
object shape = InvokeMember("Item",
shapes, new object[] { i });
object textFrame = GetProperty("TextFrame",shape);
int hasText = (int)GetProperty("HasText",textFrame);
if (hasText < 0)
{
object range = GetProperty("TextRange", textFrame);
ReplaceRange(range,wordDoc,wordApplication,findText,replaceText);
}
}
isSuccess = true;
}
while(false);
return isSuccess;
}
/// <summary>
/// Replace a word with in a range.
/// </summary>
/// <param name="range">Range to replace</param>
/// <param name="wordDocument">Document to replace</param>
/// <param name="wordApp">Word Application</param>
/// <param name="findText">Text to find</param>
/// <param name="replaceText">Text to replace</param>
private void ReplaceRange(object range,
object wordDocument,
object wordApp,
string findText, string replaceText)
{
object missing = System.Reflection.Missing.Value;
InvokeMember("Activate",wordDocument);
object item = 1;
object whichItem = 1;
InvokeMember("GoTo",wordDocument,new object[]{item, whichItem});
object replaceAll = 2;
object matchAllWord = true;
object find = GetProperty("Find",range);
InvokeMember("ClearFormatting",find);
object replacement = GetProperty("Replacement",find);
InvokeMember("ClearFormatting",replacement);
InvokeMember("Execute",find,
new object[]{findText,false,true,
missing,missing,missing,true,missing,missing
,replaceText,replaceAll});
}
/// <summary>
/// Invoke a member from an instance
/// </summary>
/// <param name="method">Method name to invoke</param>
/// <param name="instance">Instance that method includes</param>
/// <param name="parameters">Parameters to the function</param>
/// <returns>object that returns from the function</returns>
private object InvokeMember(string method, object instance,
object[] parameters)
{
Type type = instance.GetType();
return type.InvokeMember(method,
BindingFlags.InvokeMethod,null,instance,parameters);
}
/// <summary>
/// Invoke a member from an instance
/// </summary>
/// <param name="method">Method name to invoke</param>
/// <param name="instance">Instance that method includes</param>
/// <returns>object that returns from the function</returns>
private object InvokeMember(string method, object instance)
{
Type type = instance.GetType();
return type.InvokeMember(method,
BindingFlags.InvokeMethod,null,instance,new object[]{});
}
/// <summary>
/// Function to get the property from a class
/// </summary>
/// <param name="propertyName">Name of property to access</param>
/// <param name="instance">Instance that property includes</param>
/// <returns>Property Value</returns>
private object GetProperty(string propertyName, object instance)
{
Type type = instance.GetType();
return type.InvokeMember(propertyName,
BindingFlags.GetProperty,null,instance,new object[]{});
}
/// <summary>
/// Function to set the property value
/// </summary>
/// <param name="propertyName">Name of property to set</param>
/// <param name="instance">Instance that property includes</param>
/// <param name="value">Value to set</param>
private void SetProperty(string propertyName,object instance, object value)
{
Type type = instance.GetType();
type.InvokeMember(
propertyName,BindingFlags.SetProperty,
null,instance,new object[]{ value} );
}
#endregion
}
}