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

MKN
09-04-2015, 15:04
FileVersionInfo Header v1.2.2

/*

---------------------------------------------
FileVersionInfo Header v1.2.2

All Functions comes from:
http://nsis.pastebin.com/f5e461c4d
Written by Anders
Collected and modified by JiaKe
---------------------------------------------

Copyright 2011 Nullsoft Install System

Usage in script:

!include "FileVerInfo.nsh"

[Section|Function]

${FileVerInfoFunc} FILEPATH $var

# $var=["error"|""|Result]
# "error": This version info doesn't exist
# "": This version info exsits but is blank
# Result: The value of this version info

[SectionEnd|FunctionEnd]

FileVerInfoFunc can be:
[un.]GetFileVersion
[un.]GetProductVersion
[un.]GetProductName
[un.]GetCompanyName
[un.]GetFileDescription
[un.]GetComments
[un.]GetLegalCopyright
[un.]GetLegalTrademarks
[un.]GetInternalName
[un.]GetOriginalFilename
[un.]GetSpecialBuild
[un.]GetPrivateBuild
[un.]GetUserDefined <Userdefined Name>

---------------------------------------------

Examples:
${GetCompanyName} $WINDIR\Notepad.exe $R0
${un.GetComments} $SYSDIR\registry.exe $R0

---------------------------------------------

*/

!ifndef FILEVERINFO_INCLUDED
!define FILEVERINFO_INCLUDED

!include Util.nsh
!include LogicLib.nsh

!verbose push
!verbose 3
!ifndef _FILEVERINFO_VERBOSE
!define _FILEVERINFO_VERBOSE 3
!endif
!verbose ${_FILEVERINFO_VERBOSE}
!define FILEVERINFO_VERBOSE `!insertmacro FILEVERINFO_VERBOSE`
!verbose pop

!macro FILEVERINFO_VERBOSE _VERBOSE
!verbose push
!verbose 3
!undef _FILEVERINFO_VERBOSE
!define _FILEVERINFO_VERBOSE ${_VERBOSE}
!verbose pop
!macroend

!macro GetFileVerInfoCall _VERINFO_STR_NAME _FILENAME_INPUT _VERINFO_OUTPUT
!verbose push
!verbose ${_FILEVERINFO_VERBOSE}
Push `${_FILENAME_INPUT}`
Push `${_VERINFO_STR_NAME}`
${CallArtificialFunction} GetFileVerInfo_
Pop `${_VERINFO_OUTPUT}`
!verbose pop
!macroend

!macro __DefineVersionInfoName _VERINFO_STR_NAME
!define Get${_VERINFO_STR_NAME} `!insertmacro GetFileVerInfoCall ${_VERINFO_STR_NAME}`
!define un.Get${_VERINFO_STR_NAME} `!insertmacro GetFileVerInfoCall ${_VERINFO_STR_NAME}`
!macroend

!insertmacro __DefineVersionInfoName ProductName
!insertmacro __DefineVersionInfoName Comments
!insertmacro __DefineVersionInfoName CompanyName
!insertmacro __DefineVersionInfoName LegalCopyright
!insertmacro __DefineVersionInfoName FileDescription
!insertmacro __DefineVersionInfoName FileVersion
!insertmacro __DefineVersionInfoName ProductVersion
!insertmacro __DefineVersionInfoName InternalName
!insertmacro __DefineVersionInfoName LegalTrademarks
!insertmacro __DefineVersionInfoName OriginalFilename
!insertmacro __DefineVersionInfoName PrivateBuild
!insertmacro __DefineVersionInfoName SpecialBuild

!define GetUserDefined `!insertmacro GetFileVerInfoCall`
!define un.GetUserDefined `!insertmacro GetFileVerInfoCall`

!macro GetFileVerInfo_

!verbose push
!verbose ${_FILEVERINFO_VERBOSE}

