Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to feature test for window.ActiveXObject?

3,502 views
Skip to first unread message

Christoph Michael Becker

unread,
Nov 16, 2013, 2:24:27 PM11/16/13
to
In IE11 (JScript 11.0? -- I was not able to find out the exact version)
the following is true[1]:

typeof window.ActiveXObject == "undefined"

This causes isHostMethod()[2] to fail. Is there a reliable solution to
detect if the window object has an ActiveXObject method, without
actually /try/ing to instantiate a new ActiveXObject?

[1] <http://msdn.microsoft.com/en-us/library/ff955298(v=vs.85).aspx>
[2]
<http://michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting>

--
Christoph M. Becker

Thomas 'PointedEars' Lahn

unread,
Nov 16, 2013, 6:08:02 PM11/16/13
to
Christoph Michael Becker wrote:

> In IE11

Fascinating.

> (JScript 11.0? -- I was not able to find out the exact version)

Relevant JScript versions for which results have been submitted to the
ECMAScript Support Matrix are so far

- Version 11.0.16412 in "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0;
Touch; rv:11.0) like Gecko"

(presumably, Internet Explorer 11 on a smartphone or tablet, as indicated
by “Touch”)

- Version 11.0.16428 in
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"

(presumably, Internet Explorer 11 on a PC without a touchscreen)

You can use (much like I did)

ScriptEngine() + " " + [
ScriptEngineMajorVersion(),
ScriptEngineMinorVersion(),
ScriptEngineBuildVersion()
].join(".")

See also <http://PointedEars.de/es-matrix#footnote-this-impl>, and the
corresponding test cases.

> the following is true[1]:
>
> typeof window.ActiveXObject == "undefined"

You should not presume that “ActiveXObject” is a property of the object
referred to by “window”. In general, “window” should not be used for a
reference to the ECMAScript Global Object (use “this” in the global
execution context instead). Test for exactly that which you are using
later. If you want to call “new ActiveXObject” later, test for
“ActiveXObject”, not “window.ActiveXObject”.

That said, is “new ActiveXObject(…)” or “new window.ActiveXObject(…)”
supported then? If not, everything works as designed. “ActiveXObject” is a
very old feature which repeatedly introduced security leaks in MSHTML-based
applications and Windows; I would not be surprised if it was finally removed
from the JScript language as a result. For example, “file:” URIs aside, you
do not need “ActiveXObject” for XHR in recent JScript versions; use “new
XMLHttpRequest()” instead (like almost everywhere else).

> This causes isHostMethod()[2] to fail.

AFAICS (I have just tested this positive in IE 6.0.2800.1106 on Wine XP
which can create, for example, "Microsoft.XMLHTTP" objects), “ActiveXObject”
always referred to a *native* method, and yielded "function" (not "unknown")
as result of a “typeof“ operation. AFAIK it is a built-in JScript feature
even though it creates only host objects, and is therefore tested with the
ES Matrix.

> Is there a reliable solution to detect if the window object has an
> ActiveXObject method, without actually /try/ing to instantiate a new
> ActiveXObject?

Depends. try…catch at least is the only reliable way to determine whether a
host object of a certain class (sic!; as in CLSID) can be successfully
created when “ActiveXObject” is called as a constructor where try…catch is
supported (that would apply to these versions of JScript).
There are three versions of isHostMethod() there – which one have you used?
JSX:object.js has another one. However, following my argument above, Peter
Michaux’s argument is flawed and none of those methods should be used on
“ActiveXObject”.

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

JJ

unread,
Nov 16, 2013, 7:27:17 PM11/16/13
to
On Sat, 16 Nov 2013 20:24:27 +0100, Christoph Michael Becker wrote:
> window.ActiveXObject

Can you inspect and compare the property descriptor between ActiveXObject
and a non exsistent property? Like this:

var ax = Object.getOwnPropertyDescriptor(window, "ActiveXObject");
var na = Object.getOwnPropertyDescriptor(window, "dontExist");

You may need to use te Developer Tools to inspect/watch those variables.

I don't know about IE9+, but in IE8, ax and na will have different
properties. If they are in IE11, please post them here, cause I would like
to know too.

Christoph Michael Becker

unread,
Nov 18, 2013, 7:25:28 AM11/18/13
to
Thomas 'PointedEars' Lahn wrote:

> Christoph Michael Becker wrote:
>
>> In IE11
>
> Fascinating.

-v, please.

