Community
Participate
Working Groups
We have situation: java application tries to open word application. It fails on two computers. But works fine on another two computers. This is sample code: * * * * * Shell shell = new Shell(); OleFrame frame = new OleFrame(shell, SWT.NONE); OleControlSite clientSite = new OleControlSite(frame, SWT.NONE,"Word.Document"); * * * * * Application throws exception: org.eclipse.swt.SWTException: Failed to find requested interface on OLE Object. result = -2147467262 at org.eclipse.swt.ole.win32.OLE.error(OLE.java:312) ... It fails while trying to query interface "COM.IIDIViewObject2". The problem is - it does well on two computers and fails on others two. So, first, we have tried to reinstall word. And we've found another mystic behaviour: if we do not restart computer after installing word - application works fine. If we do restart it - application throws error... So, we wrote test application to see what differences are between these situations. Here is the code we tested: import java.awt.Composite; import org.eclipse.swt.SWTException; import org.eclipse.swt.internal.ole.win32.COM; import org.eclipse.swt.internal.ole.win32.COMObject; import org.eclipse.swt.internal.ole.win32.GUID; import org.eclipse.swt.internal.ole.win32.IMoniker; import org.eclipse.swt.internal.ole.win32.IOleCommandTarget; import org.eclipse.swt.internal.ole.win32.IOleDocument; import org.eclipse.swt.internal.ole.win32.IOleDocumentView; import org.eclipse.swt.internal.ole.win32.IOleInPlaceObject; import org.eclipse.swt.internal.ole.win32.IOleLink; import org.eclipse.swt.internal.ole.win32.IOleObject; import org.eclipse.swt.internal.ole.win32.IPersist; import org.eclipse.swt.internal.ole.win32.IStorage; import org.eclipse.swt.internal.ole.win32.IUnknown; import org.eclipse.swt.internal.ole.win32.IViewObject2; import org.eclipse.swt.internal.ole.win32.OLEINPLACEFRAMEINFO; import org.eclipse.swt.internal.win32.OS; import org.eclipse.swt.internal.win32.RECT; import org.eclipse.swt.ole.win32.OLE; import org.eclipse.swt.ole.win32.OleFrame; import org.eclipse.swt.widgets.Listener; public class TestCOM { public TestCOM() { createCOMInterfaces(); } public static void main(String[] args) { new TestCOM().OleClientSite(null,0,WORDPROGID); } public void OleClientSite(Composite parent, int style, String progId) { // this(parent, style); try { appClsid = getClassID(progId); if (appClsid == null) OLE.error(OLE.ERROR_INVALID_CLASSID); track("appClsid ",appClsid); // Open a temporary storage object tempStorage = createTempStorage(); // Create ole object with storage object int[] address = new int[1]; int result = COM.OleCreate(appClsid, COM.IIDIUnknown, COM.OLERENDER_DRAW, null, 0, tempStorage.getAddress(), address); track("COM.OleCreate",address); if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result); objIUnknown = new IUnknown(address[0]); // Init sinks addObjectReferences(); if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING; } catch (SWTException e) { dispose(); disposeCOMInterfaces(); throw e; } } protected void addObjectReferences() { // int[] ppvObject = new int[1]; if (objIUnknown.QueryInterface(COM.IIDIPersist, ppvObject) == COM.S_OK) { track("COM.IIDIPersist ",ppvObject); IPersist objIPersist = new IPersist(ppvObject[0]); GUID tempid = new GUID(); if (objIPersist.GetClassID(tempid) == COM.S_OK) objClsid = tempid; track("tempid ",tempid); track("objClsid ",objClsid); objIPersist.Release(); } // ppvObject = new int[1]; int result = objIUnknown.QueryInterface(COM.IIDIViewObject2, ppvObject); track("COM.IIDIViewObject2 ",ppvObject); if (result != COM.S_OK) OLE.error(OLE.ERROR_INTERFACE_NOT_FOUND, result); objIViewObject2 = new IViewObject2(ppvObject[0]); objIViewObject2.SetAdvise(aspect, 0, iAdviseSink.getAddress()); // ppvObject = new int[1]; result = objIUnknown.QueryInterface(COM.IIDIOleObject, ppvObject); track("COM.IIDIOleObject ",ppvObject); if (result != COM.S_OK) OLE.error(OLE.ERROR_INTERFACE_NOT_FOUND, result); objIOleObject = new IOleObject(ppvObject[0]); objIOleObject.SetClientSite(iOleClientSite.getAddress()); int[] pdwConnection = new int[1]; objIOleObject.Advise(iAdviseSink.getAddress(), pdwConnection); track("objIOleObject.Advise pdwConnection",pdwConnection); objIOleObject.SetHostNames("main", "main"); //$NON-NLS-1$ //$NON-NLS-2$ // Notify the control object that it is embedded in an OLE container COM.OleSetContainedObject(objIUnknown.getAddress(), true); // Is OLE object linked or embedded? ppvObject = new int[1]; if (objIUnknown.QueryInterface(COM.IIDIOleLink, ppvObject) == COM.S_OK) { IOleLink objIOleLink = new IOleLink(ppvObject[0]); int[] ppmk = new int[1]; if (objIOleLink.GetSourceMoniker(ppmk) == COM.S_OK) { IMoniker objIMoniker = new IMoniker(ppmk[0]); objIMoniker.Release(); type = COM.OLELINKED; objIOleLink.BindIfRunning(); } else { isStatic = true; } objIOleLink.Release(); } } protected int AddRef() { refCount++; return refCount; } protected IStorage createTempStorage() { int[] tempStorage = new int[1]; int grfMode = COM.STGM_READWRITE | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_DELETEONRELEASE; int result = COM.StgCreateDocfile(null, grfMode, 0, tempStorage); track("COM.StgCreateDocfile",tempStorage); if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_FILE, result); return new IStorage(tempStorage[0]); } protected GUID getClassID(String clientName) { // create a GUID struct to hold the result GUID guid = new GUID(); // create a null terminated array of char char[] buffer = null; if (clientName != null) { int count = clientName.length(); buffer = new char[count + 1]; clientName.getChars(0, count, buffer, 0); } if (COM.CLSIDFromProgID(buffer, guid) != COM.S_OK){ int result = COM.CLSIDFromString(buffer, guid); if (result != COM.S_OK) OLE.error(OLE.ERROR_INVALID_CLASSID, result); } return guid; } /** * Deactivates an active in-place object and discards the object's undo state. */ public void deactivateInPlaceClient() { if (objIOleInPlaceObject != null) { objIOleInPlaceObject.InPlaceDeactivate(); } } protected void createCOMInterfaces() { iUnknown = new COMObject(new int[]{2, 0, 0}){ public int method0(int[] args) {return QueryInterface(args[0], args[1]);} public int method1(int[] args) {return AddRef();} public int method2(int[] args) {return Release();} }; iOleClientSite = new COMObject(new int[]{2, 0, 0, 0, 3, 1, 0, 1, 0}){ public int method0(int[] args) {return QueryInterface(args[0], args[1]);} public int method1(int[] args) {return AddRef();} public int method2(int[] args) {return Release();} public int method3(int[] args) {return SaveObject();} // method4 GetMoniker - not implemented public int method5(int[] args) {return GetContainer(args[0]);} public int method6(int[] args) {return ShowObject();} public int method7(int[] args) {return OnShowWindow(args[0]);} // method8 RequestNewObjectLayout - not implemented }; iAdviseSink = new COMObject(new int[]{2, 0, 0, 2, 2, 1, 0, 0}){ public int method0(int[] args) {return QueryInterface(args[0], args[1]);} public int method1(int[] args) {return AddRef();} public int method2(int[] args) {return Release();} public int method3(int[] args) {return OnDataChange(args[0], args[1]);} public int method4(int[] args) {return OnViewChange(args[0], args[1]);} //method5 OnRename - not implemented public int method6(int[] args) {OnSave();return 0;} public int method7(int[] args) {return OnClose();} }; iOleInPlaceSite = new COMObject(new int[]{2, 0, 0, 1, 1, 0, 0, 0, 5, 1, 1, 0, 0, 0, 1}){ public int method0(int[] args) {return QueryInterface(args[0], args[1]);} public int method1(int[] args) {return AddRef();} public int method2(int[] args) {return Release();} public int method3(int[] args) {return GetWindow(args[0]);} public int method4(int[] args) {return ContextSensitiveHelp(args[0]);} public int method5(int[] args) {return CanInPlaceActivate();} public int method6(int[] args) {return OnInPlaceActivate();} public int method7(int[] args) {return OnUIActivate();} public int method8(int[] args) {return GetWindowContext(args[0], args[1], args[2], args[3], args[4]);} public int method9(int[] args) {return Scroll(args[0]);} public int method10(int[] args) {return OnUIDeactivate(args[0]);} public int method11(int[] args) {return OnInPlaceDeactivate();} // method12 DiscardUndoState - not implemented // method13 DeactivateAndUndoChange - not implemented public int method14(int[] args) {return OnPosRectChange(args[0]);} }; iOleDocumentSite = new COMObject(new int[]{2, 0, 0, 1}){ public int method0(int[] args) {return QueryInterface(args[0], args[1]);} public int method1(int[] args) {return AddRef();} public int method2(int[] args) {return Release();} public int method3(int[] args) {return ActivateMe(args[0]);} }; } private void deleteTempStorage() { //Destroy this item's contents in the temp root IStorage. if (tempStorage != null){ tempStorage.Release(); } tempStorage = null; } protected void disposeCOMInterfaces() { if (iUnknown != null) iUnknown.dispose(); iUnknown = null; if (iOleClientSite != null) iOleClientSite.dispose(); iOleClientSite = null; if (iAdviseSink != null) iAdviseSink.dispose(); iAdviseSink = null; if (iOleInPlaceSite != null) iOleInPlaceSite.dispose(); iOleInPlaceSite = null; if (iOleDocumentSite != null) iOleDocumentSite.dispose(); iOleDocumentSite = null; } private int GetContainer(int ppContainer) { /* Simple containers that do not support links to their embedded * objects probably do not need to implement this method. Instead, * they can return E_NOINTERFACE and set ppContainer to NULL. */ if (ppContainer != 0) COM.MoveMemory(ppContainer, new int[]{0}, 4); return COM.E_NOINTERFACE; } int ActivateMe(int pViewToActivate) { return COM.S_OK; } private int CanInPlaceActivate() { return COM.S_FALSE; } private int ContextSensitiveHelp(int fEnterMode) { return COM.S_OK; } protected int GetWindow(int phwnd) { if (phwnd == 0) return COM.E_INVALIDARG; if (frame == null) { COM.MoveMemory(phwnd, new int[] {0}, 4); return COM.E_NOTIMPL; } // Copy the Window's handle into the memory passed in COM.MoveMemory(phwnd, new int[] {frame.handle}, 4); return COM.S_OK; } /* RECT getRect() { Point location = this.getLocation(); Rectangle area = frame.getClientArea(); RECT rect = new RECT(); rect.left = location.x; rect.top = location.y; rect.right = location.x + area.width - borderWidths.left - borderWidths.right; rect.bottom = location.y + area.height - borderWidths.top - borderWidths.bottom; return rect; } */ private int GetWindowContext(int ppFrame, int ppDoc, int lprcPosRect, int lprcClipRect, int lpFrameInfo) { return COM.E_NOTIMPL; } private int OnClose() { return COM.S_OK; } private int OnDataChange(int pFormatetc, int pStgmed) { return COM.S_OK; } private int OnInPlaceActivate() { return COM.S_OK; } private int OnInPlaceDeactivate() { return COM.S_OK; } private int OnPosRectChange(int lprcPosRect) { return COM.S_OK; } private void OnSave() { } private int OnShowWindow(int fShow) { return COM.S_OK; } private int OnUIActivate() { return COM.S_OK; } private int OnUIDeactivate(int fUndoable) { return COM.S_OK; } private int OnViewChange(int dwAspect, int lindex) { return COM.S_OK; } protected int QueryInterface(int riid, int ppvObject) { if (riid == 0 || ppvObject == 0) return COM.E_NOINTERFACE; GUID guid = new GUID(); COM.MoveMemory(guid, riid, GUID.sizeof); if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) { COM.MoveMemory(ppvObject, new int[] {iUnknown.getAddress()}, 4); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIAdviseSink)) { COM.MoveMemory(ppvObject, new int[] {iAdviseSink.getAddress()}, 4); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIOleClientSite)) { COM.MoveMemory(ppvObject, new int[] {iOleClientSite.getAddress()}, 4); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIOleInPlaceSite)) { COM.MoveMemory(ppvObject, new int[] {iOleInPlaceSite.getAddress()}, 4); AddRef(); return COM.S_OK; } // INTENTIONALLY COMMENTED - see bug 35493 // if (COM.IsEqualGUID(guid, COM.IIDIOleDocumentSite )) { // String progID = getProgramID(); // if (!progID.startsWith("PowerPoint")) { //$NON-NLS-1$ // COM.MoveMemory(ppvObject, new int[] {iOleDocumentSite.getAddress()}, 4); // AddRef(); // return COM.S_OK; // } // } COM.MoveMemory(ppvObject, new int[] {0}, 4); return COM.E_NOINTERFACE; } protected int Release() { refCount--; if (refCount == 0) { disposeCOMInterfaces(); } return refCount; } private int SaveObject() { return COM.S_OK; } private int Scroll(int scrollExtant) { return COM.S_OK; } private int ShowObject() { /* Tells the container to position the object so it is visible to * the user. This method ensures that the container itself is * visible and not minimized. */ return COM.S_OK; } public void dispose() { } // Interfaces for this Ole Client Container private COMObject iUnknown; private COMObject iOleClientSite; private COMObject iAdviseSink; private COMObject iOleInPlaceSite; private COMObject iOleDocumentSite; protected GUID appClsid; private GUID objClsid; private int refCount; // References to the associated Frame. protected OleFrame frame; // Access to the embedded/linked Ole Object protected IUnknown objIUnknown; protected IOleObject objIOleObject; protected IViewObject2 objIViewObject2; protected IOleInPlaceObject objIOleInPlaceObject; protected IOleCommandTarget objIOleCommandTarget; protected IOleDocumentView objDocumentView; // Related storage information protected IStorage tempStorage; // IStorage interface of the receiver // Internal state and style information private int aspect; // the display aspect of the embedded object, e.g., DvaspectContent or DvaspectIcon private int type; // Indicates the type of client that can be supported inside this container private boolean isStatic; // Indicates item's display is static, i.e., a bitmap, metafile, etc. private RECT borderWidths = new RECT(); private RECT indent = new RECT(); private boolean inUpdate = false; private boolean inInit = true; private boolean inDispose = false; private static final String WORDPROGID = "Word.Document"; //$NON-NLS-1$ private Listener listener; static final int STATE_NONE = 0; static final int STATE_RUNNING = 1; static final int STATE_INPLACEACTIVE = 2; static final int STATE_UIACTIVE = 3; static final int STATE_ACTIVE = 4; int state = STATE_NONE; public void track(String msg) { System.err.println(msg); } public void track(String msg, GUID guid) { System.err.print(msg); System.err.println(formatGuid(guid)); } public void track(String msg, int[] addr) { System.err.print(msg); System.err.print(" 0x0"); System.err.println(Integer.toHexString(addr[0])); } public static String formatGuid(GUID guid) { StringBuffer sb = new StringBuffer(); sb.append(Integer.toHexString(guid.data3)); sb.append(Integer.toHexString(guid.data2)); sb.append(Integer.toHexString(guid.data1)); sb.append('-'); sb.append(Integer.toHexString(guid.b1)); sb.append(Integer.toHexString(guid.b2)); sb.append(Integer.toHexString(guid.b3)); sb.append('-'); sb.append(Integer.toHexString(guid.b4)); sb.append(Integer.toHexString(guid.b5)); sb.append(Integer.toHexString(guid.b6)); sb.append(Integer.toHexString(guid.b7)); return sb.toString(); } } The results on computers there it works (and on computers there it doesn't work, but after reinstalling word and BEFORE restart) are similar to: appClsid 0020906-000-00046 COM.StgCreateDocfile 0x03070888 COM.OleCreate 0x0a1628 COM.IIDIPersist 0x093038 tempid 0020906-000-00046 objClsid 0020906-000-00046 COM.IIDIOleObject 0x093034 COM.IIDIDataObject 0x093030 COM.IIDIViewObject2 0x0a1e30 And on computers there application doesn't work (and computers there it fails after restart): appClsid 0020906-000-00046 COM.StgCreateDocfile 0x034f0888 COM.OleCreate 0x0a8edc COM.IIDIPersist 0x0aa5fc tempid 0020906-000-00046 objClsid 0020906-000-00046 COM.IIDIOleObject 0x0aa71c COM.IIDIDataObject 0x0aa7ec COM.IIDIViewObject2 0x00 org.eclipse.swt.SWTException: Failed to find requested interface on OLE Object. result = -2147467262 at org.eclipse.swt.ole.win32.OLE.error(OLE.java:312) at TestCOM.addObjectReferences(TestCOM.java:108) at TestCOM.OleClientSite(TestCOM.java:57) at TestCOM.main(TestCOM.java:33) Exception in thread "main" The main difference here is that COM.OleCreate 0x0a1628 is higher than COM.IIDIPersist 0x093038 there application works and COM.OleCreate 0x0a8edc is lower than COM.IIDIPersist 0x0aa5fc there it doesn't work. It seems that application working state depends on whichone is higher.... Any thoughts on this?
I don't think comparing the relative position of VTable addresses in global memory has very much significance. This one still remains a mystery to me. To date, I still have not found a machine in my building that can reproduce this problem to really debug it. Can you verify that the GUID for IVewObject2 is the same on all of your machines? (Look in the registry using regedit or use OleViewer to see the guids). *** This bug has been marked as a duplicate of 21148 ***