1
votes

I am developing an application that generates a report and saves it as an Excel file in a Folder.

The solution consists of Logic Library, WinForm UI, and Windows Service.

The Core work in Logic Library (.Net Framework 4.7.2).

The Office installed on my PC is Office 2007 and the OS is Windows 10 Professional 64 Bit.

The UI App generates and Save the Excel File perfectly while the Windows Service generates the error:

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

Both WinForm UI and Windows Service are presentation layers and have no logic so all work in the Library.

Windows Service installer code is:

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;
    }
}

The Service is doing many things and according to logs they are all working but when reaching the point of saving the excel file it logs the subject error.

Library code saving the file is:

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;
            }

        }

Folder permission (Everyone Full Control)

Any advice? solution?

1

1 Answers

1
votes

After hours of research and try, the solution is:

As it looks like a permission problem; as the WinForm is using the User who installed the Office while the windows service is using the LocalSystem user to log on.

In order to allow the LocalSystem user to run the Office, I needed to select the interactive user option in the Microsoft Excel Application Properties.

Step by Step:

  1. Reach MMC Component Services (For 32 bit OS, use mmc comexp.msc while for 64 bit OS , use mmc comexp.msc /32) in Run a command window (Windows + R keys):

Run A Command Window

  1. Explore the tree --> Select DCOM Config (Right-click on Microsoft Excel Application and run the properties) --> Enable The interactive user option in identity tab --> OK.

component Services