用NSIS打包程序,安装完成后如果勾选了“运行 XXX程序”,程序运行后是不会最前端显示的(就是会被其它窗口遮挡)。但是用Inno打包就可以。自己开发一个打包程序估计也可以。那怎么解决NSIS打包程序的这个问题呢?谢谢!

解决方案 »

  1.   

    我这边有此问题哦。
    在网上找到一段脚本——
    !Macro "SingleSetup"
    BringToFront  #使安装程序窗口可见并把它带到其它窗口的最前端
    ; Check if already running, If so don't open another but bring to front
    System::Call "kernel32::CreateMutexA(i 0, i 0, t '$(^Name)') i .r0 ?e"
    Pop $0
    StrCmp $0 0 launch
    StrLen $0 "$(^Name)"
    IntOp $0 $0 + 1
    loop:
    FindWindow $1 '#32770' '' 0 $1
    IntCmp $1 0 +4
    System::Call "user32::GetWindowText(i r1, t .r2, i r0) i."
    StrCmp $2 "$(^Name)" 0 loop
    System::Call "user32::ShowWindow(i r1,i 9) i."         ; If minimized then maximize
    System::Call "user32::SetForegroundWindow(i r1) i."    ; Bring to front
    Abort
    launch:
    !macroend
    地址是这个但是完全不知道应该在哪个位置调用,有人指教下吗?
      

  2.   

    你说的不会最前端显示的是指安装程序还是那个要运行的XXX程序?如果是那个要运行的XXX程序,你在网上找的那段脚本根本没用
      

  3.   

    当然是XXX程序。那段脚本为什么没用?那么应该怎样做?
      

  4.   

    当然没用,那段脚本都写了,是安装程序不是XXX程序:
    #使安装程序窗口可见并把它带到其它窗口的最前端
      

  5.   

    那句注释只针对这一句脚本的——BringToFront
      

  6.   

    那段脚本虽然有些错误,但我还是能看出它的思想的
    ; Check if already running, If so don't open another but bring to front
    这句注释说的也是安装程序,后面判断的$(^Name)就是安装程序的名字给你写了个Demo,是运行记事本的,你自己看着办吧:SetCompressor lzma
    !include "MUI.nsh"
    !insertmacro MUI_PAGE_INSTFILES
    !define MUI_FINISHPAGE_RUN "notepad.exe"
    !insertmacro MUI_PAGE_FINISH
    !insertmacro MUI_LANGUAGE "SimpChinese"Name "Test"
    OutFile "Setup.exe"Section
    SectionEnd;下面的代码不写,记事本一样可以最前端显示
    Function .onInstSuccess
    loop:
      FindWindow $0 "Notepad" "无标题 - 记事本"
      StrCmp $0 0 loop
      System::Call User32::SetForegroundWindow(ir0)
    FunctionEnd
      

  7.   

    “Function .onInstSuccess”这个关键啊。。哈哈,可行!谢谢!
    如果可以开线程loop就好了,不然CPU使用率特高。是不是可以用System::Call User32::CreateThread 开线程呢?呵呵。不行的话就System::Call User32::Sleep 一下?这些办法是否常规呢?还有要判断到底有没有勾选安装完毕后运行XXX程序,这个。。又或者是给loop加个限时?脚本如何写?求常规做法。。谢谢。。
      

  8.   

    “Function .finishpageaction”!这个函数就是用户选择了运行XXX程序之后才会回调的!欧耶,找到了~
    在这个网页里找到的
      

  9.   

    如果你真想在勾选运行程序或勾选说明文档时调用某个函数,用头文件提供的方式就可以。!define MUI_FINISHPAGE_RUN
    !define MUI_FINISHPAGE_RUN_TEXT "运行XXX程序"
    #!define MUI_FINISHPAGE_RUN_PARAMETERS "/S" #如果需要参数就添加此定义
    #!define MUI_FINISHPAGE_RUN_NOTCHECKED #不选中
    !define MUI_FINISHPAGE_RUN_FUNCTION myFuncXXX
    !define 
    !define MUI_FINISHPAGE_SHOWREADME
    !define MUI_FINISHPAGE_SHOWREADME_TEXT "运行YYY程序"
    #!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED #不选中
    !define MUI_FINISHPAGE_SHOWREADME_FUNCTION myFuncYYYFunction myFuncXXX
        # 勾选"运行XXX程序"
    FunctionEndFunction myFuncYYY
        # 勾选"运行YYY程序"
    FunctionEnd不过是不能解决你那个窗口前置的问题的。
      

  10.   

    谢谢!原来把这些定义写在“!insertmacro MUI_PAGE_FINISH”之前是关键啊。。唉。。写在后面就不会生效了。如你所说,利用这些来解决窗口前置问题貌似不行。我试了下!define MUI_FINISHPAGE_RUN_FUNCTION finishpageaction,然后在这个函数里面loop,但发现这个函数先于程序启动而执行。。所以就会一直loop。。我也试了下在这个函数里面首先Exec "XXX.exe",但是这样做的话,安装界面竟然一直就不消失了。。
      

  11.   

    一直 loop 肯定不行,窗口找不到肯定一直都是 0,无限循环了。不管你是用:
    !define MUI_FINISHPAGE_RUN_FUNCTION myFuncXXX
    !define MUI_FINISHPAGE_SHOWREADME_FUNCTION myFuncYYY
    还是:
    !define MUI_PAGECUSTOMFUNCTION_LEAVE finishpageaction
    还是直接使用内置回调函数 .onInstSuccess 都不是解决问题的关键。
    如果是下面这两个方案,用 HideWindows 把窗体隐藏就不会出现卡死不关闭的情况了。
      

  12.   

    “……如果是下面这两个方案,用 HideWindows 把窗体隐藏就不会出现卡死不关闭的情况了。”这个巧~