PDA

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


Страниц : 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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

kotkovets
19-01-2012, 01:19
SamLab, посмотрите в хедере x64.nsh - макросы ${DisableX64FSRedirection} и ${EnableX64FSRedirection}
переключение направления - ваш случай.
Paval, Смотрите макрос #1985 (http://forum.oszone.net/post-1810498-1985.html)

wolkow70
20-01-2012, 16:37
kotkovets,

Не подскажите как создать пустой ini-файл.
Пробую так :

Fileopen $1 "$INSTDIR\aida64.assetprofile.ini" w
FileClose $1

После компиляции выводится:
comment contains line-continuation character, following line will be ignored (D:\NSIS\Aida64BE.nsi:177)

kotkovets
20-01-2012, 18:26
Не подскажите как создать пустой ini-файл. »
Можно и так:
Writeinistr "$EXEDIR\assetprofile.ini" " " "" ""
После компиляции выводится:
comment contains line-continuation character, following line will be ignored (D:\NSIS\Aida64BE.nsi:177) »
так покажите 177 строку
---
у меня никаких проблем с созданием файла двумя способами

wolkow70
21-01-2012, 08:00
так покажите 177 строку »
В конструкции
Fileopen $1 "$INSTDIR\aida64.assetprofile.ini" w
FileClose $1

стр 177 это
FileClose $1

Впрочем, другой способ мне больше понравился.

romgun
21-01-2012, 12:38
если можно, мне тоже помогите, а?
http://forum.oszone.net/post-1838837-2217.html

kotkovets
21-01-2012, 14:03
romgun, Слишком сложно - загоните реализацию в тупик, упрощайте задачу.С логикой беда - если значение не найдено, из цикла выползти не могу »
${Break} - прерывание любого цикла.
Можно так, но есть проблема - подсказка, сделайте признак, значение переменной 0 или 1, для того, если
все нужные действия сделаны при SetShellVarContext all, не вызывать заново функцию cfg при SetShellVarContext current
!include "textfunc.nsh"
!include "logiclib.nsh"

var int

outfile file.exe

Section
SetShellVarContext all
Call cfg
;---
SetShellVarContext current
Call cfg
SectionEnd

Function Read
StrCpy $R0 $9 9
StrCmp $R0 "Dirpatch_" 0 +2
InTop $int $int + 1
Push $0
FunctionEnd

Function cfg
StrCpy $int 0
ClearErrors
${FileReadFromEnd} "$APPDATA\Microsoft\file.cfg" "Read"
${If} ${Errors}
Call xml ;если file.cfg - не найден!
${Else}
${If} $int != 0
${For} $0 1 $int
ReadIniStr $1 "$APPDATA\Microsof\file.cfg" "dir" "Dirpatch_$0"
MessageBox mb_ok "$0$\n$1"
${Next}
${ElseIf} $int == 0
Call xml ;если пути нужные не найдены, т.е $int = 0
${EndIf}
${EndIf}
FunctionEnd

Function xml
MessageBox MB_ICONINFORMATION|MB_OK "xml" IDOK
;команды для работы с xml файлами и проверки сушествования xml
FunctionEnd

Повторюсь еще раз, условно повторяющийся код переносится в функцию или в макрос - это очень удобно!
Важно знать, что Вы хотите - какой результат!
Поиск наиболее простого и эффективного решения - ключевые свойства любого проекта.
Про цикл For, с каждым циклом переменная $0 увеличивается на единицу, отсчет от единицы до значения $int,
какое Вам нужно значение - я не знаю...
Если Вам нужно последнее значение, то цикл не нужен, достаточно:
ReadIniStr $1 "$APPDATA\Microsof\file.cfg" "dir" "Dirpatch_$int"
В $int - количество совпадений заданного выражения, если выражение(обрезанная строка) совпадет в другой секции cfg файла,
делайте так, что бы нужные выражения были в нужной секции файла и больше нигде.
стр 177 это
FileClose $1 »
Скорее всего небольшие проблемы, до этой строки, наверно в команде FileWrite -
из-за неверного синтаксиса или неверного/закрытого значения дескриптора файла - второе значение синтаксиса команды FileWrite

