We'd like to allow our users to download an hta file and run our web app inside it, and have certain pages detect that they are running in an hta file and offer additional features that a web app wouldn't norma开发者_运维百科lly have permission to do.
How can I simply detect if the page is being browsed from an hta file container?
window.location.protocol=='file:'
would indicate a local page but that could be a local
html page or a local hta.
I'm thinking window.external
may be different in each context.
So making and opening 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, isHTA=(window.external==null)
would indicate the HTA context.
Or, isHTA=false;try{isHTA=(window.external==null)}catch(e){}
To be on the safe side, since I have only tested current versions of IE, FF, and Chrome and who knows what the other browsers will do.
What about just:-
var isHTA = (document.all && top.document && (top.document.getElementsByTagName('application')[0]));
HTAs are unique in how they populate the DOM with 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 have to use the full tag name to access the same object:
// For Firefox/Chrome/IE
var elements = document.getElementsByTagName("HTA:APPLICATION");
I haven't tested, but wouldn't just looking at window.location work?
This might fit the bill. Verifying the attributes could 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>
Checking the commandLine
property of the HTA-Application object is the best method to see if you are running as real HTML-Application, because this property is only available in the mshta.exe.
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";
}
guess not many people still using HTA nowadays, anyway, I think the below should cover all the 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>
精彩评论