从ASP MVC控制器运行Word时,继续获取InteropServices.COMException

时间:2015-03-12 05:34:50

标签: c# asp.net-mvc asp.net-mvc-4 com office-interop

我从ASP .NET MVC应用程序中的控制器运行Microsoft.Interop.Word时遇到错误远程过程调用失败HRESULT:0x800706BE异常。奇怪的是,如果我调试应用程序并逐步运行它,则不会抛出任何异常。我还没能理解我在微软上发现的关于这个例外的一些文档。我读到的是,当它被调用时,Word会关闭套接字,但我不知道有什么关于它的,所以我希望有人可能知道问题可能是什么。异常总是抛在我的代码的特定行(我已经评论它失败的地方):

//
    // GET /Asistencia/PrintDocentes
    public ActionResult PrintDocentes(int IdCurso)
    {
        List<AsistenciaDocentesViewModel> materias = new Metodos.Entidades().getListadoProfesores(IdCurso);
        List<int> compartidas = new List<int>();
        compartidas = materias.GroupBy(t => t.IdMateriasCursos).Where(t => t.Count() > 1).Select(t => t.Key).ToList();
        List<string> catedrasCompartidas = new List<string>();
        catedrasCompartidas= materias.Where(s => compartidas.Any(t=> t.Equals(s.IdMateriasCursos))).Select(r => r.NombresMaestro).ToList();

        string document = "asistenciaDocentes.docx";
        string uploadsFolder = HostingEnvironment.MapPath("~/App_Data/Docs");
        string imageFolder = HostingEnvironment.MapPath("~/Images/Docs");
        string[] encabezado = { "logoCideAsistencia.jpg", "logoSegobAsistencia.jpg", "logoPFAsistencia.jpg", "logoDiplomadoAsistencia.jpg" };
        string archivo = Path.Combine(uploadsFolder, @document);
        ApWord = new Word.Application();
        docAsistencia = ApWord.Documents.Add(ref opc, ref opc, ref opc, ref opc);
        ApWord.Visible = true;
        docAsistencia.PageSetup.RightMargin = (float)100;
        docAsistencia.PageSetup.LeftMargin = (float)60;
        foreach (Word.Section section in ApWord.ActiveDocument.Sections)
        {
            Word.Range headerRange = section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
            for (int i = 0; i < encabezado.Length; i++)
            {
                headerRange.Collapse(Word.WdCollapseDirection.wdCollapseStart);
                string path = Path.Combine(imageFolder, encabezado[i]);
                Word.InlineShape map = headerRange.InlineShapes.AddPicture(path);
                if (i == 0) { map.Height = 48; map.Width = 39; } /*********
*********************This is the line that throws the exception ********/
                if (i == 1) { map.Width = 263; map.Height = 39; }
                if (i == 2) { map.Width = 141; map.Height = 26; }
                headerRange.Move(Word.WdUnits.wdCharacter);
                headerRange.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
                if (i == 2) break;

            }

            Word.Shape titulo = docAsistencia.Shapes.AddTextbox(Microsoft.Office.Core.MsoTextOrientation.msoTextOrientationHorizontal,60, 5, 300, 50, ref opc);
            titulo.TextFrame.TextRange.Text = "DIPLOMADO EN MANDO POLICIAL 2015\nLista de Asistencia de profesores\n";
            titulo.Line.Visible = MsoTriState.msoFalse;
            titulo.TextFrame.TextRange.Font.Name = "Cambria";
            titulo.TextFrame.TextRange.Font.Size = 16;
            titulo.TextFrame.TextRange.Font.Bold = 1;
            titulo.TextFrame.TextRange.Font.Italic = 1;


            headerRange.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphRight;
            Word.InlineShape map2 = headerRange.InlineShapes.AddPicture(Path.Combine(imageFolder, encabezado[3]));
            map2.Height = 106;
            map2.Width = 137;


        }
        foreach(AsistenciaDocentesViewModel item in materias)
        {
        Word.Paragraph grupo1 = docAsistencia.Paragraphs.Add(ref opc);
        grupo1.Range.Font.Name = "Arial";
        grupo1.Range.Font.Size = 14;
        grupo1.Range.Font.Bold = 1;
        grupo1.Range.InsertAfter("Semana\t" + item.Semana);
        Word.Paragraph grupo2 = docAsistencia.Paragraphs.Add();
        grupo2.Range.InsertAfter("Sede\t" + item.Sede);
        Word.Paragraph grupo3 = docAsistencia.Paragraphs.Add();
        grupo3.Range.InsertAfter("Grupo\t" + item.Grupo);
        Word.Paragraph grupo4 = docAsistencia.Paragraphs.Add();
        docAsistencia.Words.Last.InsertBreak(Word.WdBreakType.wdLineBreak);
        grupo4.Range.InsertAfter("Fecha\t" + item.Fecha);
        Word.Paragraph grupo5 = docAsistencia.Paragraphs.Add();
        grupo5.Range.InsertAfter("Día\t" + item.Dia);
        Word.Paragraph grupo6 = docAsistencia.Paragraphs.Add();
        grupo6.Range.InsertAfter("Horario\t" + item.HorarioInicio + " - " + item.HorarioFin);
        Word.Paragraph grupo7 = docAsistencia.Paragraphs.Add();
        grupo7.Range.InsertAfter("compartir");

        if (compartidas.Contains(item.IdMateriasCursos))
        {
            List<AsistenciaDocentesViewModel> compartir = materias.Where(t => t.IdMateriasCursos.Equals(item.IdMateriasCursos)).ToList();
            List<string> catedras = compartir.Select(t => t.NombresMaestro).ToList();
            List<string> catedras_aImprimir = catedras.Where(t => !t.Equals(item.NombresMaestro)).ToList();
            foreach (string catedra in catedras_aImprimir)
            {
                Word.Paragraph grupo8 = docAsistencia.Paragraphs.Add();
                grupo8.Range.InsertAfter(catedra);

            }
            docAsistencia.Words.Last.InsertBreak(Word.WdBreakType.wdLineBreak);
        }
        Word.Paragraph grupo9 = docAsistencia.Paragraphs.Add();
        grupo9.Range.InsertAfter("Módulo");
        Word.Paragraph grupo10 = docAsistencia.Paragraphs.Add(); 
        grupo10.Range.InsertAfter(item.Modulo);
        Word.Paragraph grupo11 = docAsistencia.Paragraphs.Add();
        grupo11.Range.InsertAfter("Materia");
        Word.Paragraph grupo12 = docAsistencia.Paragraphs.Add();
        grupo12.Range.InsertAfter(item.Materia);
        Word.Paragraph grupo13 = docAsistencia.Paragraphs.Add();
        grupo13.Range.InsertAfter("Profesor");
        Word.Paragraph grupo14 = docAsistencia.Paragraphs.Add();
        grupo14.Range.InsertAfter(item.NombresMaestro);
        Word.Paragraph grupo15 = docAsistencia.Paragraphs.Add();
        grupo15.Range.InsertAfter("Firma:______________________________________________________");

        docAsistencia.Words.Last.InsertBreak(Word.WdBreakType.wdPageBreak);
        }
        docAsistencia.SaveAs2(archivo, ref opc, ref opc, ref opc, ref opc, ref opc, ref opc, ref opc, ref opc, ref opc, ref opc,
            ref opc, ref opc, ref opc, ref opc, ref opc, ref opc);
        docAsistencia.Close();
        Marshal.FinalReleaseComObject(ApWord);
        Marshal.FinalReleaseComObject(docAsistencia);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        return RedirectToAction("VerRecursos", new { file = document });

    }

请帮忙,我之前没有和Interop合作过,所以我真的无法猜出是什么错,我想也许这两个循环可能会导致问题,但我真的不知道

1 个答案:

答案 0 :(得分:2)

Microsoft目前不建议也不支持从任何无人参与的非交互式客户端应用程序或组件(包括ASP,ASP.NET,DCOM和NT服务)自动化Microsoft Office应用程序,因为Office在此环境中运行Office时,可能会出现不稳定的行为和/或死锁。

如果要构建在服务器端上下文中运行的解决方案,则应尝试使用已为安全无人值守执行的组件。或者,您应该尝试找到允许至少部分代码在客户端运行的替代方法。如果从服务器端解决方案使用Office应用程序,则应用程序将缺少许多成功运行的必要功能。此外,您将承担整体解决方案稳定性的风险。您可以在Considerations for server-side Automation of Office文章中详细了解相关内容。

考虑使用Open XML SDK,有关详细信息,请参阅Welcome to the Open XML SDK 2.5 for Office。您还可以找到专为服务器端执行而设计的第三方组件。