denixx
21-01-2012, 21:54
kotkovets, видимо мне надо обращаться конкретно к тебе :)

Гугл выдаёт по запросу WinVer2 только одну из страниц этой темы...
Где взять собственно сам WinVer2.nsh?
Поможешь?

Мне нужно просто определить, является ли операционка x64, и если это так, то дальнейшие действия выполнять по нужной ветке.
Насколько я понял, этот хедер как раз это и позволяет узнать.
Конкретно: надо в зависимости от архитектуры просматривать, есть ли уже установленный Firefox на компе, у него кажется ключи в разных ветках находятся. А ещё надо ставить разные версии JVM.

kotkovets
21-01-2012, 22:18
Где взять собственно сам WinVer2.nsh? »
в шапке темы ссылка на справочник по NSIS - там он живет.
является ли операционка x64 »
есть для этого хедер - х64.nsh, в стандартной "коробке" NSIS

denixx
21-01-2012, 22:31
Спасибо, всё оказалось гораздо проще =)
Там прямо в самом x64.nsh есть пример с показом окошка.

Ну теперь осталось дело за малым - написать годные скрипты.
Вроде нужна только работа с реестром, да запуск .exe в нужных местах.
Плюс ещё работа с папкой TEMP виндовой, чтобы туда выгружать нужные файлы перед запуском.

wolkow70
24-01-2012, 10:11
kotkovets, доброго времени суток.

Можете, что-то посоветовать в таком случае?

Function .OnInit
StrCpy "$INSTDIR" "$PROGRAMFILES\AIMP3"
${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
${OrIf} ${FileExists} "$APPDATA\AIMP3\AIMP3.INI"
${OrIf} ${FileExists} "$INSTDIR\AIMP3\AIMP3.INI"
MessageBox MB_OKCANCEL|MB_USERICON|MB_TOPMOST "ВНИМАНИЕ!$\n\
$\nAIMP3 уже установлен, или на вашем компьютере есть настройки этого приложения. \
$\nДанный инсталлятор не может быть использован поверх установленного AIMP3. \
$\nПри нажатии кнопки 'Ok' будет произведено удаление следов предыдущей установки \
$\nи выполнена новая установка AIMP3. \
$\nПри нажатии кнопки 'Отмена' установка AIMP3 будет отменена. \
$\nВыполнить новую установку AIMP3?" /SD IDOK IDCANCEL cancel
;
Код удаления программы
;
ExecWait 'taskkill /F /IM explorer.exe' $0
DetailPrint "taskkill exit: [ $0 ]"
Sleep 500
StrCmp $0 0 0 +2
Exec "explorer.exe"
;
${If} ${RunningX64}
Delete "$INSTDIR\Modules\aimp_menu64.dll"
RMDir /r "$INSTDIR\Modules"
RMDir /r "$INSTDIR"
${Else}
Delete "$INSTDIR\Modules\aimp_menu32.dll"
RMDir /r "$INSTDIR\Modules"
RMDir /r "$INSTDIR"
${EndIf}
SetShellVarContext current
RMDir /r "$APPDATA\AIMP3"
Goto Done
cancel:
Abort
Done:
${EndIf}
FunctionEnd

В принципе работает, если AIMP3 установлен по дефолтному пути, а если нет?
Как можно вычислить директорию установки и локацию dll-файла для задания комманд удаления и дерегистрации?

И еще вопрос: Вы обещали сообщить, что выяснится с дерегистрацией aimp_menu64.dll?

kotkovets
24-01-2012, 14:22
В принципе работает, если AIMP3 установлен по дефолтному пути, а если нет? »
программа портабельная, настройки в реестре не хранит.
Если чешется можно искать файлы/настройки по всему компу...
Вопрос в том, сколько времени это займет... :)
Как можно вычислить директорию установки и локацию dll-файла для задания комманд удаления и дерегистрации? »
Сканируйте реестр при регистрации dll - вы найдете путь к dll, а из пути dll через
GetParent(смотрите справку) - папку программы
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}\InprocServer32]
@="C:\\AIMP3\\Modules\\aimp_menu32.dll"
И еще вопрос: Вы обещали сообщить, что выяснится с дерегистрацией aimp_menu64.dll? »
Пробуйте запускать исполняемый файл программы ключами:
AIMP3.exe /REG=MENU --> контекстное меню файлов (регистрация dll, независимо от системы)
AIMP3.exe /REG=R --> ассоциация файлов с AIMP3 (независимо от системы)
AIMP3.exe /REG=UALL --> разрегистрирует dll и уберет ассоциации файлов. (независимо от системы)
Вроде бы все просто и достаточно прозрачно.

