Word Automation - 文件正在被其他应用程序或用户使用
我有一个 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 服务还很陌生,因此我们将不胜感激。谢谢。
I have a WinForms application where I am using Word Automation to build documents via a template, and then save them to the database. After the document is created, I retrieve the document from the database, write it to the file system in a temp directory, and then open the document using the Word Interop services.
There is a list of documents loaded and the user can open only 1 instance of each document, but can open multiple different documents simultaneously. I don't have any problems with opening, saving, and closing when they open 1 document, however, when they open multiple documents simultaneously, I get the following error when closing any of my instances of 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.
I am using the following code to open the document and handle the BeforeDocumentClosed event:
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);
}
}
Does anyone see anything wrong that I am doing to allow opening of multiple documents at the same time? I am fairly new to Word Automation and the Word Interop services, so any advice is appreciated. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我通过这篇 MSDN 文章找到了解决方案: http://support.microsoft.com/kb/285885
您需要执行以下操作在调用 Application.Quit() 之前执行此操作;
这可以防止 Word 尝试保存 Normal.dotm 模板。我希望这对其他人有帮助。
I found the solution via this MSDN article: http://support.microsoft.com/kb/285885
You need to do this before calling Application.Quit();
This prevents Word from trying to save the Normal.dotm template. I hope this helps someone else.
我在 C# doc2pdf 应用程序中使用了 Word。在关闭文档之前,设置保存选项,如下所示:
I have used Word in C# doc2pdf application. Before close doc, set the save option like this:
我的应用程序中有帮助链接,并且想要打开特定书签的特定单词文档。如果文档已打开,则不应再次打开它。如果 Word 已打开,则不应打开 Word 的新实例。
这段代码对我有用:
I have help links in my application and wanted to open a particular word doc to a particular bookmark. If the document is already open, it should not open it again. If Word is already open, it should not open a new instance of Word.
This code worked for me:
请记住,代码:
始终会启动一个新的 Word 实例,即使已经加载了一个实例。
通常,您最好检查是否已加载实例(通过 GETOBJECT)并在存在时使用它,并且仅在需要时启动一个新实例。
Keep in mind that the code:
will always spin up a new instance of Word, even if there's already an instance loaded.
Usually, you're better off checking for a loaded instance (via GETOBJECT) and using it if there is one, and only spinning up a new instance if you need to.