>> (JScript 11.0? -- I was not able to find out the exact version)
>
> Relevant JScript versions for which results have been submitted to the
> ECMAScript Support Matrix are so far
>
> - Version 11.0.16412 in "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0;
> Touch; rv:11.0) like Gecko"
>
> (presumably, Internet Explorer 11 on a smartphone or tablet, as indicated
> by “Touch”)
>
> - Version 11.0.16428 in
> "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
>
> (presumably, Internet Explorer 11 on a PC without a touchscreen)
>
> You can use (much like I did)
>
> ScriptEngine() + " " + [
> ScriptEngineMajorVersion(),
> ScriptEngineMinorVersion(),
> ScriptEngineBuildVersion()
> ].join(".")

Thanks. :)

> See also <http://PointedEars.de/es-matrix#footnote-this-impl>, and the
> corresponding test cases.

This reports now:

| This user agent:
| Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR
| 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC
| 6.0; .NET4.0C; rv:11.0) like Gecko
|
| This ECMAScript implementation:
| undefined

However, the version number string algorithm given by you, says:

| JScript 11.0.16428

On Saturday, when I submitted the results on the ES matrix, it must have
been:

"JScript 11.0.16428" on
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko

(I have gotten some Windows updates in the meantime.)

>> the following is true[1]:
>>
>> typeof window.ActiveXObject == "undefined"
>
> You should not presume that “ActiveXObject” is a property of the object
> referred to by “window”. In general, “window” should not be used for a
> reference to the ECMAScript Global Object (use “this” in the global
> execution context instead). Test for exactly that which you are using
> later. If you want to call “new ActiveXObject” later, test for
> “ActiveXObject”, not “window.ActiveXObject”.

ACK. Thanks.

> That said, is “new ActiveXObject(…)” or “new window.ActiveXObject(…)”
> supported then? If not, everything works as designed.

That is exactly the point. Calling ActiveXObject() works as expected,
but the ActiveXObject property is undefined.

It occurs to me, Microsoft has done this to cater for scripts using
unrelated existence inference ( if (ActiveXObject) // assume IE ).
IMVHO that doesn't seem to be prudent.

> “ActiveXObject” is a
> very old feature which repeatedly introduced security leaks in MSHTML-based
> applications and Windows; I would not be surprised if it was finally removed
> from the JScript language as a result. For example, “file:” URIs aside, you
> do not need “ActiveXObject” for XHR in recent JScript versions; use “new
> XMLHttpRequest()” instead (like almost everywhere else).

I try to avoid ActiveXObject generally, but I stumbled over the issue in
a third party library, which deals with parsing XML, and tries to
fallback on ActiveXObjects when XSLTProcessor is not available.

>> This causes isHostMethod()[2] to fail.
>
> AFAICS (I have just tested this positive in IE 6.0.2800.1106 on Wine XP
> which can create, for example, "Microsoft.XMLHTTP" objects), “ActiveXObject”
> always referred to a *native* method, and yielded "function" (not "unknown")
> as result of a “typeof“ operation. AFAIK it is a built-in JScript feature
> even though it creates only host objects, and is therefore tested with the
> ES Matrix.

I hadn't even noticed the test for new ActiveXObject() there -- however,
the matrix reports:

| Test 1: failed

>> Is there a reliable solution to detect if the window object has an
>> ActiveXObject method, without actually /try/ing to instantiate a new
>> ActiveXObject?
>
> Depends. try…catch at least is the only reliable way to determine whether a
> host object of a certain class (sic!; as in CLSID) can be successfully
> created when “ActiveXObject” is called as a constructor where try…catch is
> supported (that would apply to these versions of JScript).

ACK. However, I was hoping to be able to test for existance of the
ActiveXProperty before actually trying to call it.

>> [1] <http://msdn.microsoft.com/en-us/library/ff955298(v=vs.85).aspx>
>> [2]
>> <http://michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting>
>
> There are three versions of isHostMethod() there – which one have you used?

The one in the section called "A good set of host object testing functions".

> JSX:object.js has another one. However, following my argument above, Peter
> Michaux’s argument is flawed and none of those methods should be used on
> “ActiveXObject”.

That was probably my mistake. Peter Michaux doesn't mention this
particular test in the article.

--
Christoph M. Becker

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2013, 12:52:35 PM11/18/13
to
Christoph Michael Becker wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Christoph Michael Becker wrote:
>>> In IE11
>> Fascinating.
>
> -v, please.

I was not aware that there is a new version.

>> See also <http://PointedEars.de/es-matrix#footnote-this-impl>, and the
>> corresponding test cases.
>
> This reports now:
>
> | This user agent:
> | Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR
> | 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC
> | 6.0; .NET4.0C; rv:11.0) like Gecko
> |
> | This ECMAScript implementation:
> | undefined

Thank you, fixed. See below.

With IE/MSHTML/JScript (6 and – possibly through – 9) there is still one bug
that I could not find the reason for and fix yet:

| SCRIPT1002: Syntax error
| es-matrix, line 1294 character 1

(translated from German)

Do you see it?

> However, the version number string algorithm given by you, says:
>
> | JScript 11.0.16428
>
> On Saturday, when I submitted the results on the ES matrix, it must have
> been:
>
> "JScript 11.0.16428" on
> "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
>
> (I have gotten some Windows updates in the meantime.)

I have also updated the Matrix in the meantime to sort “new ActiveXObject”
(and similar code) under “A” (first letter of the constructor identifier),
not “N”. This appears to have awoken, through cache control (later Last-
Modified date etc.), a sleeping refactoring bug in JSX:engine.js
(responsible for implementation and version detection) that is fixed now.

>>> the following is true[1]:In
>>>
>>> typeof window.ActiveXObject == "undefined"
>>
>> […]
>> That said, is “new ActiveXObject(…)” or “new window.ActiveXObject(…)”
>> supported then? If not, everything works as designed.
>
> That is exactly the point. Calling ActiveXObject() works as expected,
> but the ActiveXObject property is undefined.
>
> It occurs to me, Microsoft has done this to cater for scripts using
> unrelated existence inference ( if (ActiveXObject) // assume IE ).
> IMVHO that doesn't seem to be prudent.

ACK. In that case I would have to update JSX:http.js because it uses the
“typeof” test through jsx.object.isMethod(). Presumably, several other
people would have to update their libraries as well (or decide to screw
IE 11 and make Micro$~1 come to their senses – but that is not likely to
happen).

>> “ActiveXObject” is a very old feature which repeatedly introduced
>> security leaks in MSHTML-based applications and Windows; I would not be
>> surprised if it was finally removed from the JScript language as a
>> result. For example, “file:” URIs aside, you do not need “ActiveXObject”
>> for XHR in recent JScript versions; use “new XMLHttpRequest()” instead
>> (like almost everywhere else).
>
> I try to avoid ActiveXObject generally, but I stumbled over the issue in
> a third party library, which deals with parsing XML, and tries to
> fallback on ActiveXObjects when XSLTProcessor is not available.

ACK.

>>> This causes isHostMethod()[2] to fail.
>>
>> AFAICS (I have just tested this positive in IE 6.0.2800.1106 on Wine XP
>> which can create, for example, "Microsoft.XMLHTTP" objects),
>> “ActiveXObject” always referred to a *native* method, and yielded
>> "function" (not "unknown") as result of a “typeof“ operation. AFAIK it
>> is a built-in JScript feature even though it creates only host objects,
>> and is therefore tested with the ES Matrix.
>
> I hadn't even noticed the test for new ActiveXObject() there -- however,
> the matrix reports:
>
> | Test 1: failed

That was to be expected. I would have to use try…catch now if “typeof” did
not work. (A test for functionality appears to be impossible because I
cannot know which COM server names and type names are available.)

>>> Is there a reliable solution to detect if the window object has an
>>> ActiveXObject method, without actually /try/ing to instantiate a new
>>> ActiveXObject?
>>
>> Depends. try…catch at least is the only reliable way to determine
>> whether a host object of a certain class (sic!; as in CLSID) can be
>> successfully created when “ActiveXObject” is called as a constructor
>> where try…catch is supported (that would apply to these versions of
>> JScript).
>
> ACK. However, I was hoping to be able to test for existance of the
^e
> ActiveXProperty before actually trying to call it.
^^^^^^^^Object property

You could do

try
{
ActiveXObject
}
catch (e)
{
/* no ActiveXObject */
}

but since you have to do

var o = null;

try
{
o = new ActiveXObject("…");
}
catch (e)
{
// …
}

anyway, the former does not make much sense. It might even throw an
exception even if “ActiveXObject” is supported because the method was used
wrong. It walks like a native method, but we can see in the MSDN Library
that it quacks rather strangely.

>>> [1] <http://msdn.microsoft.com/en-us/library/ff955298(v=vs.85).aspx>
>>> [2]
>>> <http://michaux.ca/articles/feature-detection-state-of-the-art-browser->>> scripting>
>>
>> There are three versions of isHostMethod() there – which one have you
>> used?
>
> The one in the section called "A good set of host object testing
> functions".

As you can see, one can do better.

>> JSX:object.js has another one. However, following my argument above,
>> Peter Michaux’s argument is flawed and none of those methods should be
>> used on “ActiveXObject”.
>
> That was probably my mistake. Peter Michaux doesn't mention this
> particular test in the article.

ACK.

Martin Honnen

unread,
Nov 18, 2013, 1:29:31 PM11/18/13
to
Christoph Michael Becker wrote:

> That is exactly the point. Calling ActiveXObject() works as expected,
> but the ActiveXObject property is undefined.
>
> It occurs to me, Microsoft has done this to cater for scripts using
> unrelated existence inference ( if (ActiveXObject) // assume IE ).
> IMVHO that doesn't seem to be prudent.

http://msdn.microsoft.com/en-us/library/ff955298%28v=vs.85%29.aspx says
"For IE11 Mode in Internet Explorer 11, ActiveXObject is supported as
described in this section except that ActiveXObject detection will fail
when performed within a conditional statement.".

So it looks like they are doing the same that Mozilla used to do with
document.all, that is support its use but don´t support feature checks
on it.

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2013, 1:35:27 PM11/18/13
to
Only that Mozilla’s move to suddenly support document.all when it was
already phased out of MSHTML was a stupid one to begin with.

Your apostrophes are accents.

Christoph Michael Becker

unread,
Nov 21, 2013, 5:44:32 PM11/21/13
to
Thomas 'PointedEars' Lahn wrote:

> Christoph Michael Becker wrote:
>
>> Thomas 'PointedEars' Lahn wrote:
>>
>> That is exactly the point. Calling ActiveXObject() works as expected,
>> but the ActiveXObject property is undefined.
>>
>> It occurs to me, Microsoft has done this to cater for scripts using
>> unrelated existence inference ( if (ActiveXObject) // assume IE ).
>> IMVHO that doesn't seem to be prudent.
>
> ACK. In that case I would have to update JSX:http.js because it uses the
> “typeof” test through jsx.object.isMethod(). Presumably, several other
> people would have to update their libraries as well (or decide to screw
> IE 11 and make Micro$~1 come to their senses – but that is not likely to
> happen).

Indeed, that is highly unlikely -- after all, IE 11 is the first version
to support ECMAScript strict mode, AFAIK.

>> ACK. However, I was hoping to be able to test for existance of the
> ^e
>> ActiveXProperty before actually trying to call it.
> ^^^^^^^^Object property

Thanks for the corrections. :)

> You could do
>
> try
> {
> ActiveXObject
> }
> catch (e)
> {
> /* no ActiveXObject */
> }
>
> but since you have to do
>
> var o = null;
>
> try
> {
> o = new ActiveXObject("…");
> }
> catch (e)
> {
> // …
> }
>
> anyway, the former does not make much sense. It might even throw an
> exception even if “ActiveXObject” is supported because the method was used
> wrong. It walks like a native method, but we can see in the MSDN Library
> that it quacks rather strangely.

ACK.

>>> There are three versions of isHostMethod() there – which one have you
>>> used?
>>
>> The one in the section called "A good set of host object testing
>> functions".
>
> As you can see, one can do better.

Unfortunately, not perfectly, though, in the sense to know in advance
what browser vendors might do in the future.

--
Christoph M. Becker

Thomas 'PointedEars' Lahn

unread,
Nov 21, 2013, 6:32:28 PM11/21/13
to
Christoph Michael Becker wrote:

> Thomas 'PointedEars' Lahn wrote:
>> You could do
>>
>> try
>> {
>> ActiveXObject
>> }
>> catch (e)
>> {
>> /* no ActiveXObject */
>> }
>>
>> but since you have to do
>>
>> var o = null;
>>
>> try
>> {
>> o = new ActiveXObject("…");
>> }
>> catch (e)
>> {
>> // …
>> }
>>
>> anyway, the former does not make much sense. It might even throw an
>> exception even if “ActiveXObject” is supported because the method was
>> used wrong. It walks like a native method, but we can see in the MSDN
>> Library that it quacks rather strangely.
>
> ACK.

On second thought, if the former approach does work in IE 10 and 11, or if
you do know another approach that works there, please tell. I can then test
whether it works in previous versions also, and we may eventually not only
have a way to work around the recent Microsoft nonsense, but also to detect
support without the need for a call as constructor (which is also needed for
the ES Matrix).

Michael Haufe (TNO)

unread,
Nov 21, 2013, 9:38:02 PM11/21/13
to
ax = {
configurable: true,
enumerable: false,
value: undefined,
writable: true
};

na = undefined;

typeof ActiveXObject == "undefined"

ActiveXObject in window == false

ActiveXObject instanceof Function == true

Michael Haufe (TNO)

unread,
Nov 21, 2013, 10:13:34 PM11/21/13
to
On Saturday, November 16, 2013 5:08:02 PM UTC-6, Thomas 'PointedEars' Lahn wrote:
>
> Depends. try…catch at least is the only reliable way to determine whether a
> host object of a certain class (sic!; as in CLSID) can be successfully
> created when “ActiveXObject” is called as a constructor where try…catch is
> supported (that would apply to these versions of JScript).

An alternative which still seems to work:

<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>clsid test</title>
</head>
<body>
<object id="wmv" width="100%" height="100%"
classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
</object>
<object id="xhr" width="100%" height="100%"
classid="CLSID:F5078F35-C551-11D3-89B9-0000F81FE221">
</object>
<script type="text/javascript">
var wmv = document.getElementById("wmv"),
xhr = document.getElementById("xhr");
</script>
</body>
</html>

The first is windows media player, the second is Msxml2.XMLHTTP.3.0

Thomas 'PointedEars' Lahn

unread,
Nov 22, 2013, 5:56:53 AM11/22/13
to
Curious. The “classid” attribute is not listed under “content attributes”,
but it is ascribed meaning in the prose:

<http://www.w3.org/TR/2012/CR-html5-20121217/embedded-content-0.html#the-object-element>

This has not changed in the latest Editor's Draft (22 November 2013):

<http://www.w3.org/html/wg/drafts/html/CR/embedded-content-0.html#the-object-element>

However, I do not see how that could be be used to detect support for a
certain COM class. The element is there no matter whether the class is
supported. Besides, does there have to be a CLSID for each server type?
What about non-HTML use?

Michael Haufe (TNO)

unread,
Nov 22, 2013, 9:33:02 AM11/22/13
to
On Friday, November 22, 2013 4:56:53 AM UTC-6, Thomas 'PointedEars' Lahn wrote:

> However, I do not see how that could be be used to detect support for a
> certain COM class. The element is there no matter whether the class is
> supported.

While the element will exist, if you inspect the variables, you'll noticed they are augmented with the members of the COM object if it loaded properly:

wmv.cdromcollection

xhr.responseBody

> Besides, does there have to be a CLSID for each server type?

I believe you can use progids as well, but IME this is pretty unreliable.

> What about non-HTML use?

I don't understand what you're referring to exactly, but there is basically a similar mechanism in WSH and classic ASP.

Thomas 'PointedEars' Lahn

unread,
Nov 22, 2013, 9:51:29 AM11/22/13
to
Michael Haufe (TNO) wrote:

> Thomas 'PointedEars' Lahn wrote:
>> However, I do not see how that could be be used to detect support for a
>> certain COM class. The element is there no matter whether the class is
>> supported.
>
> While the element will exist, if you inspect the variables, you'll noticed
> they are augmented with the members of the COM object if it loaded
> properly:
>
> wmv.cdromcollection
>
> xhr.responseBody

ACK.

>> Besides, does there have to be a CLSID for each server type?
>
> I believe you can use progids as well, but IME this is pretty unreliable.

AFAIK you have to use ProgIDs ("server.type") when calling ActiveXObject,
and:

,-<http://msdn.microsoft.com/en-us/library/aa911706.aspx‎>
|
| A programmatic identifier (ProgID) is a registry entry that can be
| associated with a CLSID.

“Can”, not “must”/“are”.

>> What about non-HTML use?
>
> I don't understand what you're referring to exactly, but there is
> basically a similar mechanism in WSH and classic ASP.

Current libraries using ActiveXObject do not have to have elements in HTML
documents in order to do XHR, for example. And if elements are created on
the fly for the test, there is both another DOM dependency and a race
condition.

Michael Haufe (TNO)

unread,
Nov 22, 2013, 10:44:10 AM11/22/13
to
On Friday, November 22, 2013 8:51:29 AM UTC-6, Thomas 'PointedEars' Lahn wrote:
>
> AFAIK you have to use ProgIDs ("server.type") when calling ActiveXObject,

[...]

Indeed, but it looks like it this might be possible with some versions of Opera:

<http://pastebin.com/BnhXLJpm>

"var DWCtrl = new ActiveXObject('CLSID:7292BC27-A53D-4C1E-92FF-D234BBEB0E59');"

> Current libraries using ActiveXObject do not have to have elements in HTML
> documents in order to do XHR, for example. And if elements are created on
> the fly for the test, there is both another DOM dependency and a race
> condition.

I'm curious to see if HTML Components (*.htc) support the <object /> tag. Though I suspect these are no longer available in IE11. I'll have to experiment with VBScript CreateObject to see if that behaves any different.
0 new messages