Javascript is detected when run in hta
We would like to allow our users to download the hta file and run our web application inside it, and some pages find that they are running in the hta file and offer additional functionality that the web application usually does not have permission to do.
How can I simply detect if a page is being viewed from a container of hta files?
a source to share
window.location.protocol=='file:'
will point to a local page, but it could be a local html page or a local hta.
I think it window.external
may be different in every context. So, creation and discovery a.htm
and a.hta
containing:
<script>document.write(window.external)</script>
We get:
- IE:
[object]
- FireFox:
[xpconnect wrapped (nsISupports, nsISidebar, nsISidebarExternal, nsIClassInfo)]
- Chrome:
[object Object]
- HTA:
null
So this isHTA=(window.external==null)
will indicate the HTA context.
Or, isHTA=false;try{isHTA=(window.external==null)}catch(e){}
Just to be on the safe side, as I've only tested current versions of IE, FF, and Chrome and who knows what other browsers will do.
a source to share
HTAs are unique in the way they populate the DOM using the <HTA: APPLICATION> tag. I use the following to grab the HTA object:
var hta;
var elements = document.getElementsByTagName("APPLICATION");
for(var i=0; i<elements.length; i+=1) {
if ("hta" === elements[i].scopeName.toString().toLowerCase()) {
hta = elements[i];
break;
}
}
// To test if the page is an HTA:
var isHta = (undefined !== hta);
In other browsers, you will need to use the fully qualified tag name to access the same object:
// For Firefox/Chrome/IE
var elements = document.getElementsByTagName("HTA:APPLICATION");
a source to share
This may match the bill. Attribute checking can be removed.
<hta:application id="myHTA"/>
<script>
alert("isHTA = " + isHTA("myHTA"));
function isHTA(htaId) {
var retval = false;
var hta = window[htaId];
if (!hta) {
// hta wasn't defined
} else if (hta.scopeName != "hta") {
// hta:application
} else if (hta.nodeName != "application") {
// hta:application
} else if (hta.tagName != "application") {
// hta:application
} else {
retval = true;
// attributes only a real hta would have
var attribKeys = [
"applicationName",
"border",
"borderStyle",
"caption",
"commandLine",
"contextMenu",
"icon",
"innerBorder",
"maximizeButton",
"minimizeButton",
"scroll",
"scrollFlat",
"selection",
"showInTaskBar",
"singleInstance",
"sysMenu",
"version",
"windowState"
];
for (var i=0;i<attribKeys.length;i++) {
var attribKey = attribKeys[i];
if (!hta.attribKey === undefined) {
retval = false;
break;
}
}
}
return retval;
}
</script>
a source to share
Checking a property of commandLine
an HTA application object is the best way to check if it is running as a real HTML application because this property is only available in the mshta.exe file.
You need to get the HTM-Application object to check this property. If you don't know the id of the object, you can use this code:
// Check if running in a HTML-Application
var isHTA = false;
var htaApp = document.getElementsByTagName("HTA:APPLICATION")
if (!htaApp.length) {
htaApp = document.getElementsByTagName("APPLICATION");
}
if (htaApp.length == 1 && htaApp[0]) {
isHTA = typeof htaApp[0].commandLine !== "undefined";
}
a source to share
Guess not many people still use HTA anyway, anyway I think the following should cover all scenarios:
<script language=javascript>
var VBScriptVersion = "";
function getVBScriptVersion() {
var firstScriptBlock = document.getElementsByTagName('script')[0];
var tmpScript = document.createElement('script');
tmpScript.setAttribute("language", "VBScript");
tmpScript.text = 'VBScriptVersion = ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion';
tmpScript.async = false;
tmpScript.onload = function() {
this.parentNode.removeChild(this);
}
firstScriptBlock.parentNode.insertBefore(tmpScript, firstScriptBlock);
return VBScriptVersion;
}
var isHTA = (getVBScriptVersion()!="" && window.external==null);
</script>
a source to share