Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
CreateFont + WM_SETFONT (https://nsis.sourceforge.io/Docs/Chapter4.html#createfont)
Примеры в ${NSISDIR}\Examples\NSISMenu.nsi и ${NSISDIR}\Contrib\Modern UI\*.nsh
AlekseyPopovv
07-06-2023, 11:47
iglezz, как исправить? DetailPrint друг на друга наваливается.
AlekseyPopovv, Цвет фона надо поменять с прозрачного на нужное значение цвета.
AlekseyPopovv
14-06-2023, 14:05
iglezz,
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $0 $0 1004
System::Call UxTheme::SetWindowTheme(ir0,w"",w"")
SendMessage $0 0x0409 0 0x03C03C
SendMessage $0 0x2001 0 0xFF8C00
Как сделать что бы все цвета работали?
0xFF8C00 тёмно оранжевый, а показывает в районе лазурного.
Или может быть есть другой способ покрасить прогресс бар?
AlekseyPopovv, Цвет здесь нужно подавать в формате BGR
И вместо магических чисел лучше использовать человекочитаемые константы из WinMessages.nsh.
${RGB2BGR} $1 RGB_цвет_прогресса
SendMessage $0 ${PBM_SETBARCOLOR} 0 $1
${RGB2BGR} $1 RGB_цвет_фона
SendMessage $0 ${PBM_SETBKCOLOR} 0 $1
макрос RGB2BGR у меня такой:!define RGB2BGR `!insertmacro RGB2BGR `
!define BGR2RGB `!insertmacro RGB2BGR `
!define ABGR2RGB `!insertmacro RGB2BGR `
!macro RGB2BGR out var
!ifndef DataConv.nsh.tempvars
!define DataConv.nsh.tempvars
Var /Global __convtmp1
Var /Global __convtmp2
!endif
!if ${out} == '-'
!define RGB2BGR:ret ${var}
!else
!define RGB2BGR:ret ${out}
!endif
IntOp $__convtmp1 ${var} >> 16
IntOp $__convtmp2 ${var} & 0xFF00
IntOp ${RGB2BGR:ret} ${var} << 16
IntOp ${RGB2BGR:ret} ${RGB2BGR:ret} & 0xFFFFFF
IntOp ${RGB2BGR:ret} ${RGB2BGR:ret} | $__convtmp1
IntOp ${RGB2BGR:ret} ${RGB2BGR:ret} | $__convtmp2
!undef RGB2BGR:ret
!macroend
AlekseyPopovv
23-06-2023, 06:54
На кастомной странице README имеется Link. Его задача по нажатию загружать разные файлы .rtf. Как сделать что бы при нажатии Link, файлы .rtf сбрасывались на начало документа?
Как сделать что бы при нажатии Link, файлы .rtf сбрасывались на начало документа? »
Отправить richedit контролу сообщение EM_SETSCROLLPOS (https://learn.microsoft.com/en-us/windows/win32/controls/em-setscrollpos)
Получится что-то вроде!define /ifndef /math EM_SETSCROLLPOS ${WM_USER} + 222
System::Call '*(i0,i0)p.R0'
SendMessage HWND_RICHEDIT ${EM_SETSCROLLPOS} 0 $R0
При минимальных ізменениях можно не сбрасывать в 0, а восстанавливать позицию предыдущего документа.
AlekseyPopovv
02-07-2023, 10:34
Скиньте пожалуйста WinVer2.nsh
У меня ругается на:
!define VER_PLATFORM_WIN32s 0
VER_PLATFORM_WIN32s уже определён в Win\WinNT.nsh
А WinVer2.nsh во избежание конфликтов нужно доводить до соответствия актуальной версии NSIS:
Подключить стандартный !include "Win\WinNT.nsh"
Удалить дублирующий !define VER_PLATFORM....
AlekseyPopovv
02-07-2023, 11:20
Буду пробовать. Кстати вышла версия 3.09.
Всем доброго дня.
Тут застрял на такой проблеме, существует ли в NSIS команда, чтобы узнать, находится ли компьютер в домене?
Нашел только это https://nsis.sourceforge.io/WmiInspector_plug-in но оно даже не компилится в юникоде. Тест выдает какие то китайские иероглифы.
Нужно что нибудь простое, типа "да или нет". Как, например в батнике "wmic.exe ComputerSystem get PartOfDomain"
inco1, А есть под рукой для теста комп в домене, на котором это проверить можно?
Наиболее подходящий вариант, похоже, NetGetJoinInformation (https://learn.microsoft.com/en-gb/windows/win32/api/lmjoin/nf-lmjoin-netgetjoininformation)
; https://learn.microsoft.com/en-gb/windows/win32/api/lmjoin/nf-lmjoin-netgetjoininformation
System::Call 'netapi32::NetGetJoinInformation(i 0, *t 0 r0, *i 0 r1)i.r2'
${If} $2 != 0
DetailPrint 'error!'
${Else}
${Select} $1
${Case} 0
StrCpy $2 'NetSetupUnknownStatus'
${Case} 1
StrCpy $2 'NetSetupUnjoined'
${Case} 2
StrCpy $2 'NetSetupWorkgroupName'
${Case} 3
StrCpy $2 'NetSetupDomainName'
${EndSelect}
DetailPrint 'name="$0" joinstatus="$2"'
${EndIf}
Другие варианты:
- GetComputerNameEx и NetWkstaGetInfo из этого поста (http://forum.oszone.net/showthread.php?p=2344054#post2344054)
GetComputerNameEx для ComputerNameDnsDomain (2) для компа не в домене возвращает пустой результат
NetWkstaGetInfo возвращает имя либо домена либо рабочей группы, посему ненадёжна для данной задачи
- Реестр, пустое значение == комп не в домене (надо проверять на корректность)
ReadRegStr $0 HKLM "System\CurrentControlSet\Services\Tcpip\Parameters" "Domain"
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine" "Distinguished-Name"
iglezz, Спасибо. Компа нету чтобы проверить, но буду искать и всё попробую.
iglezz,
Я правильно понял ваш код?
RequestExecutionLevel user
outfile test.exe
!include LogicLib.nsh
Section
System::Call 'netapi32::NetGetJoinInformation(i 0, *t 0 r0, *i 0 r1)i.r2'
${If} $2 != 0
MessageBox MB_OK "компьютер в домене"
${Else}
MessageBox MB_OK "компьютер НЕ в домене"
${EndIf}
SectionEnd
Я правильно понял код от MKN?
RequestExecutionLevel user
outfile test2.exe
!include LogicLib.nsh
Section
System::Call 'kernel32.dll::GetComputerNameExA(i 2, t .r0,*i ${NSIS_MAX_STRLEN} r1)i.r2'
${If} $0 == 0
MessageBox MB_OK "компьютер в домене"
${Else}
MessageBox MB_OK "компьютер НЕ в домене"
${EndIf}
SectionEnd
inco1,
Для обеих функций результат будет иметь минимум три значения - да, нет, ошибка/не_знаю
В случае NetGetJoinInformation полноценный вариант в виде макроса будет выглядеть так:
/* NetGetJoinInformation macro
Retrieves join status information for the specified computer
Usage:
${NetGetJoinInformation} in_computerName out_joinToName out_joinStatus
Parameters:
in_computerName - DNS or NetBIOS name of the computer on which to call the function.
If this parameter is '' or -, the local computer is used.
out_joinToName - NetBIOS name of the domain or workgroup to which the computer is joined
If this parameter is '' or -, the value is not used.
out_joinStatus - Join status of the specified computer:
success:
0 = NetSetupUnknownStatus
1 = NetSetupUnjoined
2 = NetSetupWorkgroupName
3 = NetSetupDomainName
failure:
-SYSTEM_ERROR_CODE, e.g. -53 == ERROR_BAD_NETPATH (53)
https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
https://learn.microsoft.com/en-gb/windows/win32/api/lmjoin/nf-lmjoin-netgetjoininformation
*/
!define NetGetJoinInformation `!insertmacro NetGetJoinInformation `
!macro NetGetJoinInformation in_computerName out_joinToName out_joinStatus
!if '${in_computerName}' == '-'
Push ''
!else
Push '${in_computerName}'
!endif
Exch $0
Push $1
Push $2
System::Call '*(i)p.r1'
System::Call 'netapi32::NetGetJoinInformation(t r0, @ r2, p r1)i.r0'
!if '${out_joinToName}' == ''
!define /redef out_joinToName -
!endif
!if ${out_joinToName} != '-'
!define NetGetJoinInformation[jmp] +5
!else
!define NetGetJoinInformation[jmp] +4
!endif
StrCmp $0 0 0 ${NetGetJoinInformation[jmp]}
;ok
System::Call '*$1(i.r0)' ; get status
System::Free $1
!if ${out_joinToName} != '-'
System::Call '*$2(t.r1)' ; get name
!endif
Goto +3
;not ok
StrCpy $0 -$0 ; -SYSTEM_ERROR_CODE
StrCpy $1 ''
!undef NetGetJoinInformation[jmp]
StrCmp $2 0 +2
System::Call "netapi32::NetApiBufferFree(pr2)"
Pop $2
!if ${out_joinToName} != '-'
Exch $1 ; name
Pop ${out_joinToName}
!else
Pop $1
!endif
Exch $0
Pop ${out_joinStatus}
!macroend
Для локальной машины ${NetGetJoinInformation} '' '' $R0 или ${NetGetJoinInformation} - - $R0
запишет в $R0 результат:
- Отрицательный результат = ошибка
- Неотрицательный результат:
3 = однозначно в домене
1,2 = однозначно не в домене
0 = неизвестно
В простейшем случае, когда (однозначно в домене == Да, в остальных случаях == Нет), можно добавить LogicLib-тест
!define IsInDomain `"" IsInDomain`
!macro _IsInDomain _a _b _t _f
!insertmacro _LOGICLIB_TEMP
${NetGetJoinInformation} `${_b}` - $_LOGICLIB_TEMP
StrCmp $_LOGICLIB_TEMP 3 `${_t}` `${_f}`
!macroend
Тогда проверочное выражение сократится до
${If} ${IsInDomain} ''
DetailPrint 'in domain'
${Else}
DetailPrint 'not in domain'
${EndIf}
Чтобы не лезть в дебри дал проверить на компе в домене. Отлично работает поиск через реестр. Работают обе строки. Этого более чем достаточно.
RequestExecutionLevel user
outfile test3.exe
SilentInstall silent
!include x64.nsh
!include LogicLib.nsh
Function .onInit
Var /GLOBAL Domain
Var /GLOBAL Dom
StrCpy $Dom ""
${If} ${RunningX64}
SetRegView 64
ReadRegStr $Domain HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine" "Distinguished-Name"
SetRegView 32
${Else}
ReadRegStr $Domain HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine" "Distinguished-Name"
${EndIf}
FunctionEnd
Section
${If} $Domain == $Dom
MessageBox MB_OK " Компьютер НЕ в домене "
${Else}
MessageBox MB_OK " Компьютер в домене "
${EndIf}
SectionEnd
RequestExecutionLevel user
outfile test4.exe
SilentInstall silent
!include LogicLib.nsh
Function .onInit
Var /GLOBAL Domain
Var /GLOBAL Dom
StrCpy $Dom ""
ReadRegStr $Domain HKLM "System\CurrentControlSet\Services\Tcpip\Parameters" "Domain"
FunctionEnd
Section
${If} $Domain == $Dom
MessageBox MB_OK " Компьютер НЕ в домене "
${Else}
MessageBox MB_OK " Компьютер в домене "
${EndIf}
SectionEnd
inco1,
В этом фрагменте нет смысла дублировать ReadRegStr:${If} ${RunningX64}
SetRegView 64
ReadRegStr $Domain HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine" "Distinguished-Name"
SetRegView 32
${Else}
ReadRegStr $Domain HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine" "Distinguished-Name"
${EndIf}
Он сокращается до
${IfThen} ${RunningX64} ${|} SetRegView 64 ${|}
ReadRegStr $Domain HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine" "Distinguished-Name"
SetRegView lastused
и дальше сверять можно с пустым значением ${If} $Domain == ""
MessageBox MB_OK " Компьютер НЕ в домене "
${Else}
MessageBox MB_OK " Компьютер в домене "
${EndIf}
iglezz,
А можно ли сократить, к примеру вот такой фрагмент:
SetRegView 64
DeleteRegKey HKEY_LOCAL_MACHINE "Software\Classes\CLSID\test"
SetRegView 32
DeleteRegKey HKEY_LOCAL_MACHINE "Software\Classes\CLSID\test"
inco1,
Для эпизодически встречающихся одиночных инструкций можно написать макрос вроде такого:!define DeleteRegKey3264 `!insertmacro DeleteRegKey3264 `
!macro DeleteRegKey3264 REGROOT REGKEY
SetRegView 64
DeleteRegKey ${REGROOT} '${REGKEY}'
SetRegView 32
DeleteRegKey ${REGROOT} '${REGKEY}'
!macroend
и далее использовать как ${DeleteRegKey3264} HKEY_LOCAL_MACHINE "Software\Classes\CLSID\test"
Если есть группа ключей, то её можно вынести в макрос и использовать его вместе с SetRegView:
!macro DeleteSomeKeys
DeleteRegKey HKEY_LOCAL_MACHINE ...
DeleteRegKey HKEY_LOCAL_MACHINE ...
...
!macroend
...
SetRegView 64
!insertmacro DeleteSomeKeys
SetRegView 32
!insertmacro DeleteSomeKeys
AlekseyPopovv
11-07-2023, 14:24
iglezz, как создать xml файл с таким содержимым: :o
<?xml version="1.0" encoding="UTF-8"?>
<RDLXSettings>
<LangIDList/>
<Common CreateBackupCopy="0" ShowSplashScreen="0">
<AutoSave Enable="0" Interval="1"/>
</Common>
<ProjectHistory LoadlastProject="0" NoProject="1"/>
<Spelling Type="1">
<HunSpellDictionary Enabled="1">$EXEDIR\${APPDIR}\ru-RU.dic</HunSpellDictionary>
</Spelling>
</RDLXSettings>
Соответственно потом нужно будет удалять строку:
<HunSpellDictionary Enabled="1">$EXEDIR\${APPDIR}\ru-RU.dic</HunSpellDictionary>
А потом заново записывать эту строку.
Проблема со строкой:
<Common CreateBackupCopy="0" ShowSplashScreen="0">
Она записывается так:
<Common>CreateBackupCopy="0" ShowSplashScreen="0"</Common>
И как туда добавить:
<AutoSave Enable="0" Interval="1"/>
ума не приложу... :(
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC