Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
alexfinik
30-10-2013, 18:54
Limonica, Это для кнопки Next 1. Для Back, вроде 2. 3 - надпись между кнопками (ее только изменить можно и не этими операторами)
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${BM_CLICK} 0 0
Я говорил про изменение размеров интерфейса у некоторых установщиков/программ, из-за пользовательской настройки "точек на дюйм" в системе »
Хм. Ну я в одной и той же системе проверял 2 этих файла.
Что примечательно, с другими *.bmp из стандартной папки, всё работает.
Хм. Ну я в одной и той же системе проверял 2 этих файла.
Что примечательно, с другими *.bmp из стандартной папки, всё работает. »
Не могли бы сделать скрин, где всё работает? Хотелось бы посмотреть как в рабочем виде выглядит.
Может, настройка DPI у пользователя отличается от стандартной? »
Спасибо. Да, скорее всего Вы правы, видимо из-за этих настроек площадь инсталлера расширяется. Что-нибудь можно с этим сделать? Как-нибудь заставить инсталлер игнорировать пользовательские настройки DPI, чтобы инсталл запускался в стандартном размере. Или это из области фантастики?
Как-нибудь заставить инсталлер игнорировать пользовательские настройки DPI, чтобы инсталл запускался в стандартном размере. Или это из области фантастики? »
Вроде как в 3.0 Alpha 0 ввели команду ManifestDPIAware, которая должна помочь, можете проверить, сам не тестировал
alexfinik
31-10-2013, 14:46
Aster, красным обозначено то, что работает. Черным - измененный рисунок
Ниже - простейший код, где показывается или НЕ показывается изображение слева.
Значок слева наверху у вас отсутствует из-за измененного или отсутствующего значка (это оценочное суждение, только предполагаю) в папка ../icons (относительно Header). По-видимому отсутствует или изменен файл modern-install.ico
http://forum.oszone.net/attachment.php?attachmentid=106079&stc=1&d=1383215681
!include MUI2.nsh
Name "nsDialogs Example"
OutFile "nsDialogs Example.exe"
XPStyle on
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\orange-r.bmp"
!insertmacro MUI_LANGUAGE "Russian"
!insertmacro MUI_PAGE_INIT
Section
SectionEnd
alexfinik
31-10-2013, 14:47
Цитата Aster:
Как-нибудь заставить инсталлер игнорировать пользовательские настройки DPI, чтобы инсталл запускался в стандартном размере. Или это из области фантастики? »
Вроде как в 3.0 Alpha 0 ввели команду ManifestDPIAware, которая должна помочь, можете проверить, сам не тестировал »
Да вроде ж не в этом дело-то? Ведь с одним рисунком всё есть, а с измененным - нет ничего...
Определяем букву CD/DVD привода и есть ли в нём диск.
Букву дисков можно конечно определить с помощью штатной команды GetDrives, но и этот код может пригодиться :
OutFile "GetCDVolume.exe"
Section
Push $0
Push $1
Push $2
Push $3
; Выделяем блок памяти для определения максимальной длины строковой переменной
System::Alloc ${NSIS_MAX_STRLEN}
Pop $3
; GetLogicalDriveStringsA - Определяет все диски ( заполняет буфер строками, которые определяют действительные устройства в системе )
System::Call 'kernel32::GetLogicalDriveStringsA(i, i) i(${NSIS_MAX_STRLEN}, r3)'
Loop:
; Функция lstrlenA возвращает длину строки в символах по указателю.
; Именно lstrlenA используется для строк в формате ANSI. Используем эту функцию для получения длины строки.
System::Call 'kernel32::lstrlenA(t) i(i r3) .r2'
IntCmp $2 0 End
/*GetDriveTypeA - получение информации о типе диска
DRIVE_UNKNOWN - 0 Тип устройства не может быть определен.
DRIVE_NO_ROOT_DIR - 1 Корневой путь недопустим; например нет никаких томов, смонтированных по указанному пути.
DRIVE_REMOVABLE - 2 Удаляемые медиаустройства, например, флоппи-диск или съёмный жесткий диск.
DRIVE_FIXED - 3 Устройства , которые не могут быть удалены, например, фиксированный жесткий диск.
DRIVE_REMOTE - 4 удаленное (сетевое) устройство
DRIVE_CDROM - 5 устройство CD/DVD - ROM
DRIVE_RAMDISK - 6 RAM диск*/
System::Call 'kernel32::GetDriveTypeA(t) i(i r3) .r1'
StrCmp $1 5 0 Next ; проверка наличия диска
; получаем информацию о доступном месте на диске
System::Call 'kernel32::GetDiskFreeSpaceExA(t, *l, *l, *l) i(i r3, 0, .r1, 0)'
StrCmp $1 0 +3
StrCpy $1 "Диск в приводе"
Goto +2
StrCpy $1 "В приводе НЕТ диска"
System::Call '*$3(&t${NSIS_MAX_STRLEN} .r0)' ; буква(путь) диска
MessageBox MB_OK|MB_TOPMOST "Буква диска : $0 Состояние привода : $1 "
Next:
IntOp $3 $3 + $2
IntOp $3 $3 + 1
Goto Loop
End:
System::Free $3
Pop $3
Pop $2
Pop $1
Pop $0
SectionEnd
Вроде как в 3.0 Alpha 0 ввели команду ManifestDPIAware, которая должна помочь, можете проверить, сам не тестировал »
А есть ли примеры для это команды? В каком виде в скрипте её прописывать?
Я думаю эта информация потом и для справочника NSIS будет полезна.
Да вроде ж не в этом дело-то? Ведь с одним рисунком всё есть, а с измененным - нет ничего... »
У меня простая логика. Если размер интерфейса инсталлера не будет расширяться и запустится в стандартном размере, то и с картинками всё будет нормально. Я показал скрин, где масштаб окон установщика увеличился. Вот и я хочу чтобы у всех и независимо ни от чего мой инсталлер запускался в родном размере. А кроме как эти самые настройки DPI, не вижу других причин почему размер установщика расширяется.
kotkovets
31-10-2013, 19:20
4.8.1.29 ManifestDPIAware
notset|true|false
---
начиная от версии 3.0 Alpha 0
пишется вне секции и функции
---
это команда масштабирует только текст (элементы диалога), что бы текст не размывался, при изменении DPI
т.е к растровое изображение не масштабирует..
так гласит справка..
alexfinik
01-11-2013, 13:38
У меня простая логика. Если размер интерфейса инсталлера не будет расширяться и запустится в стандартном размере, то и с картинками всё будет нормально. Я показал скрин, где масштаб окон установщика увеличился. Вот и я хочу чтобы у всех и независимо ни от чего мой инсталлер запускался в родном размере. А кроме как эти самые настройки DPI, не вижу других причин почему размер установщика расширяется. »
Логика логикой, а установили бы себе NSIS и попробовали. Это пять минут.
1. Ставите
2. Запускаете хотя бы и мой пример, указанный выше (сохраняя файл в *.nsi).
3. Можно изменить картинку по указанному пути, можно взять указанную мной и положить ее по указанному пути.
Уважаемые! Определяю наличие главного окна программы через FindWindow. Есть ли возможность найти дочерние окна по типу\названию и определить HWND и, очень важно, - видимое оно, в данный момент, или нет?
видимое оно, в данный момент, или нет? »
StrCpy $0 "hwnd"
System::Call "user32::IsWindowVisible(i r0)i.r0"
# $0 here is non-zero if the window is visible.
найти дочерние окна по типу\названию и определить HWND »
попробуй через EnumChildWindow (в доке есть код )
или EnhancedFindWindow
Вот код, перечислит все видимые окна :
!include LogicLib.nsh
showinstdetails show
outfile wind.exe
Section
System::Get "(i.r1) iss"
Pop $R0
System::Call "user32::EnumWindows(k R0,i) i.s"
loop:
Pop $0
StrCmp $0 "callback1" 0 done
System::Call "user32::IsWindowVisible(ir1)i.r2"
${If} $2 <> 0
System::Call "user32::GetWindowText(ir1,t.r2,i${NSIS_MAX_STRLEN})"
System::Call "user32::GetClassName(ir1,t.r3,i${NSIS_MAX_STRLEN})"
IntFmt $1 "0x%X" $1
DetailPrint "$1 - [$3] $2"
${EndIf}
Push 1 # callback's return value
System::Call "$R0"
Goto loop
done:
System::Free $R0
Sectionend
MKN, Спасибо! Обошелся поиском всех видимых окон и последующей фильтрацией... Как всегда, что-нибудь упустишь! Нужно еще определить размер окна и его расположение на мониторе...
Нужно еще определить размер окна и его расположение на мониторе... »
И это уже было в доках...
;Функция GetWindowRect извлекает размеры рабочего прямоугольника определяемого окна.
;Размеры даются в экранной системе координат, которые считаются относительно
; левого верхнего угла экрана
; Create RECT struct
System::Call "*${stRECT} .r1"
; Find Window info for the window we're displaying
System::Call "User32::GetWindowRect(i, i) i ($HWNDPARENT, r1) .r2"
Если ещё конкретней, то как то так :
OutFile Rect_test.exe
Section
Push $R0
System::Call /NOUNLOAD "*(i, i, i, i) i.s"
Pop $R0
System::Call /NOUNLOAD 'User32::GetWindowRect(i, i) i ($HWNDPARENT, R0)'
System::Call /NOUNLOAD "*$R0(i .s, i .s, i .s, i .s)"
Pop $0 ;left
Pop $1 ;top
Pop $2 ;right
Pop $3 ;bottom
Messagebox mb_ok "$$0:$0 $$1:$1 $$2:$2 $$3:$3"
SectionEnd
А ещё есть функция GetWindowInfo с хорошими примерами : http://nsis.sourceforge.net/GetWindowInfo
MKN, Вы меня, прямо, балуете, спасибо... Я не лентяй, просто у меня еще нет навыка в поиске информации. Буду изучать и, если что, рассчитываю еще на Ваш опыт...
А можно заставить окно инсталлятора открываться не в центре экрана, а по координатам, которые я укажу в той же системе, что и в вашем примере выше?
А можно заставить окно инсталлятора открываться не в центре экрана, а по координатам, которые я укажу »
И про это уже было...
!include "MUI2.nsh"
!define MUI_CUSTOMFUNCTION_GUIINIT Welcome
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
OutFile RepositionWindow_test.exe
!define stRECT "(i, i, i, i) i"
!define SPI_GETWORKAREA 0x0030
Function Welcome
; Создать RECT структуру. Внутри этой структуры координаты углов.
; Верхний левый угол определяется двумя координатами left и top.
; Нижний правый соответственно определяется двумя оставшимися координатами - right и bottom.
System::Call "*${stRECT} .r1"
; Получить окно прямоугольника.Функция GetWindowRect отыскивает размеры рамки ограничивающей прямоугольник
;определяемого окна. Размеры даны в экранных координатах, которые расположены относительно левого верхнего угла экрана.
System::Call "User32::GetWindowRect(i, i) i ($HWNDPARENT, r1) .r2"
; Получить координаты
System::Call "*$1${stRECT} (.r2, .r3, .r4, .r5)"
; Рассчитать ширину / высоту нашего окна
IntOp $2 $4 - $2 ; $2 - ширина
IntOp $3 $5 - $3 ; $3 - высота
; Определить размер рабочего стола без панели задач
System::Call "User32::SystemParametersInfo(i, i, i, i) i (${SPI_GETWORKAREA}, 0, r1, 0) .r4"
; Получить координаты
System::Call "*$1${stRECT} (.r4, .r5, .r6, .r7)"
System::Free $1
; правую сторону экрана разделить на 4
IntOp $0 $6 / 4
IntOp $8 $2 / 4
IntOp $0 $0 - $8
; нижнюю часть экрана разделить на 4
IntOp $1 $7 / 4
IntOp $8 $3 / 4
IntOp $1 $1 - $8
;Установить новую позицию окна
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, 0, $0, $1, 0, 0, 0x201)"
FunctionEnd
Section
SectionEnd
Я не лентяй »
Хмм... Шутка ? :)
Хмм... Шутка ? » Спасибо... В каждой шутке есть.... Признаю, что выглядит, именно, так.
kotkovets, подскажите пожалуйста как такой батник выполнить командами nsis:
@Echo Off
color 1e
Title “Обновление Microsoft Office 2013
::“Обновление Microsoft Office 2013
set "path=%SystemRoot%;%SystemRoot%\system32;%SystemRoot%\system32\wbem"
reg export HKLM\Software\Policies\Microsoft\Windows\Installer "%temp%\installer.reg"
reg add HKLM\Software\Policies\Microsoft\Windows\Installer /v MaxPatchCacheSize /t REG_DWORD /d 0 /f
net stop msiserver
cls
for /f %%i in ('dir /b /O-s Updates\*.msp') do (Call :SetupUpd %%i)
:SetupUpd
echo “Обновление %1
Updates\%1 /qn /norestart
GoTo :EOF
kotkovets
05-11-2013, 00:59
подскажите пожалуйста как такой батник выполнить командами nsis: »
!include "MUI2.nsh"
!include "FileFunc.nsh"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
ShowInstDetails show
outfile nets.exe
Section
SetDetailsPrint textonly
DetailPrint "Обновление Microsoft Office 2013"
SetDetailsPrint none
IfFileExists "$TEMP\installer.reg" 0 +2
Delete "$TEMP\installer.reg"
SetDetailsPrint listonly
nsExec::Exec 'reg export HKLM\Software\Policies\Microsoft\Windows\Installer "$TEMP\installer.reg"'
Pop $0
nsExec::Exec 'reg add HKLM\Software\Policies\Microsoft\Windows\Installer /v MaxPatchCacheSize /t REG_DWORD /d 0 /f'
Pop $0
nsExec::Exec 'net stop msiserver'
Pop $0
StrCmp $0 2 0 +3
MessageBox MB_OK "$0 Служба не запущена или хз" IDOK
Abort
SetDetailsPrint none
${Locate} "Путь к папке\Updates" "/L=F /M=*.msp /G=0" Updates
SetDetailsPrint both
SectionEnd
Function Updates
SetDetailsPrint textonly
DetailPrint "Обновление Microsoft Office 2013"
SetDetailsPrint listonly
DetailPrint "Обновление $R7"
ExecWait 'msiexec /i "$R9" /norestart /qn' $R1
;dumpstate::debug
Push $0
FunctionEnd
Насчет команды запуска *.msp файлов на примере msi
ExecWait 'msiexec /i "$R9" /norestart /qn' $R1
В $R9 - путь к файлу\*.msp
В общем допиливайте опытным путем до рабочего состояния - примерно так...
---
p.s
и в конце предложите перезагрузиться..
Limonica
05-11-2013, 01:33
kotkovets, пересматриваю ваш код по установке устройств, но есть странная особенность установка\обновление идет только в том случае если устройство уже установленно, если же оно не установленно ничего не происходит. Тестировался нижеследущий код XP Professional - все ок, XP Home - установка не проходит, в чем может быть проблема, непонятно, буду благодарен если посмотрите...
!define ERROR_NO_SUCH_DEVINST -536870389
!define SPOST_NONE 0
!define SPOST_PATH 1
!define SPOST_URL 2
!define SP_COPY_DELETESOURCE 0x1
!define SP_COPY_REPLACEONLY 0x2
!define SP_COPY_NOOVERWRITE 0x8
!define SP_COPY_OEMINF_CATALOG_ONLY 0x40000
!define CM_LOCATE_DEVNODE_NORMAL 0x00000000
!define CM_REENUMERATE_NORMAL 0
!define InstallDriver "!insertmacro InstallDriverCall"
!include "logiclib.nsh"
!macro InstallDriverCall HID INFPATH INFDIR
System::Store S
Push "${INFDIR}"
Push "${INFPATH}"
Push "${HID}"
DetailPrint "Rescan drivers..."
System::Call "cfgmgr32::CM_Locate_DevNode(*i.r0, n, i${CM_LOCATE_DEVNODE_NORMAL}) i.r1"
${If} $1 <> 0
StrCpy $1 1
${Else}
System::Call "cfgmgr32::CM_Reenumerate_DevNode (ir0, i${CM_REENUMERATE_NORMAL}) i.r1"
${IfThen} $1 <> 0 ${|}StrCpy $1 2${|}
${EndIf}
${If} $1 = 0
DetailPrint "Installing the driver..."
System::Call "newdev::UpdateDriverForPlugAndPlayDevices(i0, ts, tss, i0, *i0)?ei.s"
Pop $0
IntCmp $0 ${ERROR_NO_SUCH_DEVINST} 0 +2 +2
DetailPrint "The device is not plugged in, cannot update the driver."
${If} $0 = 0
System::Call "setupapi::SetupCopyOEMInf(ts, ts, i${SPOST_PATH}, i0, i0, i0, *i0, tn)i.r0"
IntCmp $0 1 0 +2 +2
DetailPrint "Istall driver success!"
IntCmp $0 0 0 +2 +2
DetailPrint "Istall driver error!"
${EndIf}
${ElseIf} $1 = 1
DetailPrint "An error occurred while trying to get the device instance for the machine"
${ElseIf} $1 = 2
DetailPrint "An error occurred while trying to refresh the device list"
${EndIf}
System::Store L
!macroend
OutFile InstDrv.exe
ShowInstDetails show
Section
# ${InstallDriver} "HWID" "путь к inf файлу" "папка с дровами"
${InstallDriver} "ROOT\RDPDR" "$WINDIR\inf\machine.inf" "$WINDIR\inf"
SectionEnd
kotkovets, спаибо большое, и еще один вопрос, в справке сказано о команде nsExec::Exec для скрытного запуска консольных утилит, cmd и bat файлов, так вот можно запустить cmd файл, но только в видимом режиме и с невозможностью закрытия окна консоли, то есть что бы окно закрывалось уже когда батник завершит все свои дела. Можно воспользоваться ExecShell "open", но тогда как решить проблему невозможности закрытия окна cmd до завершения процесса?
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC