【发布时间】:2019-04-20 21:35:34
【问题描述】:
我正在 Outlook 中开发一个 VSTO,它调用 MSWord 创建一个 word 文档,将其保存为 PDF,之后 VSTO 退出 word。我正在使用 VS2017 Professional 和 Office365 - MSWord 版本 16。
如果 MSWord 未打开 - 下面的代码就像一种享受。但是,如果 MSWord 已打开,我会收到警告 “Word 无法保存文件,因为它已在其他地方打开 (normal.dotm)”。现在我知道这已经被讨论了很多次,并且我已经尝试了我可以在 StackExchange 和其他地方找到的所有解决方案。之前通过引用this question 中的答案解决了这个问题,但自从最近更新了 Office365 后,同样的警告又回来了。
以下是我正在使用的代码的子集 - 所有文件名等都是有效的。
// start word to create PDF file
Word.Application wordApp = new Word.Application();
Word.Document wrdDoc = new Word.Document();
object saveOption = false;
//Word.WdSaveOptions.wdDoNotSaveChanges;
object oMissing = Type.Missing;
Word.Documents d = wordApp.Documents;
try
{
// set the word app invisible
wordApp.Visible = false;
// open the document with the tmpfilename
wrdDoc = d.Open(FileNameIn, Visible: true);
//set the page size ...
//wrdDoc.PageSetup.PaperSize = Word.WdPaperSize.wdPaperA4;
}
catch (COMException es)
{
throw (es);
}
try
{
//Save/Export our document to a PDF
wrdDoc.ExportAsFixedFormat(OutputFileName: FileNameOut, ExportFormat: Word.WdExportFormat.wdExportFormatPDF,
OpenAfterExport: false, OptimizeFor: Word.WdExportOptimizeFor.wdExportOptimizeForPrint,
Range: Word.WdExportRange.wdExportAllDocument, From: 0, To: 0, Item: Word.WdExportItem.wdExportDocumentContent,
IncludeDocProps: true, KeepIRM: true, CreateBookmarks: Word.WdExportCreateBookmarks.wdExportCreateNoBookmarks,
DocStructureTags: true, BitmapMissingFonts: true, UseISO19005_1: false);
// trick our Word App into thinking that we have been saved
wordApp.NormalTemplate.Saved = true;
}
catch (COMException es)
{
// there is an actual error reporting mechanism here
throw (es);
}
finally
{
try
{
// make our document think its been saved
wrdDoc.Saved = true;
// close our document
wrdDoc.Close(ref saveOption, ref oMissing, ref oMissing);
// trick our Word App into thinking that we have been saved
wordApp.NormalTemplate.Saved = true;
wordApp.Quit(ref saveOption, ref oMissing, ref oMissing);
// release our document object
Marshal.ReleaseComObject(wrdDoc);
// release our documents object
Marshal.ReleaseComObject(d);
// release our application object
Marshal.ReleaseComObject(wordApp);
}
catch (Exception es)
{
// there is an actual error reporting mechanism here
throw (es);
}
finally
{
//
}
}
我有义务为解决此问题提供任何和所有帮助。 提前谢谢了 DWE
【问题讨论】:
-
现在不能尝试你的代码,但是为什么你有这行
Word.Document wrdDoc = new Word.Document();?您稍后使用 d.Open() 覆盖 wrdDoc,我怀疑可能有一个新文档的处理实例潜伏在周围。尝试删除它,看看它是否对您有所改变。 -
Nick,使该更改在我目前正在使用的计算机上运行......但我们正在测试的代码也是如此......所以我将在计算机上尝试它明天它在哪里失败(我在澳大利亚)......你知道这段代码是否受到线程或多个监视器的影响?在工作环境中,我们使用两个监视器,代码在一个线程上运行......会有所作为吗?
-
您必须仅从在 STA 中运行的一个线程中使用自动化。这就是 WinForms 和 WPF 的 UI 线程。永远不要在任务和其他线程中使用 Office 自动化!至于多显示器,我们在开发和生产中都有多个显示器设置的自动化 Word 用例。因此没有问题。
-
Nick,我检查了工作环境中的代码,但在相关机器(有两个显示器)上仍然失败,而在单显示器机器上没有失败;奇怪。此外,我可以确认代码在线程上运行时正在 STA 中运行。
标签: c# vsto outlook-addin