我有一个WinForms应用程序,我使用Word Automation通过模板构建文档,然后将它们保存到数据库中。创建文档后,我从数据库中检索文档,将其写入临时目录中的文件系统,然后使用Word Interop服务打开文档。
已加载文档列表,用户只能打开每个文档的1个实例,但可以同时打开多个不同的文档。打开1个文档时打开,保存和关闭没有任何问题,但是,当他们同时打开多个文档时,关闭我的任何Word实例时出现以下错误:
The file is in use by another application or user. (C:\...\Templates\Normal.dotm)
This error is commonly encountered when a read lock is set on the file that you are attempting to open.
我使用以下代码打开文档并处理BeforeDocumentClosed事件:
public void OpenDocument(string filePath, Protocol protocol, string docTitle, byte[] document)
{
_protocol = protocol;
documentTitle = docTitle;
_path = filePath;
if (!_wordDocuments.ContainsKey(_path))
{
FileUtility.WriteToFileSystem(filePath, document);
Word.Application wordApplication = new Word.Application();
wordApplication.DocumentBeforeClose += WordApplicationDocumentBeforeClose;
wordApplication.Documents.Open(_path);
_wordDocuments.Add(_path, wordApplication);
}
_wordApplication = _wordDocuments[_path];
_currentWordDocument = _wordApplication.ActiveDocument;
ShowWordApplication();
}
public void ShowWordApplication()
{
if (_wordApplication != null)
{
_wordApplication.Visible = true;
_wordApplication.Activate();
_wordApplication.ActiveWindow.SetFocus();
}
}
private void WordApplicationDocumentBeforeClose(Document doc, ref bool cancel)
{
if (!_currentWordDocument.Saved)
{
DialogResult dr = MessageHandler.ShowConfirmationYnc(String.Format(Strings.DocumentNotSavedMsg, _documentTitle), Strings.DocumentNotSavedCaption);
switch (dr)
{
case DialogResult.Yes:
SaveDocument(_path);
break;
case DialogResult.Cancel:
cancel = true;
return;
}
}
try
{
if (_currentWordDocument != null)
_currentWordDocument.Close();
}
finally
{
Cleanup();
}
}
public void Cleanup()
{
if (_currentWordDocument != null)
while(Marshal.ReleaseComObject(_currentWordDocument) > 0);
if (_wordApplication != null)
{
_wordApplication.Quit();
while (Marshal.ReleaseComObject(_wordApplication) > 0);
_wordDocuments.Remove(_path);
}
}
有没有人发现我正在做的任何错误,允许同时打开多个文件?我是Word Automation和Word Interop服务的新手,所以任何建议都表示赞赏。感谢。
答案 0 :(得分:9)
我通过这篇MSDN文章找到了解决方案:http://support.microsoft.com/kb/285885
您需要在调用Application.Quit();
之前执行此操作_wordApplication.NormalTemplate.Saved = true;
这可以防止Word尝试保存Normal.dotm模板。我希望这有助于其他人。
答案 1 :(得分:2)
我在C#doc2pdf应用程序中使用过Word。在关闭doc之前,请像这样设置保存选项:
object saveOption = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
oDoc.Close(ref saveOption, ref oMissing, ref oMissing);
oWord.Quit(ref saveOption, ref oMissing, ref oMissing);
答案 2 :(得分:1)
我的应用程序中有帮助链接,并希望将特定的文档doc打开到特定的书签。如果文档已经打开,则不应再次打开它。如果Word已经打开,则不应该打开Word的新实例。
此代码对我有用:
object filename = @"C:\Documents and Settings\blah\My Documents\chapters.docx";
object confirmConversions = false;
object readOnly = true;
object visible = true;
object missing = Type.Missing;
Application wordApp;
object word;
try
{
word = System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
}
catch (COMException)
{
Type type = Type.GetTypeFromProgID("Word.Application");
word = System.Activator.CreateInstance(type);
}
wordApp = (Application) word;
wordApp.Visible = true;
Console.WriteLine("There are {0} documents open.", wordApp.Documents.Count);
var wordDoc = wordApp.Documents.Open(ref filename, ref confirmConversions, ref readOnly, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref visible,
ref missing, ref missing, ref missing, ref missing);
wordApp.Activate();
object bookmarkName = "Chapter2";
if (wordDoc.Bookmarks.Exists(bookmarkName.ToString()))
{
var bookmark = wordDoc.Bookmarks.get_Item(bookmarkName);
bookmark.Select();
}
答案 3 :(得分:0)
请记住代码:
Word.Application wordApplication = new Word.Application();
总是会启动一个新的Word实例,即使已经加载了一个实例。
通常情况下,最好检查一个已加载的实例(通过GETOBJECT)并在有一个实例时使用它,并且只在需要时启动一个新实例。