/* The question arises here: why didn't I just use content.Text to acquire the content. It's because it returns a different text * from what the setRange() function works on (and using setRange later is unavoidable). You might be asking then, why not use * the TextRetrievalMode and ViewType properties of the content, but turns out they can't give you the same text that setRange() * is working on either. So unfortunately the ugly solution here seems unavoidable. The Characters array of content is also not usable. * Sadly, this solution produces a noticable slowdown with long documents, and I couldn't find a better solution with the Word API. */ private string GetFullTextOfDocument(Word.Range content) { int length = content.End; StringBuilder sb = new StringBuilder(content.End); for (int i = 0; i < length; i++) { content.SetRange(i, i + 1); /* In certain cases a null is returned instead of a character (for example at the place of the special character representing * the starting point of a Hyperlink block, but in other simpler cases too. There is no information about these in the * documentation, so I couldn't write a state machine for it. ) But if I didn't take these into consideration then it woulddn't * be aligned correctly with setRange(), so I have to substitute it with something. Later it turned out that in some cases * there are two characters returned by setRange(i, i+1): The '\r\a' symbol representing the end of a cell takes up two character * spaces as a string, but only one in the Range logic. */ if (content.Text == null) { sb.Append(' '); } else { if (content.Text.Length == 1) sb.Append(content.Text); else sb.Append(content.Text[0]); } } return sb.ToString(); }