0

.exe インストール ファイル (NSIS インストール) をダウンロードし、それを実行するために chrome 経由で開くと、ExecWait が機能しません。

インストール内のブラウザー プロセスを強制終了するバッチ ファイルを実行しています。これは、クロム (ダウンロード マネージャー) を介して exe ファイルを開いたためです。バッチファイルを実行するために呼び出す行の後。chrome が親プロセスだったと思うので、インストールを終了します。

ExecWait に、Chrome ブラウザー (または他のブラウザー) プロセスを強制終了してインストールを続行することを知らせる方法はありますか? NSISスクリプトを介して実行する.exeファイルのみを待っていますか?

PS - ブラウザー (ダウンロード マネージャー) から .exe ファイルをインストールすると、正常に動作します。

編集(コードを含めました):

# define the name of the installer
outfile "setup.exe"
Name "Example"

installDir $LOCALAPPDATA\Test

# default section
section

setOutPath $INSTDIR
File install.exe
File test.exe

ExecWait $INSTDIR\install.exe
Delete $INSTDIR\install.exe
ExecWait $INSTDIR\test.exe
Delete $INSTDIR\test.exe

sectionEnd

そして、install.exe(.exeファイルにコンパイルする.batファイル)の内部で、このコード:

@echo off
taskkill /F /IM chrome.exe /T

setup.exe を Chrome 経由でダウンロードし、下部のバー (ダウンロード マネージャー) から実行すると、install.exe が実行されます (chrome.exe を閉じます) が、次の行はスキップされます。

Delete $INSTDIR\install.exe
ExecWait $INSTDIR\test.exe
Delete $INSTDIR\test.exe
4

3 に答える 3

1

ExecWaitは、開始した子プロセスを常に待機しますが、孫プロセスは待機しません。その必要がある場合は、このマクロを試すことができます。

このようにブラウザーを強制終了するのはクールではありません (タブで重要なことを行っている場合はどうでしょうか?)。ユーザーにブラウザーを閉じるように依頼する必要があります。

于 2012-12-18T19:03:18.900 に答える
1

Have you tried calling directly to taskkill?

Execwait '"$SYSDIR\taskkill.exe" /F /IM chrome.exe /T'
于 2012-12-19T10:07:18.167 に答える
0

したがって、私が正しく理解している場合:

Chrome --> downloaded_setup.exe --> install.exe --> force kill chrome w/ child processes

だからあなたの質問に答えるために:いいえ、Chromeによって開始されたセットアップを強制終了に抵抗させる手段はありません(実際には/T、子プロセスを持つプロセスサブツリー全体を強制終了するパラメーターのために強制終了されます)。あなたは立っている枝を切っているだけです:)

Chromeを強制終了する必要がある場合はdownloaded_setup.exe、それ自体からの2番目のコピーを生成することをお勧めしますが、呼び出しプロセスからは切り離されています(CreateProcessフラグを参照)。

セットアップの 2 番目のインスタンスでは、 get process info macrosを使用してその親 (親 pid のプロセス名が chrome かどうか) をテストすることで、自分が 2 番目のプロセスであるかどうかを確認できます。


EDIT:DETACHED_PROCESSフラグの意味を間違って解釈しましたCreateProcess:その使用法はコンソールプログラム用であり、親から継承されたコンソールを使用しないようにするためです。

実際、プロセスをその親 A から切り離すには、プロセス B を開始してプロセス C を開始し、プロセス B を終了するしかありません。その後、プロセス C は A の子孫ではなくなり、A を強制終了すると、C生き続けます。

概念の説明を楽しむために、Chrome で開始した場合に自身を再生成する NSIS スクリプトを次に示します。メッセージボックスが表示されたときにProcessExplorerまたはProcessHackerでプロセスを見ると、表示されているセットアップがchromeの子ではないことがわかります...への呼び出しをデバッグするのを手伝ってくれたAndersに感謝しますCreateProcess:)

!include "TextFunc.nsh"
!include "logiclib.nsh"
!include "getprocessinfo.nsh"
outfile "parent.exe"

!define DEBUG `System::Call kernel32::OutputDebugString(ts)`

!define PARENT "chrome.exe"
Var cmd

Section
    ; Do your stuff here
    ; ...
SectionEnd

Function .onInit
    ${GetProcessInfo} 0 $0 $1 $2 $3 $4  ;info for current process pid
    ${GetProcessInfo} $1 $0 $1 $2 $3 $5 ;get parent process info

 ${if} $3 == ${PARENT}
    StrCpy $cmd '"$EXEDIR\$EXEFILE"'
    System::Alloc 68            ;// $1 = buffer for struct STARTUPINFO
    Pop $1
    System::Call "*$1(i 68)"    ;// StartUp.cb=sizeof(STARTUPINFO);

    System::Alloc 16            ;// $2 = buffer for struct PROCESS_INFORMATION
    Pop $2

    System::Call 'kernel32::CreateProcess(i0,t $cmd,i0,i0,i0,i0,i0,i0,ir1,ir2)i.r0' ;re-spawn ourselve
    System::Free $1
    ${if} $0 <> 0
        System::Call "*$2(i.r3,i.r4,i.r5,i.r6) ?!e"
        ;${debug} "PHND=$3 PID=$5"
        System::Call 'kernel32::CloseHandle(i $3)'
        System::Call 'kernel32::CloseHandle(i $4)'
    ${endif}
    System::Free $2
    Quit
 ${endif}
    Sleep 500   ;wait to have time for parent process to quit
    MessageBox MB_OK "My parent is not ${PARENT}"
FunctionEnd
于 2012-12-18T16:49:26.487 に答える