簡體   English   中英

OLE 自動化 - 任務管理器中的 Ghost Excel 實例

[英]OLE Automation - Ghost Excel Instance in Task Manager

我正在使用wxAutomationObject將數據導出到 MS Excel。 我創建了一些幫助類 ExcelApp、ExcelWorkbook 等......所有這些都繼承自wxAutomationObject

簡而言之,ExcelApp如下:

class ExcelApp :public wxAutomationObject
{

    public:

        ExcelApp(WXIDISPATCH* dispatchPtr = NULL);

        ~ExcelApp() = default;

        
        void Quit();

        std::unique_ptr<ExcelWorkbook> CreateWorkbook(bool Visible = true);

        std::vector<std::unique_ptr<ExcelWorkbook>> GetOpenedWorkbooks();

        long GetNumberofOpenedWorkbooks() const;


    private:
        wxAutomationObject m_App;   
};

構造函數實現如下:

ExcelApp::ExcelApp(WXIDISPATCH* dispatchPtr):wxAutomationObject(dispatchPtr)
{
        if (!m_App.GetInstance("Excel.Application"))
            throw std::exception("An instance of Excel object could not be created.");
}

為了創建一個工作簿,我曾經使用以下代碼:

std::unique_ptr<ExcelWorkbook> ExcelApp::CreateWorkbook(bool Visible)
{
        auto wb = std::make_unique<ExcelWorkbook>();

        bool suc = m_App.GetObject(*wb, "Workbooks.Add");

        if (!suc)
            return nullptr;


        if (Visible)
            m_App.PutProperty("Visible", true);

        
        return std::move(wb);
}

這整個 OLE 實現是動態菜單的一部分。 菜單事件處理程序的部分代碼是:

void MyFrame::OnExportToExcelButtonHandler(wxCommandEvent& event)
{
    
        auto item = static_cast<wxMenu*>(event.GetEventObject());

        std::unique_ptr<ExcelWorkbook> xlsWB ((ExcelWorkbook*)event.GetEventUserData());

        
        bool CreateNewWB = false;
    
        try
        {
            

            //Export either the entire workbook or the active worksheet to a new Workbook
            if (xlsWB == nullptr)
            {
                auto xlsApp = ExcelApp(); 

                xlsWB = std::move(xlsApp.CreateWorkbook());

                CreateNewWB = true;
            }

在導出數據和格式化方面,一切正常。 但是,關閉創建的 Workbooks 后Excel.exe 仍然保留在任務欄列表中。 我想知道我可能會錯過什么?

順便說一句,我嘗試了 wxWidgets 附帶的非常基本的示例,退出后似乎沒有 Excel 的幽靈實例。

我使用 VS 2019 在 Windows 10 上使用 wxWidgets 3.1.4。

編輯1:

生成動態菜單的功能區按鈕:

void MyFrame::OnExportToExcelButtonClicked(wxRibbonButtonBarEvent& event)
{
    auto excel = sys::win32::ole::ExcelApp();


        auto PrepareMenu = [&](wxMenu* Menu)
        {

            try
            {
                

                wxMenuItem* item1 = Menu->Append(wxID_ANY, "New Excel Workbook");
                item1->SetBitmap(wxArtProvider::GetBitmap(wxART_NEW));

                Bind(wxEVT_COMMAND_MENU_SELECTED, &MyFrame::OnExportToExcelButtonHandler, this, item1->GetId());


                auto wbs = excel.GetOpenedWorkbooks();

                if (wbs.size() > 0)
                {
                    for (int i = 0; i < wbs.size(); ++i)
                    {
                        auto ExcelWB = std::move(wbs[i]);

                        wxMenuItem* item1 = Menu->Append(wxID_ANY, ExcelWB->GetFullName());

                        Bind(wxEVT_COMMAND_MENU_SELECTED, &MyFrame::OnExportToExcelButtonHandler, this, item1->GetId(), wxID_ANY, ExcelWB.release());

                        
                    }
                }

            }
}

問題似乎源於以下行:

Bind(wxEVT_COMMAND_MENU_SELECTED, &MyFrame::OnExportToExcelButtonHandler, this, item1->GetId(), wxID_ANY, ExcelWB.release());

ExcelWB指針現在歸 wxWidgets 系統所有,因此保留了一個引用,因此保留了幽靈 Excel.exe。

為了解決這個問題,我在以下過程中添加了:

void MyFrame::OnExportToExcelButtonHandler(wxCommandEvent& event)
{
    Unbind(wxEVT_COMMAND_MENU_SELECTED, &MyFrame::OnExportToExcelButtonHandler, this, event.GetId(), wxID_ANY, xlsWB.get());

但問題仍然存在。 我不確定如何正確擺脫菜單現在擁有的指針。 我用 shared_ptr 重新設計了一些部分,但沒有幫助。

你可能已經這樣做了,但只是為了確定。

調試此類事情時,請確保應用程序實例始終可見,以便您可以看到它何時卡住等待用戶輸入,例如,要求保存修改后的工作簿,防止它退出。

我已經編寫了基於 wxWidgets 的 MS Excel 自動化包裝器wxAutoExcel (它對 Excel 對象使用共享指針而不是唯一指針),並且我從未遇到過應用程序幽靈,除非我在調試時終止了我的應用程序,而沒有處理 ZC1D81AF563E58D4ED8FDCZD9 對象。

順便說一句,我不明白為什么您的ExcelApp都派生自wxAutomationObject並將wxAutomationObject作為成員變量( m_App )。 ExcelApp ctor 中使用的IDispatch有什么用?

最后,似乎我使用以下步驟解決了這個問題:

  1. 現在使用對話框而不是菜單 因此,菜單不再擁有指針。
  2. 所有wxAutomationObject繼承對象都通過 std::unique_ptr 傳遞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM