Below is my code on click to button. If I will run project using localhost it will open word document very well but when I am going to host this project on IIS and try to open it from another machine by IP it will transfer my page to error message.
Microsoft.Office.Interop.Word.ApplicationClass wordApp = new Microsoft.Office.Interop.Word.ApplicationClass();
object file = "D:\\poForM.docx";
object objFalse = false;
object objTrue = true;
object missing = System.Reflection.Missing.Value;
object emptyData = string.Empty;
object readOnly = false;
object visible = true;
wordApp.Visible = true;
Microsoft.Office.Interop.Word.Document aDoc = wordApp.Documents.Open(ref file, ref missing, ref readOnly, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, visible, ref missing, ref missing, ref missing, ref missing);
aDoc.Activate();
Your code is relying on there being an instance of Microsoft Word on the server (Microsoft.Office.Interop.Word.ApplicationClass)... and having the object file at a specified location on the server.
If I understand correctly what you are trying to do you want to host the Word document on your IIS server but download it onto the local machine for editing..
You can do this by providing a link in your Web page to where the Word doc is, for example:
Open Word Document
Then when you click the link the browser will download the doc and open it in Word (assuming it's installed locally)
Of course if I've completely misunderstood what you're trying to do feel free to comment....
I believe you want to achieve SharePoint alike behaviour where the user can open the file and then save it back to server. Here is a similar thread Possible for Word to edit documents directly off an web server without Sharepoint? . The only bad thing about this solution is that AFAIK it is working only in IE. You can also try new ActiveXObject("Word.Application");instead of the new ActiveXObject("SharePoint.OpenDocuments");
I am using Microsoft Office Interop Word to generate documents using C#. In order for the document generation to work, there should be an entry for the "Microsoft Office Word 97 - 2003 Document" under the Dcom Config Settings as shown below:
The Local Path under the General Tab has a correct path when Microsoft Office is first installed. If I then join the computer to a Domain, and then restart the system with a Domain user, the Local Path becomes blank and the application doesn't generate the documents and gives error.
Even if I join the computer to Domain first and then login with Domain user and then install the Microsoft Office, the Local Path appears correct first and then after a restart, it becomes blank again. While, at the same time, if I login with the Local User, the Path is still there.
What is causing the value of Local Path to go blank?
This all setup is on virtual machines and the word automation works on a domain account as I have seen it working on a physical machine joined to domain.
UPDATE: What my application is doing:
There are 4-5 components in my application.
The first is a VSTO Word AddIn, which integrates with Microsoft Word, where we create new documents that contain some Expressions that are also saved in the database. There are also conditions on the Expressions and they can be nested also. Expressions contain schema elements from XSD files which are saved in database. Once this type of document is created, its WordML is saved in the database. This all is done in VSTO AddIn.
The second is a Web Service which receives an input xml from another component that confirms to the XSD above from which the schema elements were embedded into the expressions in the document created through VSTO addIn. This web service checks for the validations and several other tasks. It then gets the WordML of the corresponding word document from the database and passes it to the Word Interop which using its APIs, iterates through it recursively to replace the schema elements with their actual values from the input xml. This then saves the WordML to a file as word document.
This also attaches a template to the document before saving it. It uses the SaveAs functionality of Word Interop to also save the file as PDF.
UPDATE:
I have again gone through my complete application and came to know that we are doing all things by parsing the Office Open XML (e.g. for feeding the input to the word document), but the only things that we are doing using Word Automation are following:
Using Word Interop to save the generated WordML as one of the Word Format Files.
Exporting the generated WordML to the PDF file.
Merging several WordMLs into a single word document file.
Fetching the XML for it.
All these four codes are shown below with only relevant parts of code:
Microsoft.Office.Interop.Word.Document wordDocument = null;
object templateName = "templateFile.dotm";
wordDocument = this.WordApplication.Documents.Add(ref missing, ref missing, ref missing, ref missing);
wordDocument.Range(ref missing, ref missing).Text = "";
wordDocument.set_AttachedTemplate(ref templateName);
wordDocument = this.WordApplication.Documents.Open(
ref objSourceFilePath, ref oFalse, ref oTrue,
ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing,
ref oMissing);
wordDocument.ExportAsFixedFormat(
strTargetPath,
targetFormat,
paramOpenAfterExport,
paramExportOptimizeFor,
paramExportRange,
paramStartPage,
paramEndPage,
paramExportItem,
paramIncludeDocProps,
paramKeepIRM,
paramCreateBookmarks,
paramDocStructureTags,
paramBitmapMissingFonts,
paramUseISO19005_1,
ref oMissing);
object SaveToFormat = SaveToFormat = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument97;
wordDocument.SaveAs(ref objTargetFilePath, ref SaveToFormat, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
For Merging several files:
Microsoft.Office.Interop.Word.Document doc = null;
Microsoft.Office.Interop.Word.Section section = null;
object sectionBreakNextPage = (object)WdBreakType.wdSectionBreakNextPage;
WordApp.Visible = false;
doc = this.WordApplication.Documents.Add(ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing);
if (doc != null)
{
doc.Activate();
int fileCount = sourceFiles.Length;
String fileName = string.Empty;
for (int fileIndex = 0; fileIndex < fileCount; fileIndex++)
{
fileName = sourceFiles[fileIndex];
if (System.IO.File.Exists(fileName))
{
section = doc.Sections.Last;
//delink the current section's header & footer from previous section's header & footer
section.Headers[WdHeaderFooterIndex.wdHeaderFooterFirstPage].LinkToPrevious = false;
section.Footers[WdHeaderFooterIndex.wdHeaderFooterFirstPage].LinkToPrevious = false;
section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false;
section.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false;
section.Headers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].LinkToPrevious = false;
section.Footers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].LinkToPrevious = false;
section.Range.InsertFile(fileName, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing);
//if it is last iteration, do'nt insert break
if (fileIndex < fileCount - 1)
{
object rangeStart = (object)(section.Range.End - 1);
doc.Range(ref rangeStart, ref paramMissing).InsertBreak(ref sectionBreakNextPage);
}
}
}
doc.SaveAs(ref targetFile, ref wordFormat, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing);
return true;
}
Right now, I am receiving the following error:
The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))
Can this all be done without using the Word Automation?
Instead of trying to fix and deal with that error, I think you should read this and then try another approach to your problem:
(...) Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when run in this environment. (...)
Some of the alternatives recommended in that KB are:
(...) Microsoft strongly recommends a number of alternatives that do not require Office to be installed server-side, and that can perform most common tasks more efficiently and more quickly than Automation. Before you involve Office as a server-side component in your project, consider alternatives.
Most server-side Automation tasks involve document creation or editing. Office 2007 supports new Open XML file formats that let developers create, edit, read, and transform file content on the server side. These file formats use the System.IO.Package.IO namespace in the Microsoft .NET 3.x Framework to edit Office files without using the Office client applications themselves. This is the recommended and supported method for handling changes to Office files from a service. (...)
And
(...) Microsoft provides an SDK for manipulating Open XML file formats from the .NET 3.x Framework. For more information about the SDK and about how to use the SDK to create or edit Open XML files, visit the following Microsoft Developer Network (MSDN) Web sites:
Open XML SDK Documentation
How to: Manipulate Office Open XML Formats Documents
Manipulating Word 2007 Files with the Open XML Object Model (Part 1 of 3)
Manipulating Word 2007 Files with the Open XML Object Model (Part 2 of 3)
Manipulating Word 2007 Files with the Open XML Object Model (Part 3 of 3) (...)
Note, that even if you get your problem fixed, your solution will hardly be stable... In essence what, it seems to be happening is that you messed your registry and it seems that your Word reinstallation is not fixing your registry, and that is problematic.
Based on this, I recommend you to read the above documentation and to try put together a more stable solution using the above alternatives, as Automation of Microsoft Office applications from any unattended, non-interactive client application or component, which is your case, may exhibit unstable behaviors.
UPDATE 1
You have an Hello World example here.
Creating a document with Open XML can be as easy as doing this:
public void HelloWorld(string docName)
{
// Create a Wordprocessing document.
using (WordprocessingDocument package = WordprocessingDocument.Create(docName, WordprocessingDocumentType.Document))
{
// Add a new main document part.
package.AddMainDocumentPart();
// Create the Document DOM.
package.MainDocumentPart.Document =
new Document(
new Body(
new Paragraph(
new Run(
new Text("Hello World!")))));
// Save changes to the main document part.
package.MainDocumentPart.Document.Save();
}
}
Note
I could spent here hours, trying to solve your registry, but as you can see in this article in my blog, those problem are huge headaches, and in your case, even if you find a way to solve it, it will not be a maintainable or either scalable solution, in my opinion of course.
UPDATE 2
According to this, those configurations such as local path are extracted from the registry and are not modifiable:
(...) The General tab provides general information about the application. This tab displays the Application name, type (local server or remote server), and location (local path or remote computer). These settings are not modifiable through the DCOM Config interface.
The General Tab retrieves all of its information from subkeys of the following registry key:
HKEY_CLASSES_ROOT\CLSID{...CLSID...}
where {...CLSID...} is the unique CLSID for the Object Server currently being viewed. (...)
So! Run > regedit > Go to HKEY_CLASSES_ROOT\CLSID, then go to Edit menu and click Find, filter by key and put your ApplicationID there. You should find it this way.
Now after finding the registry entry for your DCOM, expand it, you should see a LocalServer32, the property (Default) holds your Local Path value, try change it the same path as in your new Oracle Virtual Box.
If this works, test if the value hold after restarting and logging in with you Domain User account if it does, great, if not, run a batch to run a .reg file to perform this modification, on every login.
Warning: Nevertheless, this is bad stuff, I strongly, strongly encourage you to go the other way around, this is not the way to do it.
UPDATE 3
Regarding the "MS-WORD AUTOMATION ERROR : "The message filter indicated that the application is busy", you have a very good reply to that problem here. I'll cite a bit of the above link, for further understanding of why that error happens:
(...) That issue is the fact that the Word objects you are calling into do not support multiple threading. Since they are exposed to arbitrary clients via COM, the possibility exists that multiple threads could attempt to simultaneously execute code within the object. To prevent this from happening, will serialize all incoming calls by queuing them up and only allowing one call at a time to execute. This is done by packaging up the details of each call and posting a message to Word. When Word processes, the message, the call will execute on Word's own main thread. The problem with this approach is that if Word is busy doing something else when the call comes in, the caller will have to wait. (...)
About the merging, this tool claims to be capable of merging OpenXML documents, I never used it, but I would give it a try (if I were you).
(...) PowerTools for Open XML contains source code and guidance for accomplishing various common tasks using the Open XML SDK, such as: - High-fidelity conversion of DOCX to HTML/CSS using HtmlConverter.cs; - Merging and splitting DOCX documents using DocumentBuilder.cs; - Merging and splitting PPTX presentations using PresentationBuilder.cs; - Accepting tracked revisions in DOCX documents using RevisionAccepter.cs; - Searching and replacing text in DOCX documents using TextReplacer.cs (...)
Finally to generate PDFs, from your word documents, you can use this tool here.
So as you can see, once more, you can keep dealing with Word Automation (Dark Side), or you can join the Light Side of the Force :).
I am looking for a .net winforms component that can compare two formatted documents (in .doc, .docx, .html, .rtf, any one of them will do) and visually spot changes. We prefer to see the changes as MS Word does when it shows the changes in its track changes mode
We expect short documents of only few pages long and not much editing (few words changed, a paragraph added/deleted, etc)
Are you aware of such a component that you can recommend free or otherwise
Thank you,
Kemal
Following code will compare two word doc and save the merging of changes in third doc.
Add reference of Microsoft Word 12.0 Object Library
using Microsoft.Office;
public static void comp()
{
object missing = System.Reflection.Missing.Value;
//create a readonly variable of object type and assign it to false.
object readonlyobj = false;
object filename = "C:\\romil1.docx";
//create a word application object for processing the word file.
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
//create a word document object and open the above file..
Microsoft.Office.Interop.Word.Document doc = app.Documents.Open(
ref filename, ref missing, ref readonlyobj, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
string filenm = "C:\\romil2.docx";
object filenm3 = "C:\\romil3.docx";
doc.TrackRevisions = true;
doc.ShowRevisions = false;
doc.PrintRevisions = true;
doc.Compare(filenm);
doc.Close(Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges);
app.ActiveDocument.SaveAs(ref filenm3, ref missing, ref readonlyobj, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
app.Quit(Microsoft.Office.Interop.Word.WdSaveOptions.wdSaveChanges);
MessageBox.Show("Process complete");
}
You can use one of the following libraries to manipulate Word document and build the document comparison method yourself.
Microsoft Interop (Office installation required)
OpenXML SDK
Aspose.Words for .NET
Since this question is old, now there are more solutions available.
Groupdocs compare
Document Comparison by Aspose.Words for .NET
I work with Aspose as Developer Evangelist.
I have some word documents with objects inside them. I am testing one that has 3 pdf-files (the wordApp.Selection.InlineShapes.Count matches this), But else I have trouble getting any info from the objects. How do I save it to a disk? Any help is appreciated, because the inlineShape.OLEFormat.IconLabel is an empty string in all 3 instances.
var wordApp = new Word.Application();
object confirmConversions = false;
object readOnly = true;
object missing = Type.Missing;
this.document = wordApp.Documents.Open(
ref fn, ref confirmConversions, ref readOnly,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing);
string applicationName = null;
foreach (Microsoft.Office.Interop.Word.InlineShape inlineShape in this.document.InlineShapes)
{
applicationName = inlineShape.OLEFormat.IconLabel;
}
Here's a snippet from a post which I found here which explains the approach you need to take in order to do this:
Any file that can be embedded in a
document as an OLE object can be
extracted. However, we may not be
able to provide you with a simple code
example if the technology doesn't
belong to us (such as Adobe Acrobat
files).
What we are doing with Office objects
is activating the object and then
taking advantage of the exposed
IDispatch interface so that we can use
COM interop to communicate directly
with the object's programming model.
As it happens, the Office applications
generally expose SaveAs methods that
we can call to save the files in
question. Going through the Office
programming model in this fashion is a
handy shortcut that enables saving
embedded objects with very little
code.
I suspect that Adobe Acrobat exposes a
similar programming model because
there is an Adobe Acrobat Type
Library. You will have to browse the
Type Library to see if it exposes some
sort of Save or Save as method. If it
does, you can add it as a reference to
your project (via the COM References
tab of the Add Reference dialog in
Visual Studio) and take a similar
approach as Ji suggests in his post
above.
(continues...)
If you are open to using 3rd party controls, this can be easily accomplished using Aspose.Words:
Aspose.Words.Document d = new Document(#"C:\users\john\desktop\embeddedPDF.docx");
foreach (Aspose.Words.Drawing.Shape shp in d.GetChildNodes(NodeType.Shape, true))
{
shp.OleFormat.Save(#"C:\Temp\testoutput.pdf");
}