Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 89974

Summary: [OLE] MSExcel remains as backround process when call by OLE Automation
Product: [Eclipse Project] Platform Reporter: Boris Munivrana <bmunivrana>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: CLOSED WONTFIX QA Contact: Felipe Heidrich <eclipse.felipe>
Severity: normal    
Priority: P3 CC: christian.grimm, dee.adesanwo, Shawn.Peters, snorthov, veronika_irvine
Version: 3.0Keywords: triaged
Target Milestone: ---   
Hardware: PC   
OS: Windows 2000   
Whiteboard: stalebug

Description Boris Munivrana CLA 2005-04-01 11:12:10 EST
I’m using swt.ole.win32  to take advantage of the COM-interfaces for
Office apps MSWord and MSExcel (Note: I have Office 2000 installed,
running on Windows 2000 Professional, Service Pack 3).

What I’m basically doing is writing data from a SWT.Table into a new Word
document (creating a table there) and, of course, into a new Excel
workbook.
With MSWord, everything works like a charm, but MSExcel causes a problem:

When Excel is closed after the operation (writing the data), there still
remains an EXCEL-background process, as one can see switching to the
Windows Taskmanager’s “Processes” tab, and can only be “killed” via the
“End Process”-Menu of the taskmanager.
All this happens even if I dispose all instances of my OleAutomation (even
without doing operations on Excel, just calling the application, this behavior
can be noticed). 
In opposition to that, MSWord REALLY quits after closing the application.

I made a benchmark test using Visual Basic, just to see if Excel behaves
the same way being called remotely, but no, everything worked fine.

Please also note: 
For MSWord, I make use of “Word.Application” as the
OleClientSite’s program id, as it can also be used in Visual Basic (see
CreateObject(“Word.Application”)).
Everything works fine.

Making use of “Excel.Application” with SWT, the processor load rises up to
a 100% and remains at that level, hence I’m using “Excel.Sheet” as progid,
but still there’s the problem with a remaining background process (Note:
closing Excel with it's "End"-Menu or invoking the "Quit"-Method remotely
via DispatchInterface doesn't make any difference).

Will this bug be fixed?
Comment 1 Dee Adesanwo CLA 2008-07-25 18:41:27 EDT
Although this Bug is 3 yrs old, has anyone come up with a solution? I have tried to implement this method of closing excel[1] but the process still stays. Any help would be greatly appreciated. 

[1]http://pointlessly.blogspot.com/2007/05/kill-excel-in-automation.html
Comment 2 Duong Nguyen CLA 2008-07-28 12:08:15 EDT
Do you see this problem when you run the Excel example (Snippet261)? I'm running on XP with Office 2003 and I don't see this problem.
Comment 3 Dee Adesanwo CLA 2008-07-28 15:10:20 EDT
Thanks Duong for your response.

I don't see the issue when I run the excel example Snippet261 as java application. I modified the example code so I could call it from an RCP application 'Snippet261.main()':

import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.ole.win32.*;
import org.eclipse.swt.widgets.*;

public class Snippet261 
{
    public static void main() 
    {
        Shell shell = new Shell();
        shell.setText("Excel Example");
        shell.setLayout(new FillLayout());
        OleAutomation tempClientSite, application;
        try {
            OleFrame frame = new OleFrame(shell, SWT.NONE);
            OleClientSite clientSite = new OleClientSite(frame, SWT.NONE, "Excel.Sheet");
            addFileMenu(frame);
            
            tempClientSite = new OleAutomation(clientSite);            
            int methodIds[];
            methodIds = tempClientSite.getIDsOfNames(new String[] { "Application" });            
            application = tempClientSite.getProperty(methodIds[0]).getAutomation();
            
            
            
        } catch (SWTError e) {
            System.out.println("Unable to open activeX control");
            return;
        }
        shell.setSize(800, 600);
        shell.open();
        
        while (!shell.isDisposed()) {
            if (!shell.getDisplay().readAndDispatch())
                shell.getDisplay().sleep();
        }
        
        application.dispose();
        tempClientSite.dispose();
        
    }
    
    static void addFileMenu(OleFrame frame) {
        final Shell shell = frame.getShell();
        Menu menuBar = new Menu(shell, SWT.BAR);
        shell.setMenuBar(menuBar);
        MenuItem fileMenu = new MenuItem(menuBar, SWT.CASCADE);
        fileMenu.setText("&File");
        Menu menuFile = new Menu(fileMenu);
        fileMenu.setMenu(menuFile);
        MenuItem menuFileControl = new MenuItem(menuFile, SWT.CASCADE);
        menuFileControl.setText("Exit");
        menuFileControl.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                shell.dispose();
            }
        });
        frame.setFileMenus(new MenuItem[] { fileMenu });
    }
}

The issue I'm having is when I create the "application" OleAutomation object, the excel process still remains in memory even if I dispose it. I am creating the application object to get the version of excel and also get other objects such as the ActiveWorkbook and WorkSheets. I'm running Vista with Office 2007. If I don't create the Oleautomation object then the excel process goes away on close.

Another funny thing is, that if I create the object in the original Snippet261.java example code by adding this to the main method:

