0

「RequestExecutionLevel ユーザー」を持つ NSIS インストーラーがあります。そのインストーラーには、「RequestExecutionLevel admin」を持つ組み込みの NSIS インストーラーが含まれています。この子インストーラーは、特定のシナリオでのみ呼び出されます。これは、特定の管理操作を子インストーラーに含めることができるようにするためであり、必要な場合にのみユーザーに UAC の承認を求めるプロンプトが表示されるようにします。

私の質問は、次のように子インストーラーを呼び出すには
どうすれ
ばよいですか?一定期間内。

私は ShellExecWait ( http://nsis.sourceforge.net/ShellExecWait ) を使用していますが、これはうまく機能しますが、タイムアウト値を指定するオプションがありません (つまり、永遠に待機します)。

以下の NSIS 関数を既に試したことに注意してください:
* ShellExecWait - タイムアウトを許可しません
* ExecWait - 親インストーラーの実行レベルを継承するため、子インストーラーは失敗します。
* ExecShell - タイムアウトを許可しません
* nsExec::Exec - 親インストーラの実行レベルを継承するため、子インストーラは失敗します。

私はここでかなり必死になっています - どんな助けもいただければ幸いです。

4

1 に答える 1

0

UAC はこれをサポートするように設計されておらず、これを行う試みはハッキングと見なされるべきです!

問題の一部は、プロセス内の ShellExecuteEx が昇格操作の一部であるため、スレッドまたはプロセスを強制終了せずに強制終了できないことです。これを回避するために、セットアップが私たちが殺すことができる仲介者として機能できるようにします。この設計の 1 つの欠点は、タイムアウトによってプロセスが強制終了された後も UAC ダイアログが残っていることです (UAC GUI は、システムとして実行されている consent.exe にあります)。これは、メイン インストーラーがなくなった後、ユーザーが子インストーラーを昇格できることを意味します。私はこれをWin7でのみテストしましたが、親がなくなった場合、UACは新しいプロセスを開始しませんが、これはバグである可能性があり、少なくとも動作はAFAIKで文書化されておらず、おそらく製品コードで使用すべきものではありません!

Outfile "test.exe"
RequestExecutionlevel User

!include LogicLib.nsh
!include WinMessages.nsh
!include FileFunc.nsh

Page Instfiles

!macro ElevateWithTimeout_OnInit
${GetParameters} $0
${GetOptions} $0 '--ExecTimer' $1
${If} $1 != ""
    StrCpy $1 $0 "" 12
    ExecShell 'runas' $1 ;RunAs is not really required as long as the .exe has a manifest that requests elevation...
    Quit
${EndIf}
!macroend
Function ElevateWithTimeout
InitPluginsDir
System::Call '*(&i60,tsr1)i.r0'
StrCpy $1 "--ExecTimer $1"
System::Call '*$0(i 60,i 0x40,i $HwndParent,i0,t"$ExePath",tr1,to,i1)i.r0'
System::Call 'shell32::ShellExecuteEx(ir0)i.r1'
System::Call '*$0(i,i,i,i,i,i,i,i,i,i,i,i,i,i,i.r2)'
System::Free $0
Pop $0 ; Timeout (MS)
${If} $1 <> 0
    System::Call 'kernel32::WaitForSingleObject(ir2,ir0)i.r0'
    ${If} 0x102 = $0 ;WAIT_TIMEOUT
        System::Call 'kernel32::TerminateProcess(ir2,i666)'
    ${EndIf}
    System::Call 'kernel32::CloseHandle(ir2)'
${EndIf}
FunctionEnd

Function .onInit
!insertmacro ElevateWithTimeout_OnInit
FunctionEnd

Section
Push 30000
Push "regedit.exe"
call ElevateWithTimeout
SectionEnd

より安全で堅牢なソリューションを作成するには、子インストーラーがゲームに参加し、親がなくなった場合にいつ自分自身を中止するかを知る必要がありますが、純粋な NSIS コードでそれを行うのは非常に手間がかかります。

タイムアウト要件を削除RequestExecutionlevel highestして外部インストーラーで使用し、管理者である場合にのみ子を実行することをお勧めします ( UserInfo::GetAccountType)。

于 2013-02-27T17:24:42.687 に答える