wolkow70
24-01-2012, 14:22
Пока не придумал ничего другого, чем взять путь из CLSID

ReadRegStr $0 HKLM "SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}\InprocServer32" ""
StrCpy $DllPath $0
;
regdll "$DllPath" ContextMenuAddonUnregister
DeleteRegKey HKLM "SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}" ""
DeleteRegValue HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved" "{1F77B17B-F531-44DB-ACA4-76ABB5010A28}"

wolkow70
24-01-2012, 14:37
Искать путь к AIMP3.exe через DLL не надежно, программа может быть установлена и без регистрации контекста.

Paval
25-01-2012, 15:52
Ситуация такая. На компьютере у пользователя стоит программа. Я ставлю точно такую же, но другой версии. Нужно сравнить версии программы на компе и той, что я ставлю. Если у пользователя версия новее - просот обрубаем инсталятор, если новее моя - удаляем старую и ставим мою. С этим проблем нет. И с определением версии программы на комьютере проблем нет(просто посмотрим в реестре), а вот как узнать версию инсталируемого продукта (чтобы провести сравнение)?
P.S. В скрипт версию хардкодить нельзя.

MKN
25-01-2012, 16:40
Paval,
Возможно так :

!include "FileFunc.nsh"

Section
ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\App1" "DisplayVersion"
MessageBox MB_OK "Версия установленной программы $R0"

${GetFileVersion} "App2.exe" $R1
MessageBox MB_OK "Версия устанавливаемой программы $R1"

;затем сравниваем значения переменных (здесь тоже могут быть варианты, в зависимости от нумерации и пр.) , и т.д.
SectionEnd

App2.exe может находиться рядом с скриптом.
(Если же инсталлятор устанавливаемой программы, бестолковый, т.е. версия не указана, то придётся предварительно распаковать эту прогу в Temp и фиксировать версию исполняемого файла или ещё какого-нибудь с признаком версии...)

Paval
25-01-2012, 17:06
Paval,
Возможно так :
Код:
!include "FileFunc.nsh"
Section
ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\App1" "DisplayVersion"
MessageBox MB_OK "Версия установленной программы $R0"
${GetFileVersion} "App2.exe" $R1
MessageBox MB_OK "Версия устанавливаемой программы $R1"
;затем сравниваем значения переменных (здесь тоже могут быть варианты, в зависимости от нумерации и пр.) , и т.д.
SectionEnd
App2.exe может находиться рядом с скриптом. »
Интересно, а откуда на компьютере у пользователя появиться файл App2.exe ?

P.S. Мне рекомендовали передавать версию через параметры. (я так понимаю командной стороки). Только хз как их задать.

MKN
25-01-2012, 17:11
Интересно, а откуда на компьютере у пользователя появиться файл App2.exe ? »
Ты не внятно ставишь задачу. Понимать можно всяко :
На компьютере у пользователя стоит программа. Я ставлю точно такую же, но другой версии. »
Расшифруй, где и что ты ставишь.

wolkow70
25-01-2012, 17:18
AIMP3.exe /REG=MENU --> контекстное меню файлов (регистрация dll, независимо от системы)
AIMP3.exe /REG=R --> ассоциация файлов с AIMP3 (независимо от системы)
AIMP3.exe /REG=UALL --> разрегистрирует dll и уберет ассоциации файлов. (независимо от системы)
Вроде бы все просто и достаточно прозрачно. »
Мы же не ищем легких путей :).
Сделал так:

