仅在 Windows 服务中:System.Runtime.InteropServices.COMException (0x800A03EC):HRESULT 异常:0x800A03EC

Only in Windows Service: System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT: 0x800A03EC

我正在开发一个生成报告并将其保存为文件夹中的 Excel 文件的应用程序。

解决方案由Logic LibraryWinForm UIWindows Service组成。

逻辑库中的核心工作 (.Net Framework 4.7.2)。

我电脑上安装的Office是Office 2007,OS是Windows 10 Professional 64 Bit

UI 应用程序生成并完美保存 Excel 文件 Windows 服务生成错误:

System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT: 0x800A03EC at Microsoft.Office.Interop.Excel._Workbook.SaveAs(Object Filename, Object FileFormat, Object Password, Object WriteResPassword, Object ReadOnlyRecommended, Object CreateBackup, XlSaveAsAccessMode AccessMode, Object ConflictResolution, Object AddToMru, Object TextCodepage, Object TextVisualLayout, Object Local) at Utilities.Common.ExportToExcel(DataSet ds, String fileName) in C:\REPOS\Reporting.Tool.Services\Utilities\Common.cs:line 67

WinForm UIWindows Service 都是 表示层 并且没有逻辑,所以都在库中工作。

Windows 服务安装程序代码是:

namespace SqlToEmailReportingService
{
    partial class ProjectInstaller
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
            this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
            // 
            // serviceProcessInstaller1
            // 
            this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
            this.serviceProcessInstaller1.Password = null;
            this.serviceProcessInstaller1.Username = null;
            this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall);
            // 
            // serviceInstaller1
            // 
            this.serviceInstaller1.Description = "Reporting Service";
            this.serviceInstaller1.ServiceName = "ReportingService";
            // 
            // ProjectInstaller
            // 
            this.Installers.AddRange(new System.Configuration.Install.Installer[] {
            this.serviceProcessInstaller1,
            this.serviceInstaller1});

        }

        #endregion

        private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
        private System.ServiceProcess.ServiceInstaller serviceInstaller1;
    }
}

该服务正在做很多事情,根据日志,它们都在工作,但是当到达保存 excel 文件的点时,它会记录主题错误。

保存文件的库代码是:

public void ExportToExcel(DataSet ds, string fileName)
        {
            // Creating a Excel object. 
            Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
            Microsoft.Office.Interop.Excel._Worksheet worksheet = null;

            try
            {

                worksheet = workbook.ActiveSheet;

                worksheet.Name = "ExportedFromDatGrid";

                for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                {
                    worksheet.Cells[1, j + 1] = ds.Tables[0].Columns[j].ColumnName;
                }

                int cellRowIndex = 2;
                int cellColumnIndex = 1;

                //Loop through each row and read value from each column. 
                for (int i = 0; i < ds.Tables[0].Rows.Count /*- 1*/; i++)
                {
                    for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                    {
                        worksheet.Cells[cellRowIndex, cellColumnIndex] = ds.Tables[0].Rows[i][j].ToString();
                        cellColumnIndex++;
                    }
                    cellColumnIndex = 1;
                    cellRowIndex++;
                }

                worksheet.Columns.AutoFit();

                _logger.Information("Excel File Generated");

                workbook.SaveAs($"C:\TemData\excel_files\" + fileName + ".xlsx");

            }
            catch (Exception ex)
            {
                _logger.Error(ex.ToString());
            }
            finally
            {
                excel.Quit();
                workbook = null;
                excel = null;
            }

        }

文件夹权限(所有人完全控制)

有什么建议吗?解决方案?

经过数小时的研究和尝试,解决方案是:

好像是权限问题;因为 WinForm 使用安装 Office 的用户,而 windows 服务使用 LocalSystem 用户登录。

为了允许 LocalSystem 用户 运行 Office,我需要 select Microsoft Excel Application Properties 中的 interactive user 选项。

一步一步:

  1. Run a command [=] 中获取 MMC 组件服务(对于 32 位 OS,使用 mmc comexp.msc 而对于 64 位 OS,使用 mmc comexp.msc /32) 53=](Windows + R 键):

  1. 探索树 --> Select DCOM Config (Right-click on Microsoft Excel Application and 运行 the properties ) --> 在标识选项卡中启用 The interactive user 选项 --> OK.