Exch $R0
Exch
Exch $R1
System::Store S
System::Call `version::GetFileVersionInfoSize(tR1,*i)i.R2`
IntCmpU $R2 0 +15
System::Alloc $R2
System::Call `version::GetFileVersionInfo(tR1,in,iR2,isR3)i.R4?e`
Pop $R2
IntCmpU $R2 0 0 +11 +11
IntCmpU $R4 0 +10
System::Call `version::VerQueryValue(iR3,t"\VarFileInfo\Translation",*i.R4,*i)i.R5`
IntCmpU $R5 0 +8
System::Call `*$R4(&i2.R6,&i2.R7)`
IntFmt $R6 "%04x" $R6
IntFmt $R7 "%04x" $R7
System::Call `version::VerQueryValue(iR3,t"\StringFileInfo\$R6$R7\$R0",*i.R6,*i.R7)i.R8`
IntCmpU $R8 0 +3
System::Call `*$R6(&t$R7.s)`
Goto +2
Push `error`
IntCmpU $R3 0 +2
System::Free $R3
System::Store L
Exch 2
Exch
Pop $R1
Pop $R0
!verbose pop
!macroend
!endif



На базе этого кода, похоже сделан MoreInfo plugin http://nsis.sourceforge.net/MoreInfo_plug-in

Но и у FileVerInfo.nsh , и у MoreInfo plugin есть такая лажа - инфа из некоторых файлов получается только в виде первого символа...
Например, так происходит при снятии инфы у файла vcredist_x86.exe (MicrosoftVisual C ++ 2012 Redistributable)
https://www.microsoft.com/ru-ru/download/details.aspx?id=30679

http://s017.radikal.ru/i404/1504/c9/175bb2564e80.jpg

Плагин и хедер, вроде как оч полезные, но и в то же время для некоторых случаев, бесполезные...
Как бы это исправить (исходники есть http://www.fdos.org/win32/nsis/plugins/others/MoreInfo.1.0.1.2.zip ) ?

Или хотя бы сделать внятным код для функции GetFileVersionInfo (и сопутствующих функций - см. код FileVersionInfo Header), чтобы определять параметры свойств файлов...

ps http://dictionary.cambridge.org/ru/pronunciation/британский/header

K.A.V.
09-04-2015, 15:36
MKN, закомментируй в хидере строку
!insertmacro __DefineVersionInfoName FileVersion
ругается из-за того, что макрос GetFileVersion уже есть

Или хотя бы сделать внятным код для функции GetFileVersionInfo (и сопутствующих функций - см. код FileVersionInfo Header), чтобы определять параметры свойств файлов... »
Ну так, посмотреть в хидере, что доступно и прописать как команды, не?

${GetProductName} "$WINDIR\explorer.exe" $0
${GetComments} "$WINDIR\explorer.exe" $1
${GetCompanyName} "$WINDIR\explorer.exe" $2
${GetLegalCopyright} "$WINDIR\explorer.exe" $3
${GetFileDescription} "$WINDIR\explorer.exe" $4
${GetProductVersion} "$WINDIR\explorer.exe" $5
${GetInternalName} "$WINDIR\explorer.exe" $6
${GetLegalTrademarks} "$WINDIR\explorer.exe" $7
${GetOriginalFilename} "$WINDIR\explorer.exe" $8
${GetPrivateBuild} "$WINDIR\explorer.exe" $9
${GetSpecialBuild} "$WINDIR\explorer.exe" $R0

насчет остального, правки исходников и разных глюков - это точно не ко мне, мне достаточно того, как я намучался при написании dll расширения оболочки для встраивания в контекстное меню файлов пункт для SFX Creator, C++ это не моё...

MKN
09-04-2015, 15:41
Кстати и штатный ${GetFileVersion} - показывает только первый символ... Как определять версию файла vcredist_x86.exe... ? Ещё мне надо определять версии шрифтов... Существующие плагины тоже не помощники. Кое что, да кое когда определяют, а что надо - нет... :)
NSIS ни черта не умеет, за что не возьмись... Начинаю в нём разочаровываться... :) Разрабы этот продукт сделали для неискушенных в программировании пользователей, вроде как старались , а поддержать и расширять не хотят...
ругается из-за того, что макрос GetFileVersion уже есть »
Это понятно из сообщения. Что делать то ?

K.A.V.
09-04-2015, 16:10
Это понятно из сообщения. Что делать то ? »
Я же тебе выше ответил, закомментируй указанную строку, монитор запачкался что ли? :)

Кстати и штатный ${GetFileVersion} - показывает только первый символ... Как определять версию файла vcredist_x86.exe... ? »
Ну, видимо, файл особенный, я без понятия, в чем проблема, не на всех же файлах отрабатывает без ошибок...

NSIS ни черта не умеет, за что не возьмись... Начинаю в нём разочаровываться... »
Немножко умеет, раз его использовала не одна известная компания для создания инсталлеров для своих продуктов

вроде как старались , а поддержать и расширять не хотят... »
Эта проблема всех FreeWare проектов, мне кажется, всё держится на энтузиазме создателей и у всех этот энтузиазм со временем проходит, не у всех есть желание вечно сидеть с красными глазами и пилить софт "для народа"

MKN
09-04-2015, 16:19
закомментируй указанную строку »
Первым делом закомментил. Всё равно ошибки...
ps Интересно, а нет ли где конвертера из VBScript в NSIS ? :)

K.A.V.
09-04-2015, 16:26
Первым делом закомментил. Всё равно ошибки... »
У меня нет ошибок и компилируется без проблем, если в коде только 2 указанных тобой инклуда, смотри, где у тебя ещё проблемы и на какие строки ругается...

MKN
09-04-2015, 16:37
K.A.V.,
у меня такие ошибки :
Error in macro __DefineVersionInfoName on macroline 1
!include: error in script: "FileVerInfo.nsh" on line 97
97 строку комментирую. а что имеется ввиду под macroline 1 ?

K.A.V.
09-04-2015, 17:00
а что имеется ввиду под macroline 1 ? »
Ошибка в первой строке в самом макросе
Например, если будет такой код макроса с "левым" текстом в первой строке:


!macro __DefineVersionInfoName _VERINFO_STR_NAME
мой текст
!define Get${_VERINFO_STR_NAME} `!insertmacro GetFileVerInfoCall ${_VERINFO_STR_NAME}`
!define un.Get${_VERINFO_STR_NAME} `!insertmacro GetFileVerInfoCall ${_VERINFO_STR_NAME}`
!macroend

MKN
09-04-2015, 17:06
Например, если будет такой код макроса с "левым" текстом в первой строке: »
Нет там никакого левого текста. Хедер один в один , который я здесь привёл... Хоть комментируй в нём чего, хоть нет - не работает (если вместе с !include "FileFunc.nsh" )...

выложи пожалуйста твой рабочий комплект, а то я уже не знаю на что и думать. Может у меня в самом NSIS "комплекте" чего то не так...

K.A.V.
09-04-2015, 17:54
Нет там никакого левого текста. Хедер один в один , который я здесь привёл... Хоть комментируй в нём чего, хоть нет - не работает (если вместе с !include "FileFunc.nsh" )... »
Ну не знаю, в чем там у тебя проблема, пробовал пустой код компилить только с этими инклудами?
У меня на NSIS 3.0b1 всё нормально компилится и работает

MKN
09-04-2015, 18:02
K.A.V.,
И с твоим комплектом те же ошибки... Писец какой то...
PS нашёл причину... если FileVerInfo.nsh лежит в одном каталоге со скриптом - ошибка. стОит его убрать - всё ОК...

ya158
09-04-2015, 23:55
Прошу помощи.
В скрипте для конструктора (http://forum.oszone.net/post-2344304-1676.html) AkelPad я использую для запуска утилит команду вида:
ExecWait 'hidcon.exe takeown.exe /F "$R8"'
Я решил не применять hidcon.exe для скрытия консольных окон, а использовать nsExec::Exec. На Win 8.1 инсталлятор после замены стал вылетать с ошибкой. Исследуя логи определил, что прекращение работы инсталлятора происходит при обработке следующего куска скрипта:
loop:
${Locate} "$WINDIR\WINSxS\" "/L=F /M=notepad.exe" "WINSxS"
IfErrors loop 0
.
.
Function WINSxS
System::Call "advapi32::GetUserName(t .r0, *i ${NSIS_MAX_STRLEN} r1) i.r2"
nsExec::Exec 'takeown.exe /F "$R9"'
nsExec::Exec 'icacls.exe "$R9" /grant $0:F'
nsExec::Exec 'takeown.exe /F "$R8"'
nsExec::Exec 'icacls.exe "$R8" /grant $0:F'

${GetSize} "$WINDIR\" "/M=notepad.exe /S=0K /G=0" $R0 $R2 $R3
${GetSize} "$R8" "/M=notepad.exe /S=0K /G=0" $R1 $R2 $R3
${If} $R0 == $R1
StrCpy $Path2 '$Path2,$R8'
${Else}
StrCpy $Path3 '$R8'
${EndIf}
Push $0
FunctionEnd
Вылет происходит после команды Push $0. Если вместо nsExec::Exec использовать команду ExecWait 'hidcon.exe .....' , то всё нормально.
В чем может быть проблема

K.A.V.
10-04-2015, 05:42
PS нашёл причину... если FileVerInfo.nsh лежит в одном каталоге со скриптом - ошибка. стОит его убрать - всё ОК... »
Что-то у тебя там в сборке NSIS нахимичино, у меня инклуд в одной папке со скриптом и никаких проблем.

Если вместо nsExec::Exec использовать команду ExecWait 'hidcon.exe .....' , то всё нормально.
В чем может быть проблема »
Вы используете плагин, который передаёт значения в NSIS инсталлятор, поэтому рекомендуется принимать значения из плагина командой Pop, а не оставлять это "как хочется"

System::Call "advapi32::GetUserName(t .R4, *i ${NSIS_MAX_STRLEN} r1) i.r2"
${GetSize} "$WINDIR\" "/M=notepad.exe /S=0K /G=0" $R0 $R2 $R3

loop:
${Locate} "$WINDIR\WINSxS\" "/L=F /M=notepad.exe" "WINSxS"
IfErrors loop 0

Function WINSxS
nsExec::Exec 'takeown.exe /F "$R9"'
pop $R1
nsExec::Exec 'icacls.exe "$R9" /grant $R4:F'
pop $R1
nsExec::Exec 'takeown.exe /F "$R8"'
pop $R1
nsExec::Exec 'icacls.exe "$R8" /grant $R4:F'
pop $R1

${GetSize} "$R8" "/M=notepad.exe /S=0K /G=0" $R1 $R2 $R3
${If} $R0 == $R1
StrCpy $Path2 '$Path2,$R8'
${Else}
StrCpy $Path3 '$R8'
${EndIf}
Push $0
FunctionEnd
И старайтесь писать менее грязный код, не делайте так, как у вас написано - не закидывайте лишних команд в callback функции как в Locate, на этом коде не будет заметно, но если производить поиск всех файлов, то при каждом найденном файле у вас будут отрабатывать 2 команды, которые в этом месте кода не нужны, это я говорю про команду получения информации о файле $WINDIR\notepad.exe и о вашей команде постоянного получения имени пользователя...

MKN
10-04-2015, 10:59
Что-то у тебя там в сборке NSIS нахимичино »
Переустановил NSIS на всяк случай... Почему инклуд мешал, так и не понял, но так ведь было...
С FileVerInfo.nsh с определением версии файла всё нормально (но только с номером версии, всё остальное черт те что ! )
http://s010.radikal.ru/i311/1504/79/b84e782fa876.jpg

А MoreInfo plugin, с тем же файлом, по прежнему показывает только первый символ версии...

ya158
10-04-2015, 11:46
K.A.V.,
Большое спасибо. По поводу грязного кода - полностью согласен, недоглядел. Буду оптимизировать. С nsis сталкиваюсь очень мало. Не могли бы Вы пояснить поподробнее следующее:
Вы используете плагин, который передаёт значения в NSIS инсталлятор, поэтому рекомендуется принимать значения из плагина командой Pop, а не оставлять это "как хочется" »

K.A.V.
10-04-2015, 12:47
С FileVerInfo.nsh с определением версии файла всё нормально (но только с номером версии, всё остальное черт те что ! ) »
У меня точно так же, не знаю, в чем там проблема, хотя сама винда показывает описания корректно, видимо, где-то есть очередной подводный камень от Microsoft в использовании api функции по получения информации из файла.

Не могли бы Вы пояснить поподробнее следующее: »
А что ещё пояснять? :o
Вы читали описание плагина, который используете?
Если на примере, то представьте, что вы вышли в сад собирать яблоки с другом, ваш товарищ кидает вам сорванные яблоки, надеясь, что вы поймаете, а вы думаете "не хочу ловить, пусть на земле полежат" и все яблоки, которые кидает вам друг - падают на землю. Вот и тут так же, плагин вам данные передаёт - вы их не принимаете.
Вообще, это спорный момент в NSIS (в NSIS вообще много разных "фишек" и багов), не всегда вы будете получать краш, если не будете принимать значения от плагинов, от чего это зависит - не могу сказать, т.к. прямо с программированием я не связан, возможно, получается какая-то каша со стеком из-за этого или ещё чего...Нужно всегда тестировать то, что пишите, особенно при использовании плагинов.
Что касается "фишек" NSIS, то об одной я тут писал недавно, когда при использовании команды ReadINIStr (чтение значения параметра из INI файла) в callback функции Locate - функция просто завершается, не продолжая поиск файлов.

ya158
10-04-2015, 17:58
Вот и тут так же, плагин вам данные передаёт - вы их не принимаете. »
Видимо я не разобрался с работой плагина. Я думал, что задача плагина - запускать приложения. А на выходе - результат работы приложения. И, если мне не надо знать этот результат, то я его не использую. То есть, на вашем примере, задача - освободить дерево от яблок, а куда потом денутся яблоки - будут ли собраны в мешок или останутся лежать на земле - не важно.
Правильно ли я понял, что результат своей работы плагин помещает в стек и надо его оттуда "вынуть", чтобы не вызывать переполнения? Значит ли это, что после каждого вызова плагина требуется команда типа "pop $R1"?

K.A.V.
10-04-2015, 18:47
Я думал, что задача плагина - запускать приложения »
Так и есть, плагин справляется со своими обязанностями

А на выходе - результат работы приложения »
Так и есть, только в переменную, содержащую "результат" может быть помещен разный результат, о возвращаемых значениях написано в файле ReadMe к плагину:
Return Value
------------
If nsExec is unable to execute the process, it will return "error"
on the top of the stack, if the process timed out it will return
"timeout", else it will return the return code from the
executed process.

И, если мне не надо знать этот результат, то я его не использую »
Ну, как вы увидели в своём же примере кода - иногда всё-таки необходимо принимать возвращаемые плагином значения

Правильно ли я понял, что результат своей работы плагин помещает в стек »
В цитате выше всё сказано, ReadMe к плагинам читайте

Значит ли это, что после каждого вызова плагина требуется команда типа "pop $R1"? »
Опять же, смотря какой плагин и как он написан, не все плагины пишутся так, что они возвращают значения.
Конкретно насчет плагина nsExec вы уже сами увидели, если не принимать значения после исполнения команды - получите краш

Salmo
21-04-2015, 15:28
Уважаемые. Как через NSIS определить включен ли Тестовый режим ОС (testsigning) любой разрядности. Я делал через cmd\bcdedit - очень громоздко...

MKN
21-04-2015, 16:51
делал через cmd\bcdedit - очень громоздко... »
Чего же тут громоздкого... Известен такой вариант :

; enable test signing
nsExec::Exec '$SYSDIR\bcdedit.exe /set testsigning on'
Pop $R0
${If} $R0 != 0
Abort "Failed to enable test signing: $R0"
${EndIf}

; bcdedit requires a reboot
SetRebootFlag true




© OSzone.net 2001-2012