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

Kopejkin
27-11-2014, 20:12
И снова о "занятых" DLL...

В составе программы FolderSizes (foldersizes.com (http://www.foldersizes.com/index.htm)) есть файл FSShellExt.dll, с помощью которого в контекстное меню папок добавляются собственные команды программы.

http://savepic.su/4449039.png

Мне нужно пропатчить эту dll-ку или, в крайнем случае, заменить своей и, конечно же, без перезагрузки. Проблема в том, что dll-ка "занята" и не поддается изменению/удалению. Скопировать её можно.

Не очень понимая, что получаю, заметил такую закономерность.

Пока контекстное меню папки (любой) не вызывалось, файл остается "свободным", хоть до выключения компьютера.

http://savepic.su/4420367.png

Как только контекстное меню вызвано, файл "захватывает" Explorer.exe.

http://savepic.su/4414223.png

Просто так его уже не удалить.

http://savepic.su/4407055.png

Но файл FSShellExt.dll можно ЗАМЕНИТЬ вручную (из учетки администратора, Win 8.1), например, его же копией. Проводник сопротивляется, но все же дает выполнить эту операцию.

http://savepic.su/4398863.png

О чудо! Файл теперь можно патчить, удалять, перемещать, переименовывать и т.д. И опять же, до вызова контекстного меню папки.

Так как бы узнать, какая команда была выполнена, что Проводник разблокировал файл и можно ли это как-то использовать в сценарии NSIS? Насколько я понимаю, регистрация FSShellExt.dll не отменяется и сохраняется даже после его удаления. Контекстное меню начинает работать сразу же после копирования файла FSShellExt.dll на то же место (в папку программы) и вызова контекстного меню папки.

http://savepic.su/4436750.pngПредыдущие сообщения читал. Может появилось какое-то "бесперезагрузочное" решение.

MKN
28-11-2014, 10:09
Может появилось какое-то "бесперезагрузочное" решение. »
Дык разве предыдущее обсуждение - не решение ? Находим с помощью LockedList, что "заняло" DLL, закрываем найденное и работаем спокойно с DLL без перезагрузки.

Kopejkin
28-11-2014, 21:56
Находим с помощью LockedList... »
Наверное, я что-то не так делаю.
Подставляю имя dll-ки в пример LockedListShell32.nsi для проверки.

Name `LockedList Test`
OutFile LockedListTest.exe
RequestExecutionLevel user

!include MUI2.nsh
!include x64.nsh

!insertmacro MUI_PAGE_WELCOME
Page Custom LockedListShow
!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_LANGUAGE English

Function LockedListShow
!insertmacro MUI_HEADER_TEXT `LockedList Test` `Using AddModule and shell32.dll`
${If} ${RunningX64}
File /oname=$PLUGINSDIR\LockedList64.dll `${NSISDIR}\Plugins\x86-ansi\LockedList64.dll`
${EndIf}
LockedList::AddModule \FSShellExt.dll
;LockedList::AddModule "C:\Program Files\Key Metric Software\FolderSizes 7\FSShellExt.dll"
LockedList::Dialog
Pop $R0
FunctionEnd

Section
SectionEnd
В итоге нечего закрывать.
http://savepic.su/4437801.png

MKN
29-11-2014, 09:58
Наверное, я что-то не так делаю. »
всё так.
LockedList::AddModule "$PROGRAMFILES\Key Metric Software\FolderSizes 7\FSShellExt.dll"
LockedList::Dialog
Действительно, есть такой странный момент "не определения" для explorer_a. ( и это касается аналогичных библиотек не только для FolderSizes )
Если работать с TotalCommander_ом, то LockedList всё прекрасно отображает... Я с explorer_ом никогда не работаю, потому и не заметил... В чём дело, пока не известно... Надо бы задать этот вопрос автору плагина.
Если хочешь, попробуй спросить на http://forums.winamp.com/showthread.php?t=274168&page=8 Ты ведь английским хорошо владеешь ? :)
( Как вариант, можно попробовать предыдущие версии плагина, вдруг автор именно в этой последней версии чего то забыл... Так иногда бывает... :) )

ps С другой стороны - ведь прекрасно известно, что именно explorer.exe занимает FSShellExt.dll. Ну так и гаси его перед манипуляциями с DLL. Лучше с сообщением-предупреждением.

ps2 Потому и хотелось бы автономного кода NSIS, для этих целей (определение конкретных процессов, использующих конкретную указанную DLL (OCX или EXE ), с последующим закрытием этого(этих) процесса(ов) .
Может kotkovets поможет (хорошо бы добавить такую возможность в его замечательный ProcessFunс.nsh ) ? Вячеслав, помоги пожалуйста решить эту задачу.

Kopejkin
29-11-2014, 10:44
Ну так и гаси его.. »
Я пробовал пример из Справочника. Но на Win 8.1 он работает как-то странно. А может это винда странно работает после отработки скрипта. Смысл примера - убить explorer и сразу же его запустить. Проводник действительно работает, его операции можно выполнять, dll-ку можно изменять, НО..."теряется" Рабочий стол, и восстановить его отображение можно только перезагрузкой. У меня, по крайней мере, так. После применение Unlocker винду тоже немного колбасит, но не так критично - на секунду пропадает Рабочий стол и снова появляется. То есть не очень красиво.

MKN
29-11-2014, 11:37
Смысл примера - убить explorer и сразу же его запустить. »
Попробуй командно :
Taskkill /f /im explorer.exe
start explorer.exe
или плагин http://nsis.sourceforge.net/NsRestartExplorer_plug-in - работает оч быстро на XP, на Win8 - тормоз
У меня рестарт проводника в W8x32 происходит нормально - на секнду исчезают значки раб стола и затем восстанавливаются. Может как то и можно принудительно "заморозить" на время рестарта это не красивое исчезновение - не знаю...

Kopejkin
29-11-2014, 20:45
...в W8x32 происходит нормально »
У меня Windows 8.1x64.
Командно работает точно также. Оказывается explorer.exe убивается и запускается - его видно в диспетчере задач - но какой-то недоделанный. Чтобы стал виден Рабочий стол, Проводник нужно запустить из Диспетчера как новую задачу.
В общем, не знаю, как правильно пояснить.
Может маленькое видео (http://rghost.ru/private/59338107/e64118108b703e5e2ff7bb2c51334bce) поможет.

Vincent7
30-11-2014, 23:27
Здравствуйте господа форумчане. Спустя много времени я решил вернутся к своему старому проекту, а посему нужна ваша помощь. Как из окошка исполняемой консольной программы передать все что там выводится в функцию nsis? Логирование в реальном времени. Это нужно прежде всего, чтобы "поймать" нужное сообщение, и послать окошку нажатие enter как только оно(нужное сообщение) появится, ну и чтобы посылать весь лог в detailed окно nsis. Вы скажете "а почему бы тебе не использовать execdos plug-in для этих целей?" С ним- не получается почему-то.Использую execcmd.

Sann-X!
01-12-2014, 09:02
Нашел решение своей проблемы с плагинами. По умолчанию при вызове ф-ции из плагина dll-ка перед выполнением загружается в память, а после выполнения выгружается из памяти. И так каждый раз при вызове любой ф-ции dll. Поэтому данные в памяти не сохраняются между вызовами dll. Чтобы dll каждый раз не выгружалась, следовало использовать "/NOUNLOAD" или "SetPluginsUnload". Однако с версии 2.42 эти "штуки" считаются устаревшими и не рекомендуются для использования. Вот здесь в последнем сообщении (http://forums.winamp.com/showthread.php?t=318727) есть пример на Delphi, как создать dll, которая сохраняет память между вызовами ее ф-ций.

K.A.V.
01-12-2014, 17:59
Вы скажете "а почему бы тебе не использовать execdos plug-in для этих целей?" С ним- не получается почему-то »
Потому что вы, видимо, опять сами ничего не пробовали, если взять документацию к плагину и посмотреть примеры скриптов в архиве с плагином - почему-то получается, по-крайней мере у меня с этим плагином получилось всё сразу.

Использую execcmd. »
У ExecCmd нет такой возможности, как
из окошка исполняемой консольной программы передать все что там выводится в функцию nsis? Логирование в реальном времени »

а у ExecDos есть, для этого нужно использовать ключ /TOFUNC

Интересно, он прочитает документацию к плагину и посмотрит примеры, или как год назад начнёт насиловать мозг глупыми вопросами?

Vincent7
01-12-2014, 20:12
Читал. Пробовал. Не получается. Как скажите мне, отправлять что то окну если при использовании execdos это окно не создается? Я общался с создателем execdos и execcmd, и он мне посоветовал с моей задачей использовать execcmd. Вместо сарказма могли бы помочь..

K.A.V.
01-12-2014, 21:30
Читал. Пробовал. Не получается »
Покажите, как вы пробовали и что у вас не получается, год назад об этом уже говорилось (мы помогаем, а не делаем за вас, но с вами отдельный случай, всё делали за вас...). Мне просто интересно, как может не получиться то, что за вас уже написано (примеры в архиве плагина), вам остаётся только подставить свой путь к приложению.
Я вот сейчас опять же за вас взял, открыл пример скрипта их архива с плагином, подставил путь к консольному приложению и у меня всё считалось. Почему?

Как скажите мне, отправлять что то окну если при использовании execdos это окно не создается? »
И об этом я вам писал 10 страниц текста, и год назад мы уже выяснили, что вы сами походу понять не можете, что вам нужно в итоге, какой функционал. И пример отправки нажатия клавиши в консольное приложение год назад вам давали, между прочим.

Вы хотите, чтобы я сейчас опять за вас начал прочитывать сообщения годичной давности в этой теме и начал повторять их содержимое?

Вместо сарказма могли бы помочь.. »
Помочь, ключевое слово, а не сделать за вас.

Всё-таки придётся сделать за вас. Данный пример кода создаёт текстовый документ в папке с выходным файлом, в котором будет результат исполнения команды help.exe, которая находится в системной директории.




Name "Test"
OutFile "TOFUNC_TEST.exe"


Function LogFunction
Pop $2
FileWrite $R0 "$\r$\n$2"
FunctionEnd



Function .onInit

FileOpen $R0 "$EXEDIR\LOG.log" w
FileWrite $R0 "$\n"

StrCpy $1 0
GetFunctionAddress $0 LogFunction
ExecDos::exec /NOUNLOAD /TOFUNC /TIMEOUT=5000 "$SYSDIR\help.exe" "" $0
Pop $0
ExecDos::wait $0

FileClose $R0
MessageBox MB_OK|MB_ICONINFORMATION "Готово"
quit
FunctionEnd


Section
SectionEnd

Vincent7
02-12-2014, 15:31
K.A.V., Спасибо за код, но ведь я же писал что в первую очередь нужно отправить enter выполняемому приложению, а используя execdos этого не сделаешь. Разве я не прав?

K.A.V.
02-12-2014, 17:34
нужно отправить enter выполняемому приложению, а используя execdos этого не сделаешь »
А с помощью ExecCmd сделаешь? Причем здесь эти плагины и отправка сообщений окну?
Плагины ExecCmd и ExecDos используются для создания процесса с скрытым окном приложения. Всё. Это основной функционал.

С чего вы взяли вообще, что именно с помощью ExecCmd/ExecDos можно отправлять сообщения окну?
Ещё раз повторюсь, что пример отправки нажатия Enter в консольное приложение вам давали год назад, разве я не прав?

Со стороны это выглядит довольно глупо, начинать обсуждать год спустя то, что уже обсуждали. Вы память потеряли? Или просто опять лень теперь уже прочитать всё то, что уже написано год назад в этой теме?

Vincent7
03-12-2014, 01:11
K.A.V., с помощью execcmd да, можно. А с чего вы взяли что я с чего-то взял что можно отправлять именно с помощью плагинов? Можно и подругому. Хорошо, спрошу иначе- можно ли без использования плагинов отправлять лог из выполняемого консольного приложения в nsis функцию?

MKN
03-12-2014, 11:37
В общем, не знаю, как правильно пояснить.
Может маленькое видео поможет. »
Да, лажа на видео... Но у меня на восьмёрке вроде как всё нормально происходит. Если можно назвать нормальным, явную задержку при перерисовке стола...

Я пробовал разные утилитки, предназначенные специально для рестарта - всё в целом одно и то же - тормоза и визуально ужасно...

Например, : RestartExplorer ( Author Winaero )
Performs a graceful restart of the Explorer shell in Windows 10, 8, 7 and Vista. Explorer will save your preferences, i.e. icons order on Desktop and then restart.
http://winaero.com/download.php?view.1783

http://www.nirsoft.net/utils/restart_explorer.html

RightClick Restart Explorer http://www.thewindowsclub.com/right-click-restart-explorer-adds-restart-explorer-option-to-context-menu

Кстати, лучше всех отрабатывает батник, вообщем такой же что я уже тебе давал + организована пинг-задержка :

echo off
mode 72,3
title Explorer Restart - v1.3
if exist TEMP_FILE goto erro_1
echo Security to not open two Explorer Restart>TEMP_FILE
taskkill /F /IM explorer.exe >NUL
echo Explorer Closed, Starting...
ping 127.0.0.1 >NUL
start %systemroot%\explorer.exe
del TEMP_FILE
echo Explorer restarts, wait few seconds for this window closes.
ping 127.0.0.1 >NUL
exit
:erro_1
echo Already have an Explorer Restart In Progress.
ping 127.0.0.1 >NUL
exit

На винампе предложили такой код :

!include LogicLib.nsh
!include WinMessages.nsh

Name RestartExplorer
OutFile RestartExplorer.exe
RequestExecutionLevel user
ShowInstDetails show

!macro _IsWindow _a _b _t _f
IsWindow `${_b}` `${_t}` `${_f}`
!macroend
!define IsWindow `"" IsWindow`

!macro RestartExplorer
Push $R0
Push $R1
FindWindow $R0 Shell_TrayWnd
${If} ${IsWindow} $R0
IntOp $R1 ${WM_USER} + 436
System::Call `user32::PostMessage(i R0, i R1, i 0, i 0)`
${For} $R1 1 20
Sleep 1000
FindWindow $R0 Shell_TrayWnd
${IfNot} ${IsWindow} $R0
Exec `"$WINDIR\explorer.exe"`
${Break}
${EndIf}
${Next}
${EndIf}
Pop $R1
Pop $R0
!macroend

Section Main
!insertmacro RestartExplorer
SectionEnd

Только всё это - один хрен... Тормоза и визуально не красиво...

(Про не отображение эксплорера плагином, автор пока ничего не сказал...)

Почитав разную инфу про установку-удаление занятых DLL без перезагрузки компа или эксплорера, я пришёл к выводу, что идея эта - очень плохая... Отбирать у Винды, удерживаемый ей файл - всё равно , что отбирать у ребёнка конфету. Крику и слёз не оберёшься... :)
Лучше отложенного удаления "занятых" файлов, после ближайшей перезагрузки, ничего не придумано... А если и придумано, то держится в великом секрете... :)

(есть ещё экзотика с манипуляцией помещения файлов в память и чего то там ещё, но это для крутых программеров..)

Ну и ещё используется вариант - подмена исходных файлов на нужные, с переименованием исходных . Это дело известное и похоже, самое эффективное...

Также можно использовать сторонние утилитки типа inuse.exe или MoveFile
Inuse.exe предоставляет пользователям и администраторам возможность оперативно заменять файлы, которые в данный момент используются операционной системой.
http://download.microsoft.com/download/winntsrv40/Utility/1.3/NT4/EN-US/inuse.exe


Программы PendMoves (версия 1.2) и MoveFile (версия 1.01)
Автор: Марк Руссинович (Mark Russinovich)
http://technet.microsoft.com/ru-ru/sysinternals/bb897556.aspx

Kopejkin
03-12-2014, 17:19
MKN, большое спасибо за то, что провели исследование данной проблемы и поделились результатами. Ваши рекомендации попробую применить для своих целей.

MKN
04-12-2014, 11:05
можно ли без использования плагинов отправлять лог из выполняемого консольного приложения в nsis функцию? »
Вроде как давно известно - используй операторы перенаправления консольных команд в файл (назови, лог файл или как угодно), а потом обрабатывай этот файл скриптом NSIS...
Конечно возможны нюансы и частные случаи, но ты ведь до сих пор ничего конкретного не сказал (какое консольное приложение запускаешь, что именно из него хочешь обработать и т.д. )...
http://www.windowsfaq.ru/content/view/260/57/
http://www.itroad.ru/standartnye-potoki-vyvoda-stdout-windows-ili-kak-perenapravit-vyvod-konsoli-cmd-v-fajl
http://wiki.rosalab.ru/ru/index.php/Как_сохранить_в_файл_вывод_консоли

Vincent7
04-12-2014, 17:10
MKN , вообще-то называл год назад :) обработать надо все что в лог выводит приложение... большое спасибо за ссылки! Теперь пойду читать примеры по работе с текстом в nsis

Serg866
17-12-2014, 12:31
Ребят Можно ли как-то добавить свой текст на странице прогресса установки (под прогресс баром)?
Вывод деталей установки отключён - там пусто сейчас. Хочу кое каким текстом заполнить.




© OSzone.net 2001-2012