Function .OnInit
;
StrCpy $SysDrive $WINDIR 2
;
${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
${OrIf} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.INI"
${OrIf} ${FileExists} "$PROGRAMFILES\AIMP3\profile\AIMP3.INI"
${OrIf} ${FileExists} "$PROGRAMFILES\AIMP3\profile\AIMP3_MENU.INI"
${OrIf} ${FileExists} "$PROGRAMFILES\AIMP3\Modules\aimp_menu32.dll"
${OrIf} ${FileExists} "$PROGRAMFILES\AIMP3\Modules\aimp_menu64.dll"
;
${OrIf} ${FileExists} "$SysDrive\AIMP3\AIMP3.exe"
${OrIf} ${FileExists} "$SysDrive\AIMP3\AIMP3.INI"
${OrIf} ${FileExists} "$SysDrive\AIMP3\profile\AIMP3.INI"
${OrIf} ${FileExists} "$SysDrive\AIMP3\profile\AIMP3_MENU.INI"
${OrIf} ${FileExists} "$SysDrive\AIMP3\Modules\aimp_menu32.dll"
${OrIf} ${FileExists} "$SysDrive\AIMP3\Modules\aimp_menu64.dll"
;
${OrIf} ${FileExists} "$APPDATA\AIMP3\AIMP3.INI"
${OrIf} ${FileExists} "$APPDATA\AIMP3\AIMP3_MENU.INI"
${OrIf} ${FileExists} "$INSTDIR\AIMP3.INI"
${OrIf} ${FileExists} "$INSTDIR\profile\AIMP3.INI"
${OrIf} ${FileExists} "$INSTDIR\AIMP3\AIMP3.INI"
;
MessageBox MB_OKCANCEL|MB_USERICON|MB_TOPMOST "ВНИМАНИЕ!$\n\
$\nAIMP3 уже установлен, или на вашем компьютере есть настройки этого приложения. \
$\nДанный инсталлятор не может быть использован поверх уже установленного AIMP3. \
$\nПри нажатии кнопки 'Ok' будет произведено полное удаление предыдущей установки \
$\nи выполнена новая установка AIMP3. \
$\nПри нажатии кнопки 'Отмена' установка AIMP3 будет отменена. \
$\nВыполнить новую установку AIMP3 ?" /SD IDOK IDCANCEL cancel
;
${If} ${RunningX64}
${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
${AndIf} ${FileExists} "$PROGRAMFILES\AIMP3\Modules\aimp_menu64.dll"
ExecWait "$\"$PROGRAMFILES\AIMP3\AIMP3.exe$\" /REG=UALL"
StrCpy $R1 "$PROGRAMFILES\AIMP3\Modules\aimp_menu64.dll"
${Else}
ReadRegStr $1 HKLM "SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}\InprocServer32" ""
StrCpy $R1 $1
regdll "$R1" ContextMenuAddonUnregister
${EndIf}
${Else}
${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
${AndIf} ${FileExists} "$PROGRAMFILES\AIMP3\Modules\aimp_menu32.dll"
ExecWait "$\"$PROGRAMFILES\AIMP3\AIMP3.exe$\" /REG=UALL"
StrCpy $R1 "$PROGRAMFILES\AIMP3\Modules\aimp_menu32.dll"
${Else}
ReadRegStr $1 HKLM "SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}\InprocServer32" ""
StrCpy $R1 $1
regdll "$R1" ContextMenuAddonUnregister
${EndIf}
${EndIf}
;
DeleteRegKey HKLM "SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}" ""
DeleteRegValue HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved" "{1F77B17B-F531-44DB-ACA4-76ABB5010A28}"
;
ExecWait 'taskkill /F /IM explorer.exe' $0
DetailPrint "taskkill exit: [ $0 ]"
Sleep 500
StrCmp $0 0 0 +2
Exec "explorer.exe"
;
Delete "$R1"
;
${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
RMDir /r "$PROGRAMFILES\AIMP3"
${Else}
${GetParent} "$R1" $2
StrCpy "$R2" $2
${GetParent} "$R2" $3
StrCpy "$R3" $3
RMDir /r "$R3"
${EndIf}
;
ReadRegStr $4 HKLM "SOFTWARE\Classes\CLSID\{0041494D-5033-4472-6F70-546172676574}\LocalServer32" ""
StrCpy "$R4" $4
${GetParent} "$R4" $5
StrCpy "$R5" $5
RMDir /r "$R5"
;
ReadRegStr $6 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AIMP3.exe" ""
StrCpy "$R6" $6
${GetParent} "$R6" $7
StrCpy "$R7" $7
RMDir /r "$R7"
;
-прочие комманды удаления
;
SetShellVarContext current
RMDir /r "$APPDATA\AIMP3"
${EndIf}
FunctionEnd

kotkovets
25-01-2012, 17:34
Нужно сравнить версии программы на компе и той, что я ставлю. Если у пользователя версия новее - просот обрубаем инсталятор, если новее моя - удаляем старую и ставим мою »
Сначала нужно получить версию программы, откуда получить?
1. Из реестра, текстового файла...
2. Из исполняемого файла программы, макросом GetFileVersion (FileFunc.nsh)
3. Затем сравниваем полученную версию программы и исходно устанавливаемую.
!include "WordFunc.nsh"
!define version "1.1.3" ;исходно устанавлимая версия
;--
Section
;команды получения установленной версии
;к примеру мы получили версию в $1
StrCpy $1 "1.1.0"
${VersionCompare} "$1" "${version}" $0
${If} $0 == 0
MessageBox MB_OK "версии равны"
${ElseIf} $0 == 1
MessageBox MB_OK "исходная версия, меньше полученной"
${ElseIf} $0 == 2
MessageBox MB_OK "исходная версия, больше полученной"
${EndIf}
SectionEnd
P.S. В скрипт версию хардкодить нельзя. »
здесь обсуждаются только скрипты NSIS, я правильно понял или мне телепатом становится :)
1. У вас есть некий установщик проги, назовем его Х, а скрипта нет.
2. Вы хотите написать скрипт, который заводит/отменяет установку X в зависимости от ваших условий.
Мы же не ищем легких путей »
Зачем делать то, что можно делать ключами проги: легко и просто....смысла нет огород 0городить :)
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}\InprocServer32]
@="C:\\AIMP3\\Modules\\aimp_menu32.dll" »
при первом GetParent будет --> C:\AIMP3\Modules
при втором GetParent будет --> C:\AIMP3 , и затем нужно удалить папку проги
ReadRegStr $4 HKLM "SOFTWARE\Classes\CLSID\{0041494D-5033-4472-6F70-546172676574}\LocalServer32" ""
${GetParent} "$4" "$4"
${GetParent} "$4" "$4"
RMDir /r "$4"
;--
StrCpy $4 "C:\AIMP3\Modules\aimp_menu32.dll"
${GetParent} "$4" "$4"
MessageBox MB_OK "$4" IDOK
${GetParent} "$4" "$4"
MessageBox MB_OK "$4" IDOK

