<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />我之前看到过一个类似的帖子...
我的批处理文件看起来一样,
像这样:
“C:\ Program Files \ SAS \ JMP \ 9 \ jmp.exe”“C:\ SCHEDULED \ MYSCRIPT.jsl”
但我已经有 exit(nosave);在我的脚本末尾(并关闭了所有表格和窗口)。而且,如果我只需单击 .bat 文件即可运行它,它会打开 JMP,运行脚本,然后按预期退出。只有当我通过任务计划程序运行这个 .bat 文件时,才会出现问题。它似乎没有执行 exit()。该脚本确实运行并执行其操作,但 jmp.exe 保持打开状态 - 我可以在任务管理器中看到它,尽管它在其他情况下不可见,并且任务不会继续进行(调度程序不会说它已完成,它会等待直到设定的最大时间并终止任务)。因此,效果是我的自动化脚本正在完成其工作,但随着时间的推移,越来越多的 JMP 打开,直到出现内存错误(如果我查看调度程序历史记录,我的作业永远不会成功完成,它们都会在一小时后终止,或者任何)。我尝试在 bat 文件中使用 tskill 来关闭 JMP,但这没有帮助,大概是因为它永远不会到达该步骤。
我还发现可以通过将批处理文件修改为以下内容来使调度程序满意:
启动“”“C:\Program Files\SAS\JMP\9\jmp.exe”“C:\SCHEDULED\MYSCRIPT.jsl”。然后它不会徒劳地等待事情结束,调度程序认为启动 .bat 文件后已经完成,但我仍然有 JMP 进程保持打开状态。当我在调度程序中打开JMP时,我仍然不知道如何成功关闭JMP。也许我可以每天运行一个任务,在某个奇怪的时间(当我不希望运行任何有用的东西时)对所有打开的 JMP 执行任务终止。但我希望有一个更清洁的解决方案。
对此有何想法?
这是JMP9和Windows7。各种不同的 JSL 脚本都会发生这种情况,所有这些脚本似乎都完成了其任务,直到退出 JMP(并且确实在调度程序之外退出 JMP)。
我观察到了与所描述的相同的问题。 但我找到了一个非常简单的解决方案。
我注意到,当我以交互方式运行 JMP 时,当我关闭它时,如果有任何打开的文件(例如脚本),我总是会出现一个“保存会话”对话框,询问我“您希望 JMP 记住打开的文件和报告吗?”下次再重新打开吗?”
有“是”、“否”和“取消”按钮以及“不要再询问我有关保存会话的信息”的复选框。
我怀疑该对话框也以批处理模式出现,并且 JMP 正坐在那里等待响应。
所以我勾选了“不要再问我”框并关闭了 JMP。
然后在任务计划程序中手动触发我的批处理作业......您知道什么,它成功运行并正确终止,并在任务计划程序中注明“操作成功完成”。
回复以更好地关注此主题。powershell 解决方案无法完全解决我的问题,因为我的脚本似乎在 Exit(); 之前挂起。命令。我的脚本挂在 Exit(); 之前的 NW << Save Journal("path") 处。尽管对于其他所有问题我都遇到完全相同的问题,但手动或通过 .bat 文件运行脚本不会产生任何问题。仅当我通过任务计划程序运行脚本时,它才会挂起。
感谢您的建议!
不幸的是,即使在运行 powershell 脚本后我仍然收到 JMP 执行错误......太奇怪了。
对于关注此线程的其他人,我必须在 powerscript 提示符处使用 set-executionpolicy remotesigned -scope currentuser 命令启用 powerscript shell 脚本执行,以允许脚本运行...
我还没有找到问题的根本原因解决方案。但你并不是唯一一个告诉我 exit() 并不总是有效的人。不过我现在确实有一个解决方法。
我必须让我的丈夫,一个真正的程序员,来做这件事。现在我欠他一个香蕉奶油派。
这个 Powershell 小程序实际上解决了某人可能感兴趣的另一个 JMP 特定问题。我的一个脚本想要打开一个 html 地址并从那里获取表格信息。但是,该位置受密码保护。我找不到 JMP 将我的凭据传递到 JSL 中的网站的方法,它只是失败了。然而,它只是在没有凭据的情况下工作如果我最近打开了该网站并在 Internet Explorer 中输入了凭据。JMP似乎使用了IE cookies。无论如何,这就是该程序有一个名为“loginpage”的命令行选项的全部原因。它对于 JMP 退出问题来说是多余的,但它可以选择在某个网页上打开 IE,根据需要传递硬编码凭据,然后关闭 IE。
“waitforlog”是相关的。该方案的工作方式是,当 JMP 脚本运行时,它会在完成后在最后发布某个日志文件。与 exit() 不同,这似乎可靠地发生。该程序会删除该文件的任何先前版本,打开 JMP,运行脚本,然后等待文件重新出现。当它这样做时,它知道它可以杀死 JMP,并且它已经计算出它打开的 JMP 实例的进程 ID,并仅杀死该实例。
我有一个早期的解决方法,使用taskkill定期杀死所有打开的JMP,但似乎在一个简单的批处理文件中知道您刚刚启动的特定实例并不容易,因此您可以使用taskkill杀死该特定实例。由于我有许多预定的作业,并且还想使用这台机器打开 JMP 并在作业在后台运行时执行一些手动工作,因此随意终止 JMP 实例并不是一个很好的解决方案。Powershell 似乎有一种特殊的能力来识别您刚刚启动的程序的特定实例。
无论如何,这个 Powershell 解决方案现在对我来说适用于这两个问题......
这是运行它的 .bat 文件中的语法示例......(最后两件事是可选的)
powershell "&"C:\SCHEDULED\runJMPscript. ps1" -script 'C:\SCHEDULED\yourJSLscript.JSL' -waitforlog -loginpage
就像我说的,我自己没有写这个,登录部分是基于我在另一个论坛中找到的关于启动 IE 并让它做更多事情的东西,而这些事情只需在一个简单的批处理文件中就可以完成。不过,这还是相当容易理解的。请注意,JMP 的位置是硬编码在那里的,您需要更改脚本以使其创建名称为带有 .log 扩展名的脚本名称的日志文件。
#******************************************************** **************************
#
# RunJmpScript.ps1 - 用于运行 Jmp 命令的 PowerShell 脚本
#
# 用法:
#
# powershell.exe RunJmpScript.ps1 [-loginpage] -script 脚本名 [-waitforlog]
#
#******************************************************** **************************
param ([开关]$loginpage, [字符串]$script = "未知", [开关]$waitforlog)
#
# 检查命令行选项是否有错误
#
写入主机“登录页面:$登录页面”
写入主机“脚本:$ script”
写入主机“waitforlog:$waitforlog”
$scriptexists = (测试路径 $script -PathType Leaf)
if (!($脚本存在))
{
Write-Host“错误:必须使用 -script 指定 Jmp 脚本文件的位置”
1号出口
}
#
# 如果需要的话,检索登录页面信息
#
如果($登录页)
{
# 定义一些会根据你的配置而改变的变量
# 我建议将它们存储为 XML 文件并在执行时读取它们
# 时间,但为了这个练习,我保持简单。
$username = "在此填写用户名"
$password = "在此填写密码"
$url = "在此填写网址"
# 创建 IE com 对象
$ie = new-object -com InternetExplorer.Application
# 跳转到登录页面
$ie.navigate($url)
# 等待页面加载完成
执行 {sleep 1} 直到 (-not ($ie.Busy))
#$ie.visible = $true #取消注释以进行调试
# 将 DOM 分配给 $doc 变量
$doc = $ie.文档
# 填写登录信息
尝试 {
# 找到用户名字段并将值设置为变量的值
$usernameField = $doc.getElementById('USER')
$usernameField.value = $用户名
# 找到密码字段并将值设置为结果的值
# 使用顶部定义的参数调用 get-password 函数
$passwordField = $doc.getElementById('PASSWORD')
$passwordField.value = $密码
# 找到并点击提交按钮
$submitButton = $doc.getElementById('提交')
$submitButton.click()
# 等待登录完成
执行 {sleep 1} 直到 (-not ($ie.Busy))
} 捕获 {$null}
# 等待页面加载完成
执行 {sleep 1} 直到 (-not ($ie.Busy))
# 关闭IE
$ie.quit()
}
#
# 如果我们要监视当前日志文件,请删除它
#
$logfile = $script + ".log"
如果($waitforlog)
{
if (测试路径 $logfile -PathType Leaf)
{
Write-Host“删除现有日志文件 $logfile”
删除项目 $logfile
}
}
#
# 执行Jmp命令,使用指定的脚本
#
$exe = "C:\Program Files\SAS\JMP\9\jmp.exe"
$exeargs = "`"" + $script + "`""
Write-Host“使用参数启动进程 $exe:$exeargs”
$jmp = 启动进程 $exe "$exeargs" -passthru
#
# 看看我们是否需要等待它写出日志文件。
#
如果($waitforlog)
{
$logfile = $script + ".log"
$idval = $jmp.Id
Write-Host“正在等待来自进程 $idval 的日志文件 $logfile”
while (!(测试路径 $Logfile -PathType Leaf))
{
# 如果进程退出,我们现在就可以退出
if ($jmp.HasExited)
{
出口0
}
# 否则,稍等一下,然后重试
开始-睡眠-s 1
}
Write-Host“停止外部程序$idval”
停止进程 $idval
}
出口0
在使用任务计划程序时,我也遇到过使用 exit(nosave) 命令的类似问题...当我在 JMP 中运行 jsl 脚本时,它工作正常。
我之前并没有看到它实际上不接近,但我得到了以下 2 个结果(相同的脚本,不同的机器):
1)程序按预期关闭
2) 我收到“JMP 异常!”警报窗口显示 JMP 发生了访问冲突并将关闭。如果不可能,错误信息将被复制到 My dcouments 文件夹或用户本地应用程序数据文件夹中的 JMPExcept.jer。如有必要,可以将错误信息通过电子邮件发送给 JMP 技术支持。
就我而言,我在运行 bat 文件时也得到了这些结果,但是当我从 JMP 正常运行 JSL 脚本时,它每次都能工作。
我实际上也看到了它有时在同一台机器上工作的地方,而不是其他地方。
如果有人有任何其他经验(或解决方法),我想听听。我确实向 JMP 支持人员发送了一封电子邮件,但他们不知道为什么行为有所不同。