2015-10-22 150 views
0

我使用的是WindowsXP,NSIS 2.46与nsSCM插件,并有4台机器用几乎相同的环境(硬件+软件),因为他们来自同一个GHOST镜像但很应用程序层的更改有限(不更改任何系统设置)。NSIS安装程序未能启动/停止服务

我使用NSIS安装到我的应用程序安装到它们,具体过程是:

  1. 停止“APACHE2.2”服务。
  2. 将文件复制到Apache根文件夹。
  3. CreateShortCut
    随着脚本:
CreateShortCut "$SMPROGRAMS\MyApp\Stop.lnk" "$SYSDIR\sc.exe" "stop MyAppService" "C:\WINDOWS\system32\SHELL32.dll" 27 SW_SHOWMINIMIZED 
CreateShortCut "$SMPROGRAMS\MyApp\ShowDemo.lnk" "$PROGRAMFILES\MyAppPath\MyAppShowDemoHelper.exe" "-b 102" "C:\WINDOWS\system32\SHELL32.dll" 24 SW_SHOWMINIMIZED 
  • 开始 'APACHE2.2' 服务。

    随着脚本:

  • nsSCM::Start /NOUNLOAD "Apache2.2" 
        Pop $0 ; return error/success 
        ${If} $0 == "success" 
         MessageBox MB_ICONINFORMATION|MB_OK "Successfully started 'Apache2.2' service" 
        ${Else} 
         MessageBox MB_ICONSTOP|MB_OK "Failed to start 'Apache2.2' service with result: $0, Contact help desk or start it manually!" 
        ${EndIf} 
    

    ===========================

    现在的问题是步骤4,在其中两台机器,它总是弹出错误,并始终需要手动启动服务(没有错误),但同时,快捷键是cr成功了。

    我检查了系统日志,Apache日志,但没有找到错误日志/消息。

    我花了一天,什么都试过了,最后,我发现当我删除了第3步,一切都很好,所以任何想法,为什么?

    [Edit0]:

    对于工作的时候,我要切换步骤3和4,至少现在它的作品好。

    +0

    CreateShortcut应该与插件调用完全无关,我敢肯定还有其他的事情发生。你使用的是NSIS 3 beta还是NSIS 2.46? – Anders

    +0

    @Anders我无法相信,直到我逐行评论脚本,并看到结果。我使用的是NSIS 2.46。 – Shawn

    +0

    @Anders任何建议,以尽量减少范围? – Shawn

    回答

    0

    CreateShortcut应该对插件没有影响,所以这是很奇怪的。如果我们能够缩小NSIS中插件API的问题或插件本身的问题,那将会很好。也许你可以试试SimpleSC插件?

    下面是一些代码,它与系统插件手动执行它。它并不漂亮,但如果失败则应显示相关的错误代码。

    Section 
    !define MyServiceName "Spooler" ;"stisvc" 
    ExecWait '"$SysDir\cmd.exe" /c net stop "${MyServiceName}"' ; Hack to make sure the service is stopped so we can try starting it again 
    Sleep 1111 
    
    InitPluginsDir 
    CreateShortcut "$PluginsDir\Test1.lnk" "$ExePath" ; Create some dummy shortcuts to possibly trigger the bug 
    CreateShortcut "$PluginsDir\Test2.lnk" "$ExePath" 
    
    !include LogicLib.nsh 
    !include Util.nsh 
    !define ERROR_SERVICE_ALREADY_RUNNING 1056 
    !define SC_MANAGER_CONNECT 0x0001 
    !define SERVICE_QUERY_STATUS 0x0004 
    !define SERVICE_START 0x0010 
    !define SERVICE_PAUSE_CONTINUE 0x0040 
    !define SERVICE_CONTROL_CONTINUE 3 
    !define SERVICE_STOPPED 1 
    !define SERVICE_START_PENDING 2 
    !define SERVICE_STOP_PENDING 3 
    !define SERVICE_RUNNING 4 
    !define SERVICE_CONTINUE_PENDING 5 
    !define SERVICE_PAUSE_PENDING 6 
    !define SERVICE_PAUSED 7 
    
    !macro WaitForServiceRunningStatus_ 
    System::Store S 
    Pop $6 
    Pop $1 
    System::Call KERNEL32::GetTickCount()i.r7 
    System::Call '*(i,i,i,i,i,i,i)i.r2' 
    loop: 
        System::Call 'ADVAPI32::QueryServiceStatus(ir1, ir2)i.r3' 
        System::Call '*$2(i,i.r4)' 
        ${If} $3 <> 0 
         ${If} $4 = ${SERVICE_RUNNING} 
          DetailPrint 'Service is now running.' 
         ${Else} 
          Sleep 250 
          System::Call KERNEL32::GetTickCount()i.r8 
          ${IfThen} $8 < $7 ${|} StrCpy $7 $8 ${|} ; Reset on GetTickCount rollover 
          IntOp $8 $8 - $7 
          IntCmpU $8 $6 "" loop 
          DetailPrint 'Timeout! Service status is $4' 
         ${EndIf} 
        ${EndIf} 
    System::Free $2 
    System::Store L 
    !macroend 
    !macro WaitForServiceRunningStatus hSC MsTimeout 
    Push ${hSC} 
    Push ${MsTimeout} 
    ${CallArtificialFunction} WaitForServiceRunningStatus_ 
    !macroend 
    
    System::Call 'ADVAPI32::OpenSCManager(t"", i0, i${SC_MANAGER_CONNECT})i.r0 ?e' 
    Pop $9 
    ${If} $0 = 0 
        DetailPrint 'OpenSCManager(t"", i0, i${SC_MANAGER_CONNECT}) failed with error $9' 
    ${Else} 
        System::Call 'ADVAPI32::OpenService(ir0, t"${MyServiceName}", i${SERVICE_QUERY_STATUS}|${SERVICE_START}|${SERVICE_PAUSE_CONTINUE})i.r1 ?e' 
        Pop $9 
        ${If} $1 = 0 
         DetailPrint 'OpenService("${MyServiceName}") failed with error $9' 
        ${Else} 
         System::Call '*(i,i,i,i,i,i,i)i.r2' 
         System::Call 'ADVAPI32::QueryServiceStatus(ir1, ir2)i.r3 ?e' 
         Pop $9 
         ${If} $3 = 0 
          DetailPrint 'QueryServiceStatus failed with error $9' 
          StrCpy $4 0 ; We failed, set to unused code so we stop processing 
         ${Else} 
          System::Call '*$2(i.r3,i.r4,i.r5,i,i,i,i)' 
          IntFmt $3 "%#x" $3 
          IntFmt $4 "%#x" $4 
          IntFmt $5 "%#x" $5 
          DetailPrint 'QueryServiceStatus: Type=$3, CurrentState=$4 ControlsAccepted=$5' 
         ${EndIf} 
         ${If} $4 = ${SERVICE_PAUSE_PENDING} 
         ${OrIf} $4 = ${SERVICE_PAUSED} 
          System::Call 'ADVAPI32::ControlService(ir1, i${SERVICE_CONTROL_CONTINUE}, ir2)i.r3 ?e' 
          Pop $9 
          ${If} $3 = 0 
           DetailPrint 'ControlService(SERVICE_CONTROL_CONTINUE) failed with error $9' 
          ${Else} 
           DetailPrint 'Resuming "${MyServiceName}"...' 
           !insertmacro WaitForServiceRunningStatus $1 5000 
          ${EndIf} 
         ${ElseIf} $4 = ${SERVICE_CONTINUE_PENDING} 
          !insertmacro WaitForServiceRunningStatus $1 5000 
         ${ElseIf} $4 >= ${SERVICE_STOPPED} 
          ${If} $4 = ${SERVICE_RUNNING} 
           DetailPrint "Service already running" 
          ${Else} 
           System::Call 'ADVAPI32::StartService(ir1, i0, i0)i.r3 ?e' 
           Pop $9 
           ${If} $3 = 0 
            DetailPrint 'StartService failed with error $9' 
           ${Else} 
            DetailPrint 'Starting "${MyServiceName}"...' 
            !insertmacro WaitForServiceRunningStatus $1 9000 
           ${EndIf} 
          ${EndIf} 
         ${EndIf} 
         System::Free $2 
         System::Call 'ADVAPI32::CloseServiceHandle(i.r1)' 
        ${EndIf} 
        System::Call 'ADVAPI32::CloseServiceHandle(i.r0)' 
    ${EndIf} 
    SectionEnd