我有一个旧的 html 页面,它创建一个脚本文件并使用以下命令执行它:
fsoObject = new ActiveXObject("Scripting.FileSystemObject")
wshObject = new ActiveXObject("WScript.Shell")
我正在尝试修改它并使其也可以在其他浏览器中使用。如果您知道答案,请停止阅读,请回答。如果没有快速回答,这里是我尝试的描述。我成功地完成了这项工作,但前提是脚本少于 2000 个字符。对于超过 2000 个字符的脚本,我需要帮助。
该网页仅供内部使用,因此我很容易在每台运行网络驱动器中的 VBScript 文件的计算机上创建自定义 URL 协议。
我创建了启动 VBScript 文件的自定义 URL 协议,如下所示:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\MyUrlProtocol]
"URL Protocol"=""
@="Url:MyUrlProtocol"
"UseOriginalUrlEncoding"=dword:00000001
[HKEY_CLASSES_ROOT\MyUrlProtocol\DefaultIcon]
@="C:\\Windows\\System32\\WScript.exe"
[HKEY_CLASSES_ROOT\MyUrlProtocol\shell]
[HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open]
[HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open\command]
@="C:\\Windows\\System32\\WScript.exe \"X:\\MyUrlProtocol.vbs\" \"%1\""
在MyUrlProtocol.vbs
我有这个:
MsgBox "The length of the link is " & Len(WScript.Arguments(0)) & " characters"
MsgBox "The content of the link is: " & WScript.Arguments(0)
当我单击时,<a href="MyUrlProtocol:test" id="test">click me</a>
我看到两条消息,所以一切正常(在 Windows 7 中使用 Chrome 和 IE 进行了测试。)
当我执行时它也有效document.getElementById("test").click()
我认为这可能是解决方案:我会将脚本的文本传递给 VBS 静态脚本,它会创建动态脚本并运行它,但是使用这个系统,我不能传递超过 ~2000 个字符。
因此,我尝试将脚本文本拆分为小于 2000 个字符的块,并模拟对链接的多次点击,但只有第一个有效。
所以我尝试了xmlhttp.open("GET","MyUrlProtocol:test",false);
,但 Chrome 说Cross origin requests are only supported for HTTP
。
是否可以通过自定义 URL 协议将超过 2000 个字符传递给 VBScript 脚本?
如果不是,是否可以依次调用多个自定义 URL 协议?
如果没有,是否有另一种方法来创建脚本文件并从 Javascript 运行它?
编辑 1
我找到了一个解决方案,但在 Chrome 中只有在它喜欢的时候才有效,所以我回到了原点。
IE 中的以下代码执行脚本 4 次(正确),但在 Chrome 中仅运行第一次执行。
如果我将其更改为delay += 2000
,那么 Chrome 通常会运行脚本 2 次,但有时会运行 1 次,有时会运行 3 次甚至 4 次。
如果我将其更改为delay += 10000
,那么它通常会运行脚本 4 次,但有时会错过一次。
该函数在 Chrome 和 IE 中总是执行 4 次。奇怪的是,sr.click()
有时什么都不做,函数继续执行。
<HTML>
<HEAD>
<script>
var delay;
function runScript(text) {
setTimeout(function(){runScript2(text)}, delay);
delay += 100;
}
function runScript2(text) {
var sr = document.getElementById('scriptRunner');
sr.href='intelliclad:'+text;
sr.click();
}
function test(){
delay = 0;
runScript("uno");
runScript("due");
runScript("tre");
runScript("quattro");
}
</script>
</HEAD>
<BODY>
<input type="button" value="Run test" onclick="test()">
<a href="nothing yet" id="scriptRunner">scriptRunner</a>
</BODY>
</HMTL>
编辑 2
我尝试了 Luke 的建议,即从回调内部设置下一个超时,但没有任何改变(IE 始终有效,Chrome 随时可用)。
这是新代码:
var scripts;
var delay = 2000;
function runScript() {
var sr = document.getElementById('scriptRunner');
sr.href = 'intelliclad:' + scripts.shift();
sr.click();
if(scripts.length)
setTimeout(function() {runScript()}, delay);
}
function test(){
scripts = ["uno", "due", "tre", "quattro"];
runScript();
}
一些背景:页面要求面板的形状,对于具有许多面、许多槽、许多紧固件等的面板,可以只是几个参数[nfaces=1, shape1='square', width1=100]
或数百个参数。在要求所有参数后,我们内部 3D 的脚本生成 CAD(可能大于 20KB)并启动 CAD 并要求执行脚本。
我想在客户端做所有事情,因为页面由 Domino Web 服务器提供服务,它甚至无法想象管理如此复杂的脚本。