views:

44

answers:

1

Recently deployed my web app on Windows Server2008, IIS7 (with Office installed).

After chasing (& catching) various other errors, I'm facing one I'm not sure even where to begin.

On Cassini (visual studio dev server) everything worked flawlessly (reading excel through excel interop).

On w2008 IIS it throws vague error:

Value cannot be null. Parameter name: o

[ArgumentNullException: Value cannot be null. Parameter name: o] System.Runtime.InteropServices.Marshal.FinalReleaseComObject(Object o) +9430474 longnamespace.ExcelReader.Dispose() in c:\longpath\ExcelReader.cs:23 longnamespace.ApplicationFormReader.Read(String path) in c:\longpath\ApplicationFormReader.cs:32

Currently, I'm going to add null check and see if things get better but I do suspect that it just blows up and disposes on finally block before it even starts reading anything.

Tried to set application pool to run under localsystem, but that didn't change anything.

Any ideas?


This is how dispose method looks like

    //http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c/159419#159419
    public void Dispose(){
      GC.Collect();
      GC.WaitForPendingFinalizers();
      GC.Collect();
      GC.WaitForPendingFinalizers();
      Marshal.FinalReleaseComObject(_ws); //Worksheet, line 23
      _wb.Close();
      Marshal.FinalReleaseComObject(_wb); //Workbook
      _ap.Quit();
      Marshal.FinalReleaseComObject(_ap); //Application
    }

I believe this event is related

The machine-default permission settings do not grant Local Activation permission for the COM Server application with CLSID {00024500-0000-0000-C000-000000000046} to the user NT AUTHORITY\NETWORK SERVICE SID (S-1-5-20) from address LocalHost (Using LRPC). This security permission can be modified using the Component Services administrative tool.

If so - could anyone translate?

Adding right for Microsoft Excel Application to Network service in component services somehow didn't work. kind a.

Removing authentication level didn't help too.


Changed to

  if (_ws != null)
    Marshal.FinalReleaseComObject(_ws);
  if (_wb != null)
  {
    _wb.Close();
    Marshal.FinalReleaseComObject(_wb);
  }
  if (_ap != null)
  {
    _ap.Quit();
    Marshal.FinalReleaseComObject(_ap);
  }

let's see how it goes...

+1  A: 

The exception looks fairly straightforward: at line 23 in your code you are calling Marshal.FinalReleaseComObject, passing a null reference.

So _ws, _wb or _ap is a null reference. You'll be able to see which if you look for line 23.

To solve this, test for null before calling FinalReleaseComObject.

The GUID {00024500-0000-0000-C000-000000000046} referenced in your event is Excel - as you'll be able to see with RegEdit.

So what I suspect is happening is that code you haven't posted that tries to instantiate an Excel Application object (_ap?) throws an exception due to insufficient permission. Then because your Dispose method isn't checking for _ap being null, it's throwing again there.

I suspect you're on the right track when you're looking to give Local Activation permission to the Network Service account. Not sure why this isn't working, maybe you need to reboot or restart IIS?

UPDATE Also Excel Interop is not recommended in server applications. It's better to manipulate Excel documents some other way, e.g. using a 3rd party component such as Aspose.

One thing I seem to remember is that Excel needs to run under an account that has a local profile, which may not be the case for the Network Service account. So running it under a different account as you mentioned in the comment might be the best solution if you need to use Excel Interop.

Joe
Strange thing is - why it is null if it never was before deploying on IIS? :/
Arnis L.
Switched to particular user as an identity in dcom settings and it finally worked. God I'm tired... Whole day fighting bullc**p problems like this one. Time to go home. And thanks for Your time.
Arnis L.
"Strange thing is - why it is null if it never was before deploying on IIS?" - probably because the other code that isn't posted was successfully instantiating the _ap object before deploying on IIS.
Joe