Outlook VSTO-MS Word-普通模板警告-Word无法保存文件,因为该文件已在其他位置打开(normal.dotm)

时间:2018-11-18 08:40:15

标签: c# vsto outlook-addin

我正在Outlook中开发VSTO,它要求MSWord创建一个Word文档,然后将其另存为PDF,然后VSTO退出单词。我正在使用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

1 个答案:

答案 0 :(得分:0)

最近几天,我从错误中学到了很多东西,我在上面寻求了一些帮助。

我了解到,为了正确调试Outlook和MSWord的问题,应该卸载当前正在运行的所有第三方加载项,然后尝试解决问题。在我的特殊情况下,我发现一个名为Nuance Paperport的程序具有将Word文档转换为PDF的加载项,该加载项锁定normal.dotm模板,并且在要求退出代码中的单词时不遵守规则。尽管对某些人来说这可能是微不足道的,但对我来说却是一个宝贵的教训。

下面是将Word文档转换为PDF的代码,这是我目前确定要使用的代码。

        /// <summary>
    /// A test to see if word is working
    /// this function takes a valid word document and converts it to a PDF 
    /// and takes the user to explorer with the converted file selected
    /// </summary>
    /// <param name="WordDocIn">a valid path\filename to an existing word document (doc, docx, rtf, htm, mhtml</param>
    /// <returns>returns False if there are no errors and the function completed successfully</returns>
    private bool WordToPDF(string WordDocIn)
    {
        // check and make sure our file parameter actually exists
        if(!File.Exists(WordDocIn))
        {
            MessageBox.Show("The file does not exist\n\n" + WordDocIn + "\n\n", "Office Assist: Error()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return true; // true meaning there are errors
        }
        string tmpFilename = WordDocIn;
        // create a temp filename in temp directory
        string opFileName = GetTempFilePathWithExtension("pdf");
        // set our return value
        bool ErrorsPresent = false; // false meaning there are NO errors

        // create our word app
        Word.Application wordApp = new Word.Application();
        // get our documents collection (if any)
        Word.Documents d = wordApp.Documents;
        // create our new document
        Word.Document wrdDoc = new Word.Document();
        // create our word options
        object saveOption = false;// Word.WdSaveOptions.wdDoNotSaveChanges;
        // create our missing object
        object oMissing = Type.Missing; ;// Type.Missing;

        try
        {
            // set the word app visisble for the moment sp
            // we can see what we're doing
            wordApp.Visible = false;

            // suppress our alerts
            wordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;

            // we dont need any addins - unload all of our addins
            // need to open word with no addins loaded ... 
            wordApp.AddIns.Unload(true);   // True to remove the unloaded add-ins from the AddIns collection 
                                            // (the names are removed from the Templates and Add-ins dialog box). 
                                            // False to leave the unloaded add-ins in the collection.

            // open the document with the tmofilename
            wrdDoc = d.Open(tmpFilename, Visible: true);
            //set the page size ... to A4 (note this will throw an error if the default printer does not produce A4)
            wrdDoc.PageSetup.PaperSize = Word.WdPaperSize.wdPaperA4;

            //
            // export our document to a PDF
            //
            wrdDoc.ExportAsFixedFormat(OutputFileName: opFileName, 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 the document has been saved
            wrdDoc.Saved = true;
            // close our word document
            wrdDoc.Close(ref saveOption, ref oMissing, ref oMissing);
            // close our documents collection
            //d.Close(ref saveOption, ref oMissing, ref oMissing);

            foreach (Word.Template template in wordApp.Templates)
            {
                switch (template.Name.ToLower())
                {
                    case "normal.dotm":
                        template.Saved = true;
                        break;
                }
            }
            // quit word
            wordApp.Quit(ref saveOption, ref oMissing, ref oMissing);
        }
        // catch our errors
        catch (COMException es)
        {
            string errcode = "ComException : " + es.Message + "\n\n" + "Show this message to your admin";
            MessageBox.Show("Check the default printer has the ability to print A4\nSelect a new printer and try again\n\n" + errcode, "Office Assist: Error()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            ErrorsPresent = true;
            //throw (es);
        }
        catch (Exception es)
        {
            string errcode = "Exception : " + es.Message + " \n\n " + "Show this message to your admin";
            MessageBox.Show(errcode, "Office Assist: Error()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            ErrorsPresent = true;
            //throw (es);
        }
        finally
        {
            try
            {
                // release our objects
                Marshal.ReleaseComObject(wrdDoc);
                Marshal.ReleaseComObject(d);
                Marshal.ReleaseComObject(wordApp);
            }
            catch (Exception es)
            {
                string errcode = "Exception : " + es.Message + " \n\n " + "Show this message to your admin";
                MessageBox.Show(errcode, "Office Assist: Error()", MessageBoxButtons.OK, MessageBoxIcon.Error);
                ErrorsPresent = true;
            }
        }


        // if there are no errors present
        // open explorer and select the pdf created
        //
        if (!ErrorsPresent)
        {
            // set our switches
            string argument = "/select, \"" + opFileName + "\"";
            // open explorer and select the file
            Process.Start("explorer.exe", argument);
        }

        return ErrorsPresent;
    }

鉴于我花费了很多时间来解决此问题,并且看到了与将Word文档转换为PDF以及规范模板的类似性质或类似问题有关的帖子数量,我认为应该发表评论关于我所学到的知识并发布对我有用的代码,以希望将来对其他人有帮助。