Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
AlekseyPopovv
14-08-2023, 13:26
Никогда не сталкивался с ограничением в 2 гига и вот опять, есть возможность обойти это без "Nsis7z"?
AlekseyPopovv, nsisbi (https://sourceforge.net/projects/nsisbi/)
iglezz, Доброго дня.
Возникла проблема.
Использую ваш метод добавления записей в реестр для всех имеющихся учетных записей. Всё отлично работает. Но как прописать, если в системе есть только одна активная учетная запись, то чтобы запись в реестр прописывалась только активной учетке?
Используется код:
Function SIDFilter_UsersOnly
System::Store L
Pop $0
StrCpy $1 $0 8
StrCmp $1 "S-1-5-21" +3 0
StrCpy $1 ""
System::Store S
Push $1
FunctionEnd
Function ProcUsers
System::Store L
Pop $0
Pop $1
${EnumUsersRegEx_GetProfilePath} $3 $1
${If} $3 != ""
WriteRegDWORD HKU "$0\SOFTWARE\test" "tt" 0x1
${EndIf}
System::Store S
FunctionEnd
Потом в нужном месте вставляется вызов этих функций:
${EnumUsersRegEx} ProcUsers SIDFilter_UsersOnly
Всё отлично работает и всем учеткам системы добавляется в реестр запись.
Как можно прописать, чтобы,если имеется только одна активная учетка, то прописывалось не вызов этих функций, а простая запись:
WriteRegDWORD HKEY_CURRENT_USER "SOFTWARE\test" "tt" 0x1
Как это можно сделать? Неактивные и прочие учетки игнорировать.
Буду очень признателен за ваше пояснение.
inco1, Можно посчитать в некую переменную число залогиненных учётных записей.
А потом что, если их больше одной?
iglezz,
Я, видимо не так объяснил.
Если такое возможно, то хотелось бы сделать так, чтобы было некое условие, что если число пользователей "S-1-5-21" более одного, то срабатывает этот код:
Function SIDFilter_UsersOnly
System::Store L
Pop $0
StrCpy $1 $0 8
StrCmp $1 "S-1-5-21" +3 0
StrCpy $1 ""
System::Store S
Push $1
FunctionEnd
Function ProcUsers
System::Store L
Pop $0
Pop $1
${EnumUsersRegEx_GetProfilePath} $3 $1
${If} $3 != ""
WriteRegDWORD HKU "$0\SOFTWARE\test" "tt" 0x1
${EndIf}
System::Store S
FunctionEnd
Section
${EnumUsersRegEx} ProcUsers SIDFilter_UsersOnly
SectionEnd
А если пользователь "S-1-5-21" только один, то чтобы срабатывал этот код:
Section
WriteRegDWORD HKEY_CURRENT_USER "SOFTWARE\test" "tt" 0x1
SectionEnd
Посчитать пользователей не сложно !define CountOnlineUsers `!insertmacro CountOnlineUsers `
!macro CountOnlineUsers outVar
Push $0
Push $1
Push $2
Push $3
StrCpy $0 0
StrCpy $1 -1
${Do}
IntOp $1 $1 + 1
EnumRegKey $2 HKU '' $1
${IfThen} $2 == '' ${|} ${ExitDo} ${|}
StrCpy $3 $2 8
${If} $3 == 'S-1-5-21'
StrCpy $3 $2 '' -8
${IfThen} $3 != '_Classes' ${|} IntOp $0 $0 + 1 ${|}
${EndIf}
${Loop}
Pop $3
Pop $2
Pop $1
Exch $0
Pop ${outVar}
!macroend
Section OnlineUsers
${CountOnlineUsers} $0
DetailPrint 'online users: [$0]'
SectionEnd
Но смысл в этом есть только для случая, когда выполняются разные действия для одного и нескольких пользователей.
iglezz,
Премного-премного благодарю. Это как раз тот счетчик, что я хотел.
iglezz, Доброго дня.
Рано обрадовался. Протестировал счетчик на практике. Как выяснилось, он видит только пользователей, которые вошли в систему. Если в систему вошел только один пользователь, то счетчик одного и видит.
inco1, да, счётчик считает вошедших пользователей.
По какому критерию надо считать пользователей активными?
iglezz, тех, что записаны в реестре в S-1-5-21 и не считать S-1-5-21-.............._Classes
Ближе к цели будет отфильтровать пользователей по наличию профиля
!define CountUsersR `!insertmacro CountUsersR `
!macro CountUsersR outVar
Push $0
Push $1
Push $2
Push $3
StrCpy $0 ''
StrCpy $1 -1
${Do}
IntOp $1 $1 + 1
EnumRegKey $2 HKLM 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' $1
${IfThen} $2 == '' ${|} ${ExitDo} ${|}
StrCpy $3 $2 8
${IfThen} $3 == 'S-1-5-21' ${|} IntOp $0 $0 + 1 ${|}
${Loop}
Pop $3
Pop $2
Pop $1
Exch $0
Pop ${outVar}
!macroend
iglezz,
Да. Работает корректно. Даже учетку "Администратор" , которую я когда то активировал на восьмерке сосчитало (это та, что S-1-5-21......................500 и которой нету в HKU).
Огромнейшее спасибо.
В HKEY_USERS находятся вошедшие пользователи и системные учётки (System, LocalService, NetworkService), от лица которых запущена пачка процессов/сервисов.
Стоит ещё помнить, что
HKEY_CURRENT_USER - отображение HKEY_USERS\<SID текущего пользователя>
HKEY_CURRENT_USER\Software\Classes - отображение HKEY_USERS\<SID текущего пользователя>_Classes
HKEY_CLASSES_ROOT - объединённое отображение (https://learn.microsoft.com/en-us/windows/win32/sysinfo/merged-view-of-hkey-classes-root)HKEY_CURRENT_USER\Software\Classes и HKEY_LOCAL_MACHINE\Software\Classes
!include EnumUsersRegEx.nsh
RequestExecutionLevel user
ShowInstDetails show
; SetFont 'Fira Code Retina' 9
SetFont 'Consolas' 9
InstallColors /windows
; ChangeUI all "${MYNSISDIREXAMPLES}\Contrib\UIs\largelog.exe"
; https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids
; https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netquerydisplayinformation
; https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/ns-lmaccess-net_display_user
; https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netusergetinfo
!define GetUserSID `!insertmacro GetUserSID `
!macro GetUserSID outSID username
${If} '${username}' != ''
Push '${username}'
Exch $0 ; [in] username / [out] outSID
Push $1 ; SID struct
System::Call "*(&t${NSIS_MAX_STRLEN})p.r1"
System::Call 'advapi32::LookupAccountName(t,t,p,*i,t,*i,*i)i (n,r0,r1,${NSIS_MAX_STRLEN},n,${NSIS_MAX_STRLEN},n).r0'
${If} $0 != 0
System::Call 'advapi32::ConvertSidToStringSid(p,*t) (r1,.r0)'
${Else}
StrCpy $0 ''
${EndIf}
System::Free $1
Pop $1
Exch $0
Pop ${outSID}
${Else}
StrCpy ${outSID} ''
${EndIf}
!macroend
/* NET_DISPLAY_USER.usri1_flags flags:
UF_SCRIPT=0x0001
UF_ACCOUNTDISABLE=0x0002
UF_PASSWD_NOTREQD=0x0020
UF_NORMAL_ACCOUNT=0x0200
UF_DONT_EXPIRE_PASSWD=0x10000
UF_ACCOUNT_TYPE_MASK=UF_TEMP_DUPLICATE_ACCOUNT|UF_NORMAL_ACCOUNT|UF_INTERDOMAIN_TRUST_ACCOUNT|UF_WOR KSTATION_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT
UF_DONT_REQUIRE_PREAUTH=0x400000
UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED=0x0080
UF_HOMEDIR_REQUIRED=0x0008
UF_INTERDOMAIN_TRUST_ACCOUNT=0x0800
UF_LOCKOUT=0x0010
UF_MACHINE_ACCOUNT_MASK=UF_INTERDOMAIN_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT|UF_SERVER_TRUST_AC COUNT
UF_MNS_LOGON_ACCOUNT=0x20000
UF_NOT_DELEGATED=0x100000
UF_NO_AUTH_DATA_REQUIRED=0x2000000
UF_PARTIAL_SECRETS_ACCOUNT=0x4000000
UF_PASSWD_CANT_CHANGE=0x0040
UF_PASSWORD_EXPIRED=0x800000
UF_SERVER_TRUST_ACCOUNT=0x2000
UF_SETTABLE_BITS=UF_SCRIPT|UF_ACCOUNTDISABLE|UF_LOCKOUT|UF_HOMEDIR_REQUIRED|UF_PASSWD_NOTREQD|UF_PAS SWD_CANT_CHANGE|UF_ACCOUNT_TYPE_MASK|UF_DONT_EXPIRE_PASSWD|UF_MNS_LOGON_ACCOUNT|UF_ENCRYPTED_TEXT_PA SSWORD_ALLOWED|UF_SMARTCARD_REQUIRED|UF_TRUSTED_FOR_DELEGATION|UF_NOT_DELEGATED|UF_USE_DES_KEY_ONLY| UF_DONT_REQUIRE_PREAUTH|UF_PASSWORD_EXPIRED|UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION|UF_NO_AUTH_DAT A_REQUIRED|UF_USE_AES_KEYS|
UF_SMARTCARD_REQUIRED=0x40000
UF_TEMP_DUPLICATE_ACCOUNT=0x0100
UF_TRUSTED_FOR_DELEGATION=0x80000
UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION=0x1000000
UF_USE_AES_KEYS=0x8000000
UF_USE_DES_KEY_ONLY=0x200000
UF_WORKSTATION_TRUST_ACCOUNT=0x1000
*/
!define CountUsersQ `!insertmacro CountUsersQ - `
!define PrintUsersQ `!insertmacro CountUsersQ show `
!macro CountUsersQ showinfo outVar
Push $0 ; [out] result
Push $1 ; number of struct_NET_DISPLAY_USER entries
Push $2 ; pointer to first struct_NET_DISPLAY_USER entry
Push $3 ; tmp
Push $4 ; username
Push $5 ;
Push $6 ;
Push $7 ;
Push $8 ;
Push $9 ;
Push $R0
StrCpy $0 0
StrCpy $R0 ''
System::Call "netapi32::NetQueryDisplayInformation(tn,i1,i0,i-1,i${NSIS_MAX_STRLEN},*i.r1,*i.r2)i.r3"
${If} $3 = 0
${For} $3 1 $1
System::Call "*$2(t.r4,t,i.r5,t.r6,i,i)"
${GetUserSID} $9 $4
${EnumUsersRegEx_GetProfilePath} $8 $9
!if '${showinfo}' == 'show'
DetailPrint 'SID::: $9'
IntFmt $5 0x%08X $5
StrCpy $R0 'FLAGS: $5'
IntOp $7 $5 & 0x0002 ; UF_ACCOUNTDISABLE
StrCmp $7 0 +2
StrCpy $R0 '$R0 DISABLED'
DetailPrint $R0
DetailPrint 'NAME:: $4 ($6)'
DetailPrint 'PROF:: [$8]'
DetailPrint ''
!endif
StrCmp $8 '' +2
IntOp $0 $0 + 1
IntOp $2 $2 + 24 ; move ptr to next struct in buffer
${Next}
System::Call "netapi32::NetApiBufferFree(i) (r2)"
${EndIf}
Pop $R0
Pop $9
Pop $8
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
Pop ${outVar}
!macroend
Section CountUsers
${PrintUsersQ} $0
SectionEnd
AlekseyPopovv
24-09-2023, 17:29
Ярлыки добавляю в меню пуск:
SetShellVarContext all
RMDir /r "$SMPROGRAMS\${APPNAME}"
CreateDirectory "$SMPROGRAMS\${APPNAME}"
CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\${APPEXE}"
CreateShortCut "$SMPROGRAMS\${APPNAME}\Удалить.lnk" "$INSTDIR\uninstall.exe"
${RefreshShellIcons}
После установки ярлыки находятся в папке ${APPNAME}, через пару минут остаётся только один ярлык "$SMPROGRAMS\${APPNAME}.lnk"
Хотя в папке "C:\ProgramData\Microsoft\Windows\Start Menu\Programs" присутствует и папка ${APPNAME} и ярлыки ${APPNAME}.lnk и Удалить.lnk
В чём проблема?
AlekseyPopovv
24-09-2023, 17:55
UninstallIcon "${NSISDIR}\Contrib\Graphics\Icons\nsis3-uninstall.ico"
Как сделать что бы в панели управления была другая иконка?
После установки ярлыки находятся в папке ${APPNAME}, через пару минут остаётся только один ярлык "$SMPROGRAMS\${APPNAME}.lnk"
Хотя в папке "C:\ProgramData\Microsoft\Windows\Start Menu\Programs" присутствует и папка ${APPNAME} и ярлыки ${APPNAME}.lnk и Удалить.lnk
В чём проблема? »
Это норма для современных виндов - Why does my app’s uninstaller disappear from the Start menu? (https://devblogs.microsoft.com/oldnewthing/20190319-00/?p=102342) A customer reported that their installer creates a shortcut on the Start menu called Uninstall Contoso Deluxe, but a few seconds after their installer completes, the Uninstall Contoso Deluxe icon disappears from the Start menu. The main Contoso Deluxe shortcut is still there. What’s going on?
The uninstaller shortcut is removed from the Start menu to reduce clutter. You can uninstall apps from the Apps page in Settings, or from the Programs and Features control panel (formerly known as Add or Remove Programs). You can also get to the uninstaller by right-clicking Contoso Deluxe and selecting Uninstall.
Adding an uninstaller icon to Start menu is triply redundant, and it puts uninstallers in a high-traffic area of the user interface, when users are mostly looking for apps to run, not apps to uninstall.
The uninstaller shortcut is still there, so your uninstaller won’t get confused when it tries to delete the uninstaller shortcut. But the Start menu doesn’t show it.
Как сделать что бы в панели управления была другая иконка? »
Прописать её в uninstall-ключе реестра. Примеры есть в каталоге Examples (makensis.nsi, install-per-user.nsi, install-shared.nsi).
AlekseyPopovv
26-09-2023, 14:32
Как сделать как на первом скрине?
Browse for Folder (https://nsis.sourceforge.io/Browse_for_Folder)
Вид и поведение окна настраивается через флаги ulFlags структуры BROWSEINFOW (https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfow), передаваемой функции SHBrowseForFolderW (https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shbrowseforfolderw)
AlekseyPopovv
26-09-2023, 21:36
iglezz, Пример бы посмотреть, самый простой.
AlekseyPopovv
28-09-2023, 12:32
iglezz,
!include "StrFunc.nsh"
${StrRep}
${StrRep} $0 "$INSTDIR" "\" "/"
WriteRegStr HKCU "${APPREG}\OCR" "LanguagesPath" "@ByteArray($0/OCR)"
Как считать путь к папке OCR? Пользователь может выбрать любое расположение папки.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.