Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
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Предыдущие сообщения читал. Может появилось какое-то "бесперезагрузочное" решение.
Может появилось какое-то "бесперезагрузочное" решение. »
Дык разве предыдущее обсуждение - не решение ? Находим с помощью 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
Наверное, я что-то не так делаю. »
всё так.
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 винду тоже немного колбасит, но не так критично - на секунду пропадает Рабочий стол и снова появляется. То есть не очень красиво.
Смысл примера - убить 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.
Нашел решение своей проблемы с плагинами. По умолчанию при вызове ф-ции из плагина dll-ка перед выполнением загружается в память, а после выполнения выгружается из памяти. И так каждый раз при вызове любой ф-ции dll. Поэтому данные в памяти не сохраняются между вызовами dll. Чтобы dll каждый раз не выгружалась, следовало использовать "/NOUNLOAD" или "SetPluginsUnload". Однако с версии 2.42 эти "штуки" считаются устаревшими и не рекомендуются для использования. Вот здесь в последнем сообщении (http://forums.winamp.com/showthread.php?t=318727) есть пример на Delphi, как создать dll, которая сохраняет память между вызовами ее ф-ций.
Вы скажете "а почему бы тебе не использовать execdos plug-in для этих целей?" С ним- не получается почему-то »
Потому что вы, видимо, опять сами ничего не пробовали, если взять документацию к плагину и посмотреть примеры скриптов в архиве с плагином - почему-то получается, по-крайней мере у меня с этим плагином получилось всё сразу.
Использую execcmd. »
У ExecCmd нет такой возможности, как
из окошка исполняемой консольной программы передать все что там выводится в функцию nsis? Логирование в реальном времени »
а у ExecDos есть, для этого нужно использовать ключ /TOFUNC
Интересно, он прочитает документацию к плагину и посмотрит примеры, или как год назад начнёт насиловать мозг глупыми вопросами?
Vincent7
01-12-2014, 20:12
Читал. Пробовал. Не получается. Как скажите мне, отправлять что то окну если при использовании execdos это окно не создается? Я общался с создателем execdos и execcmd, и он мне посоветовал с моей задачей использовать execcmd. Вместо сарказма могли бы помочь..
Читал. Пробовал. Не получается »
Покажите, как вы пробовали и что у вас не получается, год назад об этом уже говорилось (мы помогаем, а не делаем за вас, но с вами отдельный случай, всё делали за вас...). Мне просто интересно, как может не получиться то, что за вас уже написано (примеры в архиве плагина), вам остаётся только подставить свой путь к приложению.
Я вот сейчас опять же за вас взял, открыл пример скрипта их архива с плагином, подставил путь к консольному приложению и у меня всё считалось. Почему?
Как скажите мне, отправлять что то окну если при использовании 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 этого не сделаешь. Разве я не прав?
нужно отправить enter выполняемому приложению, а используя execdos этого не сделаешь »
А с помощью ExecCmd сделаешь? Причем здесь эти плагины и отправка сообщений окну?
Плагины ExecCmd и ExecDos используются для создания процесса с скрытым окном приложения. Всё. Это основной функционал.
С чего вы взяли вообще, что именно с помощью ExecCmd/ExecDos можно отправлять сообщения окну?
Ещё раз повторюсь, что пример отправки нажатия Enter в консольное приложение вам давали год назад, разве я не прав?
Со стороны это выглядит довольно глупо, начинать обсуждать год спустя то, что уже обсуждали. Вы память потеряли? Или просто опять лень теперь уже прочитать всё то, что уже написано год назад в этой теме?
Vincent7
03-12-2014, 01:11
K.A.V., с помощью execcmd да, можно. А с чего вы взяли что я с чего-то взял что можно отправлять именно с помощью плагинов? Можно и подругому. Хорошо, спрошу иначе- можно ли без использования плагинов отправлять лог из выполняемого консольного приложения в nsis функцию?
В общем, не знаю, как правильно пояснить.
Может маленькое видео поможет. »
Да, лажа на видео... Но у меня на восьмёрке вроде как всё нормально происходит. Если можно назвать нормальным, явную задержку при перерисовке стола...
Я пробовал разные утилитки, предназначенные специально для рестарта - всё в целом одно и то же - тормоза и визуально ужасно...
Например, : 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, большое спасибо за то, что провели исследование данной проблемы и поделились результатами. Ваши рекомендации попробую применить для своих целей.
можно ли без использования плагинов отправлять лог из выполняемого консольного приложения в 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
Ребят Можно ли как-то добавить свой текст на странице прогресса установки (под прогресс баром)?
Вывод деталей установки отключён - там пусто сейчас. Хочу кое каким текстом заполнить.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC