Reputation: 31
I am making a search module(windows form in C#). Its working fine for .txt files but I need to search for the word in the Word document too. i tried using Microsoft.Office.Interop.Word; and the code was as below
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document docOpen = app.Documents.Open(flname);
StreamReader srObj = new StreamReader(flname);
string read = srObj.ReadToEnd();
if (read.Contains(txtWordInput.Text)) // searching for the input word in the file
{
count1++;
lbSearchList.Visible = true;
lbSearchList.Items.Add(flname);
}
srObj.Close();
app.Documents.Close();
but it at run time it gave an error that the doc file is already open hence is not accessible even when the document wasn't open.
then i tried working simply with stream reader, it worked and did read the file but the data read was some random symbols and not what was actually written inside. Due to this the if (read.Contains(txtWordInput.Text)) statement was unable to search for the word.
please help me with the code as to how to successfully search for the word in the word document.
Upvotes: 3
Views: 11113
Reputation: 2509
With that code it looks like the error was correct. You tried opening the document twice. First with the "app.Documents.Open(flname)" line and then again right after by creating a StreamReader object with the same file name. Also a word document is not a text file, but actually a zip file with other files inside it. So if you just try to use a StreamReader to read the file as text, you'll get exactly what you got...a bunch of symbols.
Use this method to simply read text and search for a specific string inside a Word file. Also make sure to have the correct using statement.
using Word = Microsoft.Office.Interop.Word;
public static Boolean CheckWordDocumentForString(String documentLocation, String stringToSearchFor, Boolean caseSensitive = true)
{
// Create an application object if the passed in object is null
Word.Application winword = new Word.Application();
// Use the application object to open our word document in ReadOnly mode
Word.Document wordDoc = winword.Documents.Open(documentLocation, ReadOnly: true);
// Search for our string in the document
Boolean result;
if (caseSensitive)
result = wordDoc.Content.Text.IndexOf(stringToSearchFor) >= 0;
else
result = wordDoc.Content.Text.IndexOf(stringToSearchFor, StringComparison.CurrentCultureIgnoreCase) >= 0;
// Close the document and the application since we're done searching
wordDoc.Close();
winword.Quit();
return result;
}
Then to use the method, just call it like any other static method.
MyClass.CheckWordDocumentForString(@"C:\Users\CoolDude\Documents\MyWordDoc.docx", "memory", false);
Using your code it would be something more like this:
if (MyClass.CheckWordDocumentForString(flname, txtWordInput.Text, false))
{
// Do something if it is found
}
else
{
// Do something if it is not found
}
Upvotes: 2
Reputation: 3681
I think you can use Find function of the Interop library instead of stream. You can use the following function to check whether the desired text exists in word document or not.
protected bool FindTextInWord(object text, string flname)
{
object matchCase = false;
object matchWholeWord = true;
object matchWildCards = false;
object matchSoundsLike = false;
object matchAllWordForms = false;
object forward = true;
object format = false;
object matchKashida = false;
object matchDiacritics = false;
object matchAlefHamza = false;
object matchControl = false;
object read_only = false;
object visible = true;
object replace = 2;
object wrap = 1;
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document docOpen = app.Documents.Open(flname);
bool val = false;
try
{
val = app.Selection.Find.Execute(ref text, ref matchCase, ref matchWholeWord,
ref matchWildCards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap,
ref format, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
finally
{
app.Documents.Close();
}
return val;
}
You can check the details of each parameter in the following link http://msdn.microsoft.com/en-us/library/office/ff193977(v=office.15).aspx
You can call the function as below
FindTextInWord((object)"Proposal","your file name here");
Upvotes: 0
Reputation: 1
My two cents is that the srObj is completely irrelevant in this context, what you have done is bypass and ignore your docOpen and app objects, u create them but they never get used. I had a brief look at the API and I could tell that there are methods for getting character listings and collections of words. What I think you might need to do is grab a collection of the words from your docOpen property and sift through them.
You could use the properties docOpen.Words to get or set a collection of words, or docOpen.Text to get or set all the text as a string.
As an example
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document docOpen = app.Documents.Open(flname);
string read = docOpen.Text
if(read.Contains(txtWordInput.Text)) {
count1++;
lbSearchList.Visible = true;
lbSearchList.Items.Add(flname);
}
app.Documents.Close();
I hope this helps.
Upvotes: 0