0

I have a C# (using Razor) Web Application that runs through my company's intranet.

I have been using ClosedXML to manage all of my Excel needs and it works great, however, now I need to run Macros inside Excel Files and apparently ClosedXML cannot do this, so I must use Excel Interop.

My code below gives the dreaded:

Microsoft Excel cannot access the file ... There are several possible reasons: • The file name or path does not exist. • The file is being used by another program. • The workbook you are trying to save has the same name as a currently open workbook.

  1. The file name and path DOES exist
  2. I made sure that Excel is not even running on the server
  3. The workbook is not open (see above).

Things I've tried. I've tried to create security provisions for the C:\Windows\System32\config\systemprofile and SysWOW64\config\systemprofile.

(Side Note: I could not find IIS_USRS when I tried to add the security provisions - this may be the problem.)

I've also tried editing the Excel Application properties via dcomcnfg and I still get the same error.

here's what I'm trying to do:

//C# with Razor Syntax
@using MSExcel = Microsoft.Office.Interop.Excel
@using System.Runtime.InteropServices
@using System.Web
@using System.IO

string worksheetName = "Sheet1";

string[] macros = new string[] { "Module1.Reset_List()", "Module1.Run_Setup()"};

string workbookPath = HttpContext.Current.Server.MapPath(@"~/uploads/test.xlsm");

FileInfo xlsFile = new FileInfo(workbookPath);

string msg = (File.Exists(xlsFile.FullName)) ? "Found It!" : "Can't Find It...";
<p>@msg</p>;   // <-- This always returns "Found It!"

//Create the Excel Object
MSExcel.Application xlsApp = new MSExcel.Application();
xlsApp.Visible = true;

try
{
    //Identify the workbook (open the file)
    // *** the error occurs on the line below *** //
    MSExcel.Workbook xlsBook = xlsApp.Workbooks.Open(xlsFile.FullName);
    xlsBook.Activate();

    //Identify the worksheet
    MSExcel.Worksheet xlsSheet = (MSExcel.Worksheet)xlsBook.Sheets[worksheetName];
    xlsSheet.Activate();



    foreach (string macro in macros)
    {
        xlsApp.Run(macro);
    }

    xlsBook.Save();
    xlsBook.Close(false, "", false);
    xlsApp.Quit();
}
catch (Exception e)
{
    <p>@e.Message</p>
    Marshal.ReleaseComObject(xlsApp);
    xlsApp = null;
}

if (xlsApp != null)
{
    Marshal.ReleaseComObject(xlsApp);
    xlsApp = null;
}
bagofmilk
  • 1,492
  • 8
  • 34
  • 69
  • 3
    Word of advice: Do not do this, never use Excel interop on a web server - you will regret it. – DavidG Apr 11 '18 at 15:09
  • use the debugger and make sure the file-path and file name exist, also make sure you do not have spaces in the file name.. if you do then you need to wrap single quotes around the filename – MethodMan Apr 11 '18 at 15:09
  • @MethodMan, thank you for the reminder, but If you see in the code I check for the existence of the file, and it always returns that it was found – bagofmilk Apr 11 '18 at 15:10
  • @DavidG can you elaborate? – bagofmilk Apr 11 '18 at 15:10
  • 1
    Excel was never designed to run in that way. So while you can get it working, it will destroy your memory, use tonnes of CPU and make you want to hurt yourself. – DavidG Apr 11 '18 at 15:12
  • @DavidG lol, I already feel the pain. Is there an alternative method to run excel macros in a workbook via c#? – bagofmilk Apr 11 '18 at 15:13
  • Some good info here: https://support.microsoft.com/en-gb/help/257757/considerations-for-server-side-automation-of-office – DavidG Apr 11 '18 at 15:13
  • Just a shot in the dark here but run task mngr on the server (ctrl + alt+ end from remote desktop) . Show process from all users, and make sure that you don't have another instance of excel running holding the file. This happened to me before when using similar code, I had excel open and an instance of the file locked from a previous failed attempt. – Travis Acton Apr 11 '18 at 15:13
  • As for running macros, you're also leaving yourself open to some serious security holes doing this. – DavidG Apr 11 '18 at 15:14
  • @TravisActon, another good reminder - and I do that same method before running the app. Excel is not running before I try this. – bagofmilk Apr 11 '18 at 15:14
  • @DavidG - I completely understand about the security issues - however, this is a company intranet site and while IT expressed the concern - we have to do this – bagofmilk Apr 11 '18 at 15:15
  • @TravisActon - the error occurs at the workbook open line (I added a note above it) – bagofmilk Apr 11 '18 at 15:18
  • Well at the very least, make sure you are licensed to install Excel on your server and make sure this function is *controlled* (i.e. people can;t just upload random Excel files) and it's only used by a select few people. As soon as you have more than a couple of users hitting this, things will fall over. – DavidG Apr 11 '18 at 15:22
  • What does the path resolve to (what is the value of xlsFile.FullName) ? – PaulF Apr 11 '18 at 15:23
  • @DavidG - Good point. The files are 100% managed and operated by the server and in a specific manner. The app first copies the master workbook (that resides on the server) to another location and does its business. Only certain macros can run on certain excel workbooks. Users cannot upload workbooks or tamper with the files. – bagofmilk Apr 11 '18 at 15:24
  • Which of course begs the question: Why use macros and not just plain old C# code? – DavidG Apr 11 '18 at 15:26
  • @PaulF - honestly its the exact same path as `workbookPath`, I was just desperate and trying to see if FileInfo might do something different. The path it reads is `C:\inetpub\wwwroot\jmanage\uploads\test.xlsm` – bagofmilk Apr 11 '18 at 15:26
  • @DavidG - The engineers create their excel workbooks and then tell us what needs to happen in order to process jobs. I actually just emailed the engineer that I might need to hard-code his formulas in my app - but the easiest thing to do is run the macros from the Excel Files (if possible) - this also keeps the maintenance off my hands anytime the engineer wants to update the process. – bagofmilk Apr 11 '18 at 15:27
  • 1
    Well there are potentially better ways to do that. For example, how about embedding a scripting library? There's plenty of options there for C#, Python etc. You could even just let people write vbscript files and execute them instead of worrying about Excel. – DavidG Apr 11 '18 at 15:29
  • @DavidG - For this particular file, I need to populate certain Excel names, run two macros, then print a PDF of a specified print area and save the file on a company intranet directory. For the previous jobs I have just been populated Excel Names and saving the files elsewhere. Engineers love to play with their Excel documents, and ClosedXML had been doing just great – bagofmilk Apr 11 '18 at 15:30
  • @DavidG - I'll look into that. Thank you – bagofmilk Apr 11 '18 at 15:32
  • Have you seen this : https://stackoverflow.com/questions/7106381/microsoft-office-excel-cannot-access-the-file-c-inetpub-wwwroot-timesheet-app and the both answers here : https://forums.asp.net/t/1740537.aspx?Microsoft+Excel+cannot+access+the+file+is+solved+by+creating+a+folder+ – PaulF Apr 11 '18 at 15:39
  • There is also a video here - I don't have sound at work - so don't know if there is a commentary or what language if there is : https://www.youtube.com/watch?v=NqvQ0JyBG2c and here https://www.youtube.com/watch?v=ijfb3E_7t3o – PaulF Apr 11 '18 at 15:45
  • @PaulF - Yes I had already done that - still nothing. – bagofmilk Apr 11 '18 at 18:16
  • hi, have you found any solution ? – João Passos Feb 21 '19 at 17:10

0 Answers0