Приложение не всегда выходит на первое место после установки и запуска приложения

#wix #windows-installer #nsis

#wix #windows-установщик #nsis

Вопрос:

У нас есть система установки, основанная на MSI, построенной на WIX. Загрузчик — это NSI. Просто так все и пошло. И сейчас все работает нормально, если не считать одного небольшого сбоя.

Есть два установщика NSI. Один для новых пользователей. Это запускает MSI обычным образом, поэтому можно согласиться с их контрактным экраном. Приложение проверяет наличие обновлений, и пользователь может это сделать. Это второй пакет NSIS для этого:

 Section -RA_unzip
    InitPluginsDir
    ReadRegStr $R1 HKCU "SoftwareCompanyAppFolderProperty" "User Directory"
    SetOutPath $R1
    File "f:cppAppNamedeploymentAppName.msi"
    ExecWait 'msiexec /i "$R1AppName.msi" /L* msi.log /passive /norestart' $0
SectionEnd
      
Section -r_name_dlls
    ReadRegStr $R0 HKCU "SoftwareCompanyAppFolderProperty" "Program Directory"
    Rename $R0libssl_3.dll $R0libssl-3.dll
    Rename $R0libcrypto_3.dll $R0libcrypto-3.dll
SectionEnd

Section -Finishing Up
    Sleep 1000
SectionEnd

Section -restartRA
    ReadRegStr $R0 HKCU "SoftwareCompanyAppFolderProperty" "Program Directory"
    Exec $R0ars.exe
    Quit
SectionEnd
 

Менее чем в половине случаев приложение достигает вершины Z-порядка. Иногда оно оказывается внизу! Это происходит на моем Windows7 и Windows10 моей жены. Если я запущу это, не натыкаясь на версию MSI (она просто завершается без установки), тогда окно приложения всегда будет отображаться вверху.

Я даже добавил BringWindowToTop(*GetMainWnd()); в конце инициализации, когда главное окно хорошо установлено и запущено. И я действительно думал, что это как-то связано с тем, что установщик Windows медленно выходит, вот почему Sleep 1000 . Это не имело никакого значения.

Единственное, что можно сказать наверняка, это то, что это происходит, когда установщик Windows фактически выполняет установку.

Комментарии:

1. Если вы знаете, как писать программное обеспечение для Windows, вы можете попробовать создать приложение, которое вызывает GetForegroundWindow в цикле для отслеживания активного окна.

2. Привет @Anders, поэтому я запустил консольное приложение, которое каждые 10 мс записывает дескриптор и название окна окна переднего плана в текстовый файл. Оказывается, наше окно никогда не выходит на первое место. И консоль также вызывалась с помощью NSIS: Exec. Окно консоли остается на вершине. И я ничего не могу найти в документах, чтобы изменить поведение NSIS: Exec. Для меня это просто странно.

3. Привет @Anders и спасибо. Итак, у меня есть сеанс NSIS, который просто запускает регистратор, затем блокнот, затем мое приложение. Половина попыток моего приложения действительно выходит на первое место. Другая половина, и она появляется в разделе «блокнот». В последних 5 тестах мое приложение занимало первое место 4 раза, а затем в блокноте и окне консоли последним.

4. Не запускайте диагностическое приложение из установщика, запустите его первым и никогда не позволяйте ему быть активным окном.

Ответ №1:

Вызов Quit непосредственно после Exec этого не является хорошей идеей, потому что, если установщик завершит работу до того, как дочерний процесс отобразит свое окно, право на установку окна переднего плана будет потеряно.

Вы могли бы попробовать

 ExecShell /WAITFORINPUTIDLE "" "$R0ars.exe"
Sleep 1000
Quit 
 

Комментарии:

1. Я попробую! Спасибо.

2. Я доволен. Я просто запускал его примерно 30 раз подряд, и мое приложение каждый раз оказывалось на вершине. Это работало с plane Exec.

3. Это может работать с простым Exec, но ExecShell с WAITFORINPUTIDLE еще лучше, он ждет, пока дочерний элемент не начнет обрабатывать сообщения.

4. Хорошо, я сделаю это таким образом. Все, что угодно, чтобы сократить сбои. Большое вам спасибо за вашу помощь.