Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE) Workarounds
Asked Answered
S

5

21

From the following call

Marshal.GetActiveObject("Excel.Application")

I get a

Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))

I believe that this error is caused when the user permissions between my application and excel do not match.

I want to know if there is a workaround as to how I can access the opened excel application regardless of how excel is opened, I can open the program that I want to access excell from as an administrator.

Also I would like to know how I can tell what permissions processes were opened with? I have been using ProcessExplorer to look at the UserProfile (which was the same in both applications), and Owner (which was also the same BUILTIN\Administrators)

Background I have a program that run different tests by calling NUnit-console-x86. The application that is being tested opens up an excel form, this is the form that I want to read the data from. And when i run my program as administrator, or not I get these errors, I have also tried adding in Process.StartInfo.Verb = "runas"; to my program that starts up NUnit but I still get these errors

It appears installing visual studio fixes the problem although I do not want to have to install visual studio on every computer. Can anyone explain any of this to me?

Succession answered 10/10, 2012 at 20:54 Comment(2)
I just went through the permission nightmare with Excel and once I set Excel's compatibly mode to run as an administrator as well as the invoking application to be ran as an administrator, everything worked.Dislimn
I've had this problem so many times, I found that if I encounter the error and switch back and forth between Skype and Excel, it works...Haymes
L
7

Looking at Microsoft Support Information, 0x800401e3 seems to be generated when excel (or office in general) isn't active or running in the Running Object Table. You have to have a copy of excel opened before you call this. Its either you haven't opened excel in code yet, or its not fully registered yet. Could this be the problem?

Lenna answered 19/11, 2013 at 23:20 Comment(4)
No. It was running. But somehow I was running Visual Studio as a non-administrator. Once I reran it as an administrator, everything started working.Assiduous
Ahhhh. Yup, that would do it too. Glad you were able to get it working.Lenna
Per the article you linked: "When an Office application starts, it does not immediately register its running objects. This optimizes the application's startup process. Instead of registering at startup, an Office application registers its running objects in the ROT once it loses focus." I've found you need to focus on a different window to accomplish this(just minimizing does work...), somewhat hacky, I wonder if there is a better way :(Pivotal
@DavidRogers This worked for me, honestly it should be its own answer. But is also inane as a solution.Unwatched
B
3

It's the problem of mismatching previleges between Visual Studio and Excel. Microsoft documents don't say that but it definitely is. The more serious problem is that the exception is sometimes thrown and sometimes not through old versions of Excel which don't know the administrative previliges i.e. version 2007.

When it happens you should match the previleges as administrator-administrator or none-none. Even Excel none-previlege and Visual Studio administrator may not work.

Basophil answered 27/1, 2019 at 6:0 Comment(1)
Thank you very much! It's the same for me, I don't use Word as admin and only get a connection to a running instance when I start VS also without admin rights. The principle of matching rights is probably also the reason why you can easily access Word from Excel and vice versa with VBA's GetObject function.Heng
P
2

To extend what @DylanCorriveau says, I've found that you'll need to take one the following methods to avoid this issue.

Method 1

I found that in some cases (Excel 2010) starting excel first resolves this issue. You'll need to adjust the path and wait to fit you needs and version.

string pathToTheVersionOfExcel = @"C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE";
System.Diagnostics.Process.Start(pathToTheVersionOfExcel);
Thread.Sleep(5000); //"WaitForInputIdle" waits for way too long, generally it takes 5 seconds to start for me

Method 2

Another approach I've taken in the past is invoking Excel in a different way:

var oExcelApp = new Microsoft.Office.Interop.Excel.Application();

Method 3

Finally in my application (for both excel 2010 and 2016) I've used a bit of a workaround:

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

//In your method...
string pathToTheVersionOfExcel = @"C:\Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE";
Application oExcelApp = null;

Process process = new Process();
process.StartInfo.FileName = pathToTheVersionOfExcel;
process.Start();

Thread.Sleep(5000);

//Opening a closing notepad seems to "register" excel 2016, not needed for excel 2010 though...
Process processNotepad = new Process();
processNotepad.StartInfo.FileName = @"C:\Windows\system32\notepad.exe";
processNotepad.Start();

ShowWindow(process.MainWindowHandle, 2); //Minimize
ShowWindow(process.MainWindowHandle, 3); //Maximize

Thread.Sleep(5000);

processNotepad.CloseMainWindow();

oExcelApp = (_Application)Marshal.GetActiveObject("Excel.Application");

If you running this code in Excel 2016 in a RDP session it can be very picky, I've found that you need to customize RDP to ignore it's minimized state. I found this article quite helpful.

If your trying to invoke excel through some sort of automated build/release platform on a remote server (such as TFS/Azure DevOps), you need to play around with autologin. I haven't got that working yet myself.

Pivotal answered 10/4, 2019 at 19:47 Comment(0)
A
1

Add reference only of "Microsoft.Office.Interop.Excel.dll"

try
{
    //This requires excel app (excel.exe*32) to be running means any excel sheet should be open. If excel not running then it will throw error.
    excelApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
    excelApp.Visible = false;
}
catch
{
    //create new excel instance
    excelApp = new Excel.Application(); 
    excelApp.Visible = false;
}

This worked for me.

Advantage: No need to copy Microsoft.Office.Interop.Excel.dll to your installed folder. Since MS excel is installed it will take from GAC.

I used Office.dll too but not sure if its really required.

Aphonia answered 19/4, 2018 at 5:46 Comment(0)
B
0

I repaired my Visual Studio, and it's fine now!

Bracketing answered 31/1 at 3:6 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Pollock

© 2022 - 2024 — McMap. All rights reserved.