OleAutomation tempClientSite, application;
            tempClientSite = new OleAutomation(clientSite);            
            int methodIds[];
            methodIds = tempClientSite.getIDsOfNames(new String[] { "Application" });            
            application = tempClientSite.getProperty(methodIds[0]).getAutomation();

The excel process does not remain after I close the shell window. I am truly perplexed?

Comment 4 Duong Nguyen CLA 2008-07-28 15:59:21 EDT
Do you have an example (a snippet of code) that you can include to show the problem? I tried changing the example to "Excel.Application" but it would open the excel sheet outside of SWT in its own application. The EXCEL process remains when I close the SWT shell. Excel goes away only when I close both SWT shell and the external application which make sense.

I'm just wondering if your application is not disposing one of the automation or some how the Excel application is still running.
Comment 5 Dee Adesanwo CLA 2008-07-28 17:26:52 EDT
If you leave the previous snippet as "Excel.Sheet" and call it through an RCA app, then you should see the problem. Using "Excel.Application" works fine, but causes the CPU usage to jump to 50% - 100% (depending on your CPU - dual or single). 

You were right about the application not disposing an object; I discovered that in the previous snippet: the Variant object that gets created when I invoke "tempClientSite.getProperty(methodIds[0])" was causing the excel process to remain. I'm assuming that a temporary variant object gets created, but is not disposed. So if I changed

application = tempClientSite.getProperty(methodIds[0]).getAutomation();

to

Variant applicationV = tempClientSite.getProperty(methodIds[0]);
application = applicationV.getAutomation();

and disposed of the applicationV object, then the process closses.

Now I have another issue, when I close my RCP app, excel also closes because I dispose of the OLE objects. Is there away to cause Excel to dispose of these objects when the user clicks close in excel i.e my controlSite object listens for the close event from excel then disposes of itself?



Comment 6 Duong Nguyen CLA 2008-07-29 14:15:54 EDT
I'm not sure if I understand your last comment about clicking to close excel. Do you mean when you use "Excel.Application" and you close the last Excel sheet that you want the Excel application to close? If you use "Excel.Sheet", and you close it, the EXCEL process goes away.
Comment 7 Dee Adesanwo CLA 2008-07-31 11:06:56 EDT
I'm not sure if I understand your last comment about clicking to close excel.
Do you mean when you use "Excel.Application" and you close the last Excel sheet
that you want the Excel application to close? If you use "Excel.Sheet", and you
close it, the EXCEL process goes away.

Sorry for the confusion, I meant when I close my RCP application I don't want excel to close. The only way I can think of doing this is to not disposing the controlSite object of Excel, causing "Excel.Sheet" to remain open and in the process tree.

When I close Excel, the process is still there and I was wondering if I could add a listerner to the controlSite object so that it disposes of it self when an Excel event is triggered. Something along the lines of this:

final static int WorkbookBeforeClose = 0x00000622;
final String IID_AppEvents = "{00024413-0000-0000-C000-000000000046}";
//I believe this is the ID is for excel.

controlSite = new OleControlSite(new OleFrame(shell, SWT.NO_BACKGROUND), SWT.NONE, "Excel.Sheet");
final Variant applicationV = getVariant(controlSite, "Application");
application = applicationV.getAutomation();

//getVariant is a method i wrote in my java class.


 controlSite.addEventListener
(application, IID_AppEvents, WorkbookBeforeClose, new OleListener()
{
    public void handleEvent(OleEvent event)
        controlSite.dispose();
});

I tried it but I it doesn't work. I'm guessing there is not way to dispose of an object created in a RCP app once that app has closed, or is there?
Comment 8 Duong Nguyen CLA 2008-07-31 13:57:59 EDT
I'm not sure if that's necessary. In your RCP application you can open another root shell (new Shell(display)) for your Excel sheet. In fact you can have several of these shells open. You would need a global counter to keep track of the number of shells you have opened. For each shell, you would have a dispose listener to decrement the counter when the shell is closed.

Your main read and dispatch loop will terminate and dispose the display when the counter reaches zero (when the last shell is disposed).

		while (shellCount > 0) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();

Would this work for you?
Comment 9 Duong Nguyen CLA 2008-07-31 14:02:39 EDT
Shawn, I added you to this bug because the discussion here is similar to the one that were talking about in bug #128841. Besides, the other bug is already resolved and this one is still open. Please read my comment #8.
Comment 10 Felipe Heidrich CLA 2009-08-13 09:28:36 EDT
Your bug has been moved to triage, visit http://www.eclipse.org/swt/triage.php for more info.
Comment 11 Leo Ufimtsev CLA 2017-08-03 12:32:11 EDT
This is a one-off bulk update. (The last one in the triage migration).

Moving bugs from swt-triaged@eclipse to platform-swt-inbox@eclipse.org and adding "triaged" keyword as per new triage process:
https://wiki.eclipse.org/SWT/Devel/Triage

See Bug 518478 for details.

Tag for notification/mail filters:
@TriageBulkUpdate
Comment 12 Eclipse Genie CLA 2019-12-15 13:16:41 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.