wolkow70
26-01-2012, 05:59
при первом GetParent будет --> C:\AIMP3\Modules
при втором GetParent будет --> C:\AIMP3 , и затем нужно удалить папку проги »
У меня так и сделано, только с большим количеством переменных:

ReadRegStr $1 HKLM "SOFTWARE\Classes\CLSID\{1F77B17B-F531-44DB-ACA4-76ABB5010A28}\InprocServer32" ""
StrCpy $R1 $1
regdll "$R1" ContextMenuAddonUnregister


${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
RMDir /r "$PROGRAMFILES\AIMP3"
${Else}
${GetParent} "$R1" $2
StrCpy "$R2" $2
${GetParent} "$R2" $3
StrCpy "$R3" $3
RMDir /r "$R3"
${EndIf}

Зачем делать то, что можно делать ключами проги: легко и просто....смысла нет огород 0городить »
Для практики. И не доверяю я этим ключам. Кто его знает, что там написано.
Кстати, у меня применяется ключ, если программа установлена в директорию по умолчанию.
${If} ${FileExists} "$PROGRAMFILES\AIMP3\AIMP3.exe"
${AndIf} ${FileExists} "$PROGRAMFILES\AIMP3\Modules\aimp_menu32.dll"
ExecWait "$\"$PROGRAMFILES\AIMP3\AIMP3.exe$\" /REG=UALL"




© OSzone.net 2001-2012