Windows Can';tcl脚本中的t exec NSIS安装应用程序

Windows Can';tcl脚本中的t exec NSIS安装应用程序,windows,tcl,nsis,Windows,Tcl,Nsis,运行tcl 8.4.13,我有一个tcl脚本来执行我的NSIS安装应用程序(由microsoft正式签署),该应用程序以前可以运行,但现在失败了(windows 7和10),可能是因为windows安全更新或其他原因?当目标是notepad.exe的本地/重命名副本时,相同的tcl脚本可以正常工作。NSIS应用程序在从命令行运行时工作正常 tcl脚本如下所示,通过tclkit-win32 tclmnu.tcl运行,其中tclmnu.tcl如下所示: #! /bin/sh -x # \ e

运行tcl 8.4.13,我有一个tcl脚本来执行我的NSIS安装应用程序(由microsoft正式签署),该应用程序以前可以运行,但现在失败了(windows 7和10),可能是因为windows安全更新或其他原因?当目标是notepad.exe的本地/重命名副本时,相同的tcl脚本可以正常工作。NSIS应用程序在从命令行运行时工作正常

tcl脚本如下所示,通过tclkit-win32 tclmnu.tcl运行,其中tclmnu.tcl如下所示:

#! /bin/sh -x
# \
    exec wish "$0" "$@"
#

package require Tk

#set runcmd notepad_local_copy.exe
set runcmd my_nsis_app.exe  # this doesn't work

# this works with the notepad_local_copy.exe (above) but not my_nsis_app.exe
set catchcode [ catch { exec ${runcmd} } result ]

# also tried this, doesn't work either
#set catchcode [ catch { exec "runas /usr:administrator: ${runcmd}" } result ]

tk_messageBox -type ok -icon error -message "DEBUG: catchcode=${catchcode}"
# catchcode is 0 when runas=notepad_local_copy.exe, 1 when it's my_nsis_app.exe

我通过添加cmd/c解决了这个问题,如

set catchcode [ catch { cmd /c exec ${runcmd} } result ]

我不知道为什么它需要这样做,也不知道为什么它在以前和现在都能工作。

我对TCL一无所知,但我假设
exec
调用。当UAC被添加到Vista中时,微软似乎认为
CreateProcess
的级别太低,无法执行提升

CreateProcess
CreateProcessWithLogonW
没有新的标志来启动提升的子进程。在内部,CreateProcess()检查目标应用程序是否需要提升,方法是查找清单,确定它是否是安装程序,或者是否有app compat shim如果CreateProcess()确定目标应用程序需要提升,它将失败,并出现错误\u elevation\u REQUIRED(740)。它将不会联系AIS执行提升提示或运行应用程序。如果CreateProcess()确定应用程序不需要提升,它将生成一个新进程

ShellExecute[Ex]
但是可以联系UAC服务并显示UAC高程对话框:

要以编程方式将子进程作为提升的进程启动,必须发生两件事:首先,需要将子进程的可执行文件标识为需要提升,其次,父进程需要使用ShellExecute()或ShellExecuteEx()

似乎有多种方法可以让TCL调用
ShellExecute

eval exec [auto_execok start] {""} [list [file nativename $filename]] ;# http://wiki.tcl.tk/2809

即使未标记为需要提升,也可以请求提升可执行文件:

twapi::shell_execute -path filename.exe -verb runas 
(与
runas.exe
不同的是
runas.exe)

NSIS脚本使用
RequestExecutionLevel
属性将可执行文件标记为所需的UAC提升级别


使用
cmd/c
有点麻烦,可能会在短时间内显示控制台窗口
cmd/c
首先尝试CreateProcess,如果需要提升,则返回到
ShellExecuteEx
。我不确定这是否是记录在案的行为。

您的安装程序需要提升吗?这就是为什么我尝试了具有相同结果的runas(在上面注释掉)。但是运行cmd/c修复了它。嗯,听起来问题在于它需要在正确的子系统中运行,而Windows默认选择的子系统是错误的。这是可怕的,如果是真的,但不是完全令人难以置信;Windows上的子进程执行中隐藏了许多非常糟糕的陷阱(在操作系统API级别),这些东西只能部分隐藏。@DonalFellows这与子系统无关,CreateProcess可以混合并匹配这两个。我想它可能会在控制台上闪烁,但我没有看到一个(或不明显)。。。不管怎样,它工作得足够好,并且应用程序在任何情况下都接近EOL。
twapi::shell_execute -path filename.exe -verb runas