Skip to content

Commit

Permalink
Internet Explorer can not be started directly anymore, COM is used as…
Browse files Browse the repository at this point in the history
… workaround
  • Loading branch information
matthiasblaesing committed Apr 20, 2024
1 parent df02193 commit 268b451
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@
package com.sun.jna.platform.win32.COM;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Guid;
import com.sun.jna.platform.win32.Ole32;
import java.util.Iterator;
import java.util.NoSuchElementException;

import com.sun.jna.platform.win32.OleAuto;
import com.sun.jna.platform.win32.Variant;
import com.sun.jna.platform.win32.Variant.VARIANT;
import com.sun.jna.platform.win32.WTypes;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.PointerByReference;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.junit.After;
import org.junit.Before;
Expand All @@ -38,23 +43,48 @@
import static org.junit.Assert.*;

public class ShellApplicationWindowsTest {

private static final Guid.CLSID CLSID_InternetExplorer = new Guid.CLSID("{0002DF01-0000-0000-C000-000000000046}");

static {
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
}

private PointerByReference ieApp;
private Dispatch ieDispatch;

@Before
public void setUp() throws Exception {
Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);

// Launch IE in a manner that should ensure it opens even if the system default browser is Chrome, Firefox, or something else.
Runtime.getRuntime().exec("cmd /c start iexplore.exe -nohome \"about:blank\"");

WinNT.HRESULT hr;

hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
COMUtils.checkRC(hr);

// IE can not be launched directly anymore - so load it via COM

ieApp = new PointerByReference();
hr = Ole32.INSTANCE
.CoCreateInstance(CLSID_InternetExplorer, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ieApp);
COMUtils.checkRC(hr);

ieDispatch = new Dispatch(ieApp.getValue());
InternetExplorer ie = new InternetExplorer(ieDispatch);

ie.setProperty("Visible", true);
COMUtils.checkRC(hr);

VARIANT url = new VARIANT("about:blank");
VARIANT result = ie.invoke("Navigate", url);
OleAuto.INSTANCE.VariantClear(url);
OleAuto.INSTANCE.VariantClear(result);

ieDispatch.Release();

// Even when going to "about:blank", IE still needs a few seconds to start up and add itself to Shell.Application.Windows
// Removing this delay will cause the test to fail even on the fastest boxes I can find.
Thread.sleep(3000);
}

@Test
public void testWindowsCount()
{
Expand All @@ -70,9 +100,13 @@ public void testWindowsCount()
{
// For reasons unknown, Shell.Application.Windows can have null members inside it.
// All I care about is whether or not the collection contains the window I opened.
if (ie != null && "about:blank".equals(ie.getURL()))
if (ie != null)
{
pageFound = true;
String url = ie.getURL();
System.out.println(url);
if("about:blank".equals(ie.getURL())) {
pageFound = true;
}
}
}

Expand All @@ -85,6 +119,7 @@ public void testWindowsCount()
@After
public void tearDown() throws Exception
{
Ole32.INSTANCE.CoUninitialize();
Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
*/
package com.sun.jna.platform.win32;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.COM.COMLateBindingObject;
import com.sun.jna.platform.win32.COM.COMUtils;
import com.sun.jna.platform.win32.COM.Dispatch;
import com.sun.jna.platform.win32.COM.IDispatch;
import com.sun.jna.ptr.PointerByReference;
import java.util.Map;

import org.junit.After;
Expand All @@ -37,13 +43,41 @@ public static void main(String[] args) {
jUnitCore.run(WininetUtilTest.class);
}

private static final Guid.CLSID CLSID_InternetExplorer = new Guid.CLSID("{0002DF01-0000-0000-C000-000000000046}");

private PointerByReference ieApp;
private Dispatch ieDispatch;

@Before
public void setUp() throws Exception {
// Launch IE in a manner that should ensure it opens even if the system
// default browser is Chrome, Firefox, or something else.
// Launching IE to a page ensures there will be content in the WinInet
// cache.
Runtime.getRuntime().exec("cmd /c start iexplore.exe -nomerge -nohome \"http://www.google.com\"");
WinNT.HRESULT hr;

hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
COMUtils.checkRC(hr);

// IE can not be launched directly anymore - so load it via COM

ieApp = new PointerByReference();
hr = Ole32.INSTANCE
.CoCreateInstance(CLSID_InternetExplorer, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ieApp);
COMUtils.checkRC(hr);

ieDispatch = new Dispatch(ieApp.getValue());
LocalLateBinding ie = new LocalLateBinding(ieDispatch);

ie.setProperty("Visible", true);

Variant.VARIANT url = new Variant.VARIANT("http://www.google.com");
Variant.VARIANT result = ie.invoke("Navigate", url);
OleAuto.INSTANCE.VariantClear(url);
OleAuto.INSTANCE.VariantClear(result);

ieDispatch.Release();
Ole32.INSTANCE.CoUninitialize();

// There's no easy way to monitor IE and see when it's done loading
// google.com, so just give it 10 seconds.
Expand Down Expand Up @@ -77,6 +111,24 @@ public void testGetCache() throws Exception {
@After
public void tearDown() throws Exception {
// only kill the freshly opened Google window, unless someone has two IE windows open to Google.
Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe /fi \"windowtitle eq Google*\"");
Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe");
}

private static class LocalLateBinding extends COMLateBindingObject {

public LocalLateBinding(IDispatch iDispatch) {
super(iDispatch);
}

@Override
public void setProperty(String propertyName, boolean value) {
super.setProperty(propertyName, value);
}

@Override
public Variant.VARIANT invoke(String methodName, Variant.VARIANT arg) {
return super.invoke(methodName, arg);
}

}
}

0 comments on commit 268b451

Please sign in to comment.