C# 中的 Office 应用程序字

Office applications word in C#

我正在尝试从多个 Word 文档创建大量 PDF。 不幸的是,我无法 close/clean 起来(垃圾收集)。因此内存消耗很大,最后程序dumps

这是我的代码。我希望你们这些聪明的人可以指导我找到解决方案。

//**************************************************************
// Please notice:
//
// this.Files is an array with filepath and filenames e.g.:
// {"x:\doc\doc1.doc", "x:\doc\doc2.doc",...,"x:\doc\docn.doc"}.
//
// Please notice:
//**************************************************************


public void wordToPDF() {

    string LS_fileName = "";
    string LS_fileExtension = "";
    string LS_PDF = ".pdf";

    try
    {
        foreach (string Filename in this.Files)
        {
            LS_fileName = Path.GetFileName( Filename );
            if (Path.GetExtension( Filename ) == ".doc" || Path.GetExtension( Filename ) == ".docx")
            { 
                // Convert to PDF:
                Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
                wordDocument = appWord.Documents.Open(GlobalVar.TempFiles + LS_fileName);
                LS_fileExtension = Path.GetExtension(Filename);

                LS_fileName = LS_fileName.Replace( LS_fileExtension, LS_PDF );                  int i = 0;
                foreach (string value in this.Files)
                {
                    if (value == Filename)
                    {
                         this.Files[i] = this.Files[i].Replace(LS_fileExtension, LS_PDF);
                         break;
                    }
                    i++;
                }
                wordDocument.ExportAsFixedFormat(GlobalVar.TempFiles + LS_fileName, MSWORD.WdExportFormat.wdExportFormatPDF);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(appWord);
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("getFiles Hello I must be going.");
    }
}
}

//更新#1:

public void wordToPDF() {

    string LS_fileName = "";
    string LS_fileExtension = "";
    string LS_PDF = ".pdf";
    int i = 0;

    MSWORD.Application appWord = new MSWORD.Application();

    try
    {
        foreach (string Filename in this.Files)
            {
                LS_fileName = Path.GetFileName( Filename );
                    if (Path.GetExtension( Filename ) == ".doc" || Path.GetExtension( Filename ) == ".docx")
                    { 
                        // Convert to PDF:
                        wordDocument = appWord.Documents.Open(GlobalVar.TempFiles + LS_fileName);
                        LS_fileExtension = Path.GetExtension(Filename);

                        LS_fileName = LS_fileName.Replace( LS_fileExtension, LS_PDF );
                        i = 0;
                        foreach (string value in this.Files)
                        {
                            if (value == Filename)
                            {
                               this.Files[i] = this.Files[i].Replace(LS_fileExtension, LS_PDF);
                                break;
                            }
                            i++;
                            }
                            wordDocument.ExportAsFixedFormat(GlobalVar.TempFiles + LS_fileName, MSWORD.WdExportFormat.wdExportFormatPDF);
                    }
    }
}
    catch (Exception ex)
    {
        Console.WriteLine("getFiles Hello I must be going.");
        System.Runtime.InteropServices.Marshal.ReleaseComObject(appWord);
    wordDocument.Close();
    if (appWord != null)
    {
        appWord.Quit();
        appWord = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}
    System.Runtime.InteropServices.Marshal.ReleaseComObject(appWord);
wordDocument.Close();
    if (appWord != null)
    {
        appWord.Quit();
        appWord = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

//更新#2:

public void wordToPDF() 
{

    string LS_fileName = "";
    string LS_fileExtension = "";
    string LS_PDF = ".pdf";
    object missingType = Type.Missing;
    object SaveChanges = Type.Missing;
    object OriginalFormat = Type.Missing;
    object RouteDocument = Type.Missing;

    MSWORD.Application appWord = new MSWORD.Application();

    try
    {
        foreach (string Filename in this.Files)
            {
                LS_fileName = Path.GetFileName( Filename );
                    if (Path.GetExtension( Filename ) == ".doc" || Path.GetExtension( Filename ) == ".docx")
                    { 
                            // Convert to PDF:
            wordDocument = appWord.Documents.Open(GlobalVar.TempFiles + LS_fileName);
                            LS_fileExtension = Path.GetExtension(Filename);

                            LS_fileName = LS_fileName.Replace( LS_fileExtension, LS_PDF );
                            int i = 0;
                            foreach (string value in this.Files)
                            {
                                if (value == Filename)
                                {
                                    this.Files[i] = this.Files[i].Replace(LS_fileExtension, LS_PDF);
                                    break;
                                }
                                i++;
                            }
                            wordDocument.ExportAsFixedFormat(GlobalVar.TempFiles + LS_fileName, MSWORD.WdExportFormat.wdExportFormatPDF);

                            wordDocument.Close();
                    }
                }
    }
            catch (Exception ex)
            {
                Console.WriteLine("getFiles Hello I must be going.");
                System.Runtime.InteropServices.Marshal.ReleaseComObject(appWord);

                if (appWord != null)
                {
                    appWord.Quit();
                    appWord = null;
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
            }
            System.Runtime.InteropServices.Marshal.ReleaseComObject(appWord);

            appWord.Quit(ref object SaveChanges = Type.Missing, ref object OriginalFormat);
            if (appWord != null)
            {
                appWord = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
        }
    }
}

确保在释放 COM 对象之前关闭文档和应用程序,然后处理并可能强制执行 GC.Collect()。
编辑:如果您多次使用 word,只需启动一次 word 并打开您的文件以导出 pdf,然后一个一个地关闭。最后关闭wordApp。
Edit2:每次启动内部循环时都应将 i 重置为 0

  1. 使用"using"子句
  2. 将循环内容提取到单独的方法中以简化 GC
  3. 只有在别无选择时才应调用 GC 收集

我不明白你为什么要做内部for循环

1)尝试将此行移出循环。 (foreach (string Filename in this.Files))

 Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();

2) close all Documents at the end of the loop (foreach (string Filename in this.Files)) that will close all Word windows, or you can save you link for saved文档并关闭它。

编辑:

foreach (string Filename in this.Files)
        {
            LS_fileName = Path.GetFileName( Filename );
                if (Path.GetExtension( Filename ) == ".doc" || Path.GetExtension( Filename ) == ".docx")
                { 
                    // Convert to PDF:
                    wordDocument = appWord.Documents.Open(GlobalVar.TempFiles + LS_fileName);
                    LS_fileExtension = Path.GetExtension(Filename);

                    LS_fileName = LS_fileName.Replace( LS_fileExtension, LS_PDF );
                    i = 0;
                    foreach (string value in this.Files)
                    {
                        if (value == Filename)
                        {
                           this.Files[i] = this.Files[i].Replace(LS_fileExtension, LS_PDF);
                            break;
                        }
                        i++;
                        }
                        wordDocument.ExportAsFixedFormat(GlobalVar.TempFiles + LS_fileName, MSWORD.WdExportFormat.wdExportFormatPDF);
                       wordDocument.Close(missing, missing, missing);
                }
}

描述:由于word模型,word是一个只有一个主体的应用程序Microsoft.Office.Interop.Word.Application它包含了运行时打开的所有文档,这些文档看起来像一个独立的应用程序(windows)但是他们不是。

显然退出 winword 应用程序不起作用。 Hense 应用了一个更基本的解决方案:

Process[] processes = Process.GetProcessesByName("winword");
foreach (var process in processes)
{
    try
    {
        process.Kill();
    }
    catch (Exception)
    {
    // handle the exception...                    
    }

}
// That solved the problem.
// Thanks for your help :-).