none
Excel Protected View Crashing - C++ COM usage when Closing Workbook. RRS feed

  • Question

  • I have a Windows application written in C++ that is retrieving the existing instance of the Excel open on the machine.

    My configuration: Windows executable (not service) 32-bit compilation, VS 2017, Win10. Excel version:  Professional Plus 2016, 1803 version, Build 9126.2152 32-bit.

    1) I am getting the currently running Excel process by calling EnumChildWindows and targeting EXCEL7 window class. I am calling AccessibleObjectFromWindowfunction with hwnd of class type EXCEL7 .

    2) This coded crashes the Excel process only in Protected View. If the opened Excel file is not in Protected View, it works ok.

            Excel::_ApplicationPtr pApp;
    IDispatch *pTemp = NULL; // hwnd is EXCEL7.
    HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(IDispatch), (void**)&pTemp);
    if (hr == S_OK)
    {
    Excel::WindowPtr windowPtr(pTemp);
    if (windowPtr != NULL)
    {
    pApp = windowPtr->GetApplication();
    auto workbook = pApp->Workbooks->GetItem(1);
    if (workbook)
    workbook->Close(); // Excel crashes for Protected View. Close returns S_OK.
    }

    }

    Did anyone experienced such problem?

    Sunday, April 22, 2018 11:40 AM

All replies

  • You need to find sample code for using Excel the right way. Excel and the other Office applications were not designed to be used by using EnumChildWindows. You need to create an instance of Excel and then enumerate the workbooks to find the one you need.


    Sam Hobbs
    SimpleSamples.Info

    Sunday, April 22, 2018 5:34 PM
  • This seems to be a roundabout method of obtaining an interface pointer for the Excel.Application object instantiated by a running instance.  You should use GetActiveObject.
    Sunday, April 22, 2018 8:29 PM
  • The COM object you get back from a protected window with your call to AccessibleObjectFromWindow is not an Excel  Window object as you usually get, but is instead a ProtectedViewWindow object.

    The ProtectedViewWindow does not have an Application property, hence the error you get when you call Window.Application. Instead you can call ProtectedViewWindow.Workbook.Application - that should give you an Application object.

    Note that the Application object that you get back from a protected window is only partially functional. You can read some stuff from it, but methods like Application.Run will fail. Also, this COM object is somehow no longer valid after the protected windows close and you open a normal Workbook. So it will depend on your context whether this Application object is useful, and you certainly want to be careful with it during a longer Excel session.

    -Govert

    Excel-DNA - Free and easy .NET for Excel

    Sunday, April 22, 2018 11:06 PM
  • There may be multiple Excel processes running. GetActiveObject will only give you the Application COM object from one of these - typically the one last started as it gets registered in the COM Running Object Table. If you want to get the Excel.Application object from a particular process (e.g. if you are an Excel add-in and you want the Application COM object for the process you're running in) then GetActiveObject does not help.

    -Govert

    Excel-DNA - Free and easy .NET for Excel

    Sunday, April 22, 2018 11:11 PM
  • There may be multiple Excel processes running. GetActiveObject will only give you the Application COM object from one of these - typically the one last started as it gets registered in the COM Running Object Table. If you want to get the Excel.Application object from a particular process (e.g. if you are an Excel add-in and you want the Application COM object for the process you're running in) then GetActiveObject does not help.

    The OP wrote "I have a Windows application written in C++ that is retrieving the existing instance of the Excel open on the machine."

    There was no mention of multiple instances of Excel running and the question was not about an add-in.

    Sunday, April 22, 2018 11:32 PM
  • Not sure how your answer is related. I am trying to get an Application pointer to an existing instance of Excel.
    AccessibleObjectFromWindow expects HWND as a parameter, which returns a valid pointer to Excel::WindowPtr.

    This code works perfectly for Excel without a protected window.


    Monday, April 23, 2018 7:51 AM
  • GetActiveObject will not work in case of multiple Excel processes running.
    Monday, April 23, 2018 7:51 AM
  • Thanks for the reply. I tried getting ProtectedViewWindow.Workbook.Application, still get the crash when I try to Close the workbook.
    Monday, April 23, 2018 7:53 AM
  • Hi EyalMolad,

    Did you try to test your code with different version of Excel?

    Please try to make a test and check whether it works or generate the same error.

    It can help us to narrow down the issue.

    It can be possible that this version has some issue cause this error.

    So for testing purpose, You can try to remove this update and move to previous update and test the code.

    Let us know about the result.

    We will try to provide further suggestions, If needed.

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 23, 2018 9:11 AM
    Moderator
  • I just tried with Excel 2010. 64-Bit.  14.0.7195.5000 on Win7.

    The Protected View Excel crashes after a call to Close.

    Monday, April 23, 2018 10:07 AM