PDA

Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [35] 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

alexfinik
30-10-2013, 18:54
Limonica, Это для кнопки Next 1. Для Back, вроде 2. 3 - надпись между кнопками (ее только изменить можно и не этими операторами)


GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${BM_CLICK} 0 0

Я говорил про изменение размеров интерфейса у некоторых установщиков/программ, из-за пользовательской настройки "точек на дюйм" в системе »
Хм. Ну я в одной и той же системе проверял 2 этих файла.
Что примечательно, с другими *.bmp из стандартной папки, всё работает.

Aster
31-10-2013, 04:56
Хм. Ну я в одной и той же системе проверял 2 этих файла.
Что примечательно, с другими *.bmp из стандартной папки, всё работает. »
Не могли бы сделать скрин, где всё работает? Хотелось бы посмотреть как в рабочем виде выглядит.


Может, настройка DPI у пользователя отличается от стандартной? »
Спасибо. Да, скорее всего Вы правы, видимо из-за этих настроек площадь инсталлера расширяется. Что-нибудь можно с этим сделать? Как-нибудь заставить инсталлер игнорировать пользовательские настройки DPI, чтобы инсталл запускался в стандартном размере. Или это из области фантастики?

K.A.V.
31-10-2013, 08:08
Как-нибудь заставить инсталлер игнорировать пользовательские настройки 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, которая должна помочь, можете проверить, сам не тестировал »

Да вроде ж не в этом дело-то? Ведь с одним рисунком всё есть, а с измененным - нет ничего...

MKN
31-10-2013, 17:23
Определяем букву 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

Aster
31-10-2013, 18:20
Вроде как в 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. Можно изменить картинку по указанному пути, можно взять указанную мной и положить ее по указанному пути.

Salmo
02-11-2013, 13:48
Уважаемые! Определяю наличие главного окна программы через FindWindow. Есть ли возможность найти дочерние окна по типу\названию и определить HWND и, очень важно, - видимое оно, в данный момент, или нет?

MKN
02-11-2013, 14:42
видимое оно, в данный момент, или нет? »

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

Salmo
02-11-2013, 22:42
MKN, Спасибо! Обошелся поиском всех видимых окон и последующей фильтрацией... Как всегда, что-нибудь упустишь! Нужно еще определить размер окна и его расположение на мониторе...

MKN
03-11-2013, 09:53
Нужно еще определить размер окна и его расположение на мониторе... »
И это уже было в доках...

;Функция 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

Salmo
03-11-2013, 14:11
MKN, Вы меня, прямо, балуете, спасибо... Я не лентяй, просто у меня еще нет навыка в поиске информации. Буду изучать и, если что, рассчитываю еще на Ваш опыт...

А можно заставить окно инсталлятора открываться не в центре экрана, а по координатам, которые я укажу в той же системе, что и в вашем примере выше?

MKN
03-11-2013, 15:14
А можно заставить окно инсталлятора открываться не в центре экрана, а по координатам, которые я укажу »
И про это уже было...

!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


Я не лентяй »
Хмм... Шутка ? :)

Salmo
03-11-2013, 18:25
Хмм... Шутка ? » Спасибо... В каждой шутке есть.... Признаю, что выглядит, именно, так.

diakov
04-11-2013, 22:09
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

diakov
05-11-2013, 09:38
kotkovets, спаибо большое, и еще один вопрос, в справке сказано о команде nsExec::Exec для скрытного запуска консольных утилит, cmd и bat файлов, так вот можно запустить cmd файл, но только в видимом режиме и с невозможностью закрытия окна консоли, то есть что бы окно закрывалось уже когда батник завершит все свои дела. Можно воспользоваться ExecShell "open", но тогда как решить проблему невозможности закрытия окна cmd до завершения процесса?




© OSzone.net 2001-2012