PDA

Показать полную графическую версию : Нужен bat для удаления ИЗМЕНЁННЫХ папок и программ (ярлыков) из меню "Пуск-Программы"


Nun-Nun
26-02-2011, 15:11
Нужен батник для поиска и удаления папок и программ (ярлыков) из меню "Пуск->Программы", организованный таким образом, чтобы можно было найти и удалить искомое, даже если пользователь изменил их дефолтное расположение и название.

Iska
01-03-2011, 11:16
Nun-Nun, Ваш вопрос не ясен.даже если пользователь изменил их дефолтное расположение и название. »
«Пользователь изменил расположение» — всё же, в пределах Главного меню?! Или, скажем, если сдуру перетащил к себе на Рабочий стол?! Так?

«и название» — тут придётся ориентироваться на свойство ярлыка target. Нужно будет знать это самое значение target — раз, исходное название и местоположение ярлыка — два.

Во всяком случае, задача явно не для пакетных файлов, скорее это для Automation — WSH/PoSH/AutoIt.

Nun-Nun
01-03-2011, 12:42
в пределах Главного меню?! Или, скажем, если сдуру перетащил к себе на Рабочий стол?!»
Только в пределах главного меню. Рабочий стол и т.п. я не имею в виду.
«и название» — тут придётся ориентироваться на свойство ярлыка target. »
Может быть, но мне кажется, что лучше ориентироваться на исполняемый файл, запускаемый ярлыком.

Iska
03-03-2011, 15:05
Может быть, но мне кажется, что лучше ориентироваться на исполняемый файл, запускаемый ярлыком. »
Это оно и есть.

Примерно так:
Option Explicit

Dim objFSO
Dim arrTargetPaths


arrTargetPaths = Array("C:\WINDOWS\winhlp32.exe", "C:\WINDOWS\winhelp.exe", "C:\WINDOWS\Installer\{90110419-6000-11D3-8CFE-0150048383C9}\wordicon.exe")

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

With WScript.CreateObject("Shell.Application")
ScanSubFolders objFSO.GetFolder(.NameSpace("shell:Start Menu").Self.Path), arrTargetPaths
ScanSubFolders objFSO.GetFolder(.NameSpace("shell:Common Start Menu").Self.Path), arrTargetPaths
End With

Set objFSO = Nothing

WScript.Quit 0
'=======================================================

'=======================================================
Sub ScanSubFolders(objFolder, arrTargetPaths)
Dim objSubFolder
Dim objFile

Dim elem

WScript.Echo "[" & objFolder.Path & "]"

For Each objFile In objFolder.Files
If UCase(objFSO.GetExtensionName(objFile.Path)) = UCase("lnk") Then
With WScript.CreateObject("WScript.Shell").CreateShortcut(objFile.Path)
For Each elem In arrTargetPaths
If UCase(elem) = UCase(.TargetPath) Then
WScript.Echo vbTab, "Name: ", objFSO.GetBaseName(objFile.Name)
WScript.Echo vbTab, "Path: ", objFile.Path
WScript.Echo vbTab, "Target: ", .TargetPath
WScript.Echo vbTab

'objFile.Delete True

Exit For
End If
Next
End With
End If
Next

For Each objSubFolder In objFolder.SubFolders
ScanSubFolders objSubFolder, arrTargetPaths
Next
End Sub
'=======================================================

Поиск осуществляется в «Главном меню» текущего пользователя и в общем «Главном меню». Перечень target'ов задаётся массивом «arrTargetPaths»:
arrTargetPaths = Array("C:\WINDOWS\winhlp32.exe", "C:\WINDOWS\winhelp.exe", "C:\WINDOWS\Installer\{90110419-6000-11D3-8CFE-0150048383C9}\wordicon.exe")
Удаление найденного ярлыка в скрипте «во избежание» закомментировано:
'objFile.Delete True

Nun-Nun
03-03-2011, 15:45
Поиск осуществляется в «Главном меню» текущего пользователя и в общем «Главном меню». Перечень target'ов задаётся массивом «arrTargetPaths»: »
Допустимо ли в массиве target'ов задавать не только удаление ярлыков, но и отдельных папок, в которых эти ярлыки могут оказаться расположены (разумеется, за исключением самой папки "Программы" и папок типа "Стандартные", "Автозагрузка", "Администрирование" и т.п.)?

Iska
03-03-2011, 18:14
Допустимо ли в массиве target'ов задавать не только удаление ярлыков, но и отдельных папок…»
Задавать — допустимо, но работать это, понятное дело, не будет, ибо как не предусматривалось исходным ТЗ.

Опишите подробнее Вашу ситуацию, может станет яснее.

Nun-Nun
03-03-2011, 21:38
Опишите подробнее Вашу ситуацию, может станет яснее. »
Всё очень "просто": в меню "Программы" исходная программа может устанавливаться в самостоятельную папку. Возьмём, к примеру, программу 7-Zip. При её установке в меню "Программы" создаётся отдельная папка "7-Zip", в которой, соответственно, создаются ярлыки для файлов программы: "7-Zip 9.20", "Деинсталляция 7-Zip 9.20" и т.п. После установки программы пользователь может поступить так:
1) ничего не переименовывая, перетащить исходную папку установленной программы вместе с ярлыками в другую папку меню "Программы";
2) перетащить ярлыки установленной программы (как переименовав, так и не переименовав) в другую папку меню "Программы", а исходную папку (например, того же "7-Zip") удалить;
3) не перетаскивая исходной папки установленной программы, только переименовать ярлыки;
4) не перетаскивая исходной папки установленной программы, переименовать её (папку) и (или) ярлыки в ней;
5) ничего не перетаскивая, переименовать только исходную папку установленной программы, не трогая названий ярлыков;
6) ничего не перетаскивая, переименовать и исходную папку установленной программы, и названия ярлыков;
7) переименовать и исходную папку установленной прграммы, и названия ярлыков, а также перетащить всё это в другую папку меню "Программы".

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

Таким образом, поставленная задача выглядит так: найти и обезвредить (соррри, - удалить) последствия этого пользовательского рукоблудия (удалить и ярлыки, и папку, в которой они оказались (если, конечно, это отдельная папка)). При этом, разумеется, необходимо исключить возможность удаления как самого меню "Программы", так и расположенных в нём стандартных папок типа "Стандартные", "Автозагрузка", "Администрирование", "Утилиты" и т.п.

P.S. Уровень моих навыков в области написания bat-файлов пока ещё не на том уровне, чтобы решить подобную задачу самостоятельно, вот и приходится обращаться за помощью.

Iska
03-03-2011, 22:23
Nun-Nun, задача в поставленном виде банально не решаема (разве что иметь предварительно подготовленным весь эталонный набор ярлыков). Но, дабы не предсказывать действия пользователей — придумали групповые политики, в данном случае это:
Политика "Локальный компьютер"
Конфигурация пользователя
Административные шаблоны
Панель задач и меню "Пуск"

и там смотрите, в частности:
Удалить контекстные меню перетаскивания для элементов меню "Пуск"
Запретить изменение параметров панели задач и меню "Пуск"
Запретить доступ к контекстному меню для панели задач
Удаление значка доступа к программам и параметров по умолчанию из меню "Пуск"

(пример приведён для локальной групповой политики на изолированной машине Windows XP).

Если нет домена — для рабочей группы можно организовать распространение настроек политик посредством файлов реестра (это, конечно, не политики, но хотя бы так). Описание соответствия групповых политик можно взять из «gp.chm» из комплекта «Resource Kit» Windows 2000, или (для нынешних систем) отсюда: Download details: Group Policy Settings Reference for Windows and Windows Server (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=18c90c80-8b0a-4906-a4f5-ff24cc2030fb&displaylang=en), или, наконец, банально отсюда: Твики реестра (CHM) 1.9 (http://www.oszone.net/5618/).

По поводу же скрипта из #4 (http://forum.oszone.net/post-1626346-4.html), единственное, что могу предложить — поправить его так, дабы он удалял пустые папки, оставшиеся пустыми после удаления указанных ярлыков. Кстати, вопрос — перечень в «arrTargetPaths» у Вас длинный? Может, стоит сделать чтение данного перечня из текстового файла?!

P.S. Наткнулся в Download details: Group Policy Settings Reference for Windows and Windows Server (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=18c90c80-8b0a-4906-a4f5-ff24cc2030fb&displaylang=en) на весьма пользительную ссылку — Group Policy Search (http://gps.cloudapp.net/): указываем политику и сразу видим толкование, путь к политике в редакторе, применимость к ОС и параметр реестра, куда пишется данная политика при её применении.

Nun-Nun
04-03-2011, 11:12
По поводу же скрипта из #4, единственное, что могу предложить — поправить его так, дабы он удалял пустые папки, оставшиеся пустыми после удаления указанных ярлыков. »
Да, добавьте если не сложно.
Кстати, вопрос — перечень в «arrTargetPaths» у Вас длинный? Может, стоит сделать чтение данного перечня из текстового файла?! »
Нет, перечень не длинный. Подразумевается использование данного скрипта в аддонах программ. Предполагается, что каждый такой аддон будет проверять только наличие ранее установленной версии одной конкретной программы, и если находит, то удаляет её папку и ярлыки. Устанавливаемые программы (в подавляющем большинстве случаев) имеют всего один исполняемый файл, а при инсталляции создают в меню "Пуск" свою собственную папку с 1-5 ярлыками в ней, так что если пользователь ничего не менял, и в названиях папки и расположенных в ней ярлыков (на исполняемый или иной файл) встречается одинаковое выражение (например, "7-Zip"), то можно смело удалять всю папку вместе с ярлыками. Наиболее сложная часть эпопеи с поиском, описанным в предыдущем посте, имеет место только в случае, когда пользователь переименовал папку и (или) ярлыки; если пользователь только перетащил папку программы вместе с ярлыками в другое место, то, насколько понимаю, необходимые поиск и удаление будут не очень сложными, тут поиск может быть организован не только по названию исполняемого файла, но и по конкретному выражению в названиях папок и ярлыков, например, "7-Zip".

P.S.

В идеале весь процесс работы по нахождению-удалению я вижу таким: при установке аддон запускает поиск по конкретному выражению в названиях папок и ярлыков:

- если оно найдено в названии папки - удаление этой папки вместе с ярлыками;
- если оно найдено только в названии ярлыка (ярлыков) - удаление этого ярлыка (ярлыков);
- если после удаления ярлыка (ярлыков) папка осталась пустой - удаление этой папки (разумеется, если это не сама папка меню "Программы" или расположенные в ней типа "Стандартные", "Автозагрузка", "Администрирование", "Утилиты" и т.п.);
- если ничего не найдено по конкретному выражению, то запуск поиска ярлыка (ярлыков) по названию исполняемого файла, при этом:
- если такой ярлык найден - удаление этого ярлыка (если после удаления ярлыка папка осталась пустой - удаление папки (за исключением вышеназванных стандартных)).

Вот, в принципе, так.

Iska
05-03-2011, 07:08
добавьте если не сложно. »
Добавил (удаление папок так же закомментировано):
If objFolder.Files.Count = 0 And objFolder.SubFolders.Count = 0 Then
'objFolder.Delete True
End If

но не проверял:
Option Explicit

Dim objFSO
Dim arrTargetPaths


arrTargetPaths = Array("C:\WINDOWS\winhlp32.exe", "C:\WINDOWS\winhelp.exe", "C:\WINDOWS\Installer\{90110419-6000-11D3-8CFE-0150048383C9}\wordicon.exe")

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

With WScript.CreateObject("Shell.Application")
ScanSubFolders objFSO.GetFolder(.NameSpace("shell:Start Menu").Self.Path), arrTargetPaths
ScanSubFolders objFSO.GetFolder(.NameSpace("shell:Common Start Menu").Self.Path), arrTargetPaths
End With

Set objFSO = Nothing

WScript.Quit 0
'=======================================================

'=======================================================
Sub ScanSubFolders(objFolder, arrTargetPaths)
Dim objSubFolder
Dim objFile

Dim elem

WScript.Echo "[" & objFolder.Path & "]"

For Each objFile In objFolder.Files
If UCase(objFSO.GetExtensionName(objFile.Path)) = UCase("lnk") Then
With WScript.CreateObject("WScript.Shell").CreateShortcut(objFile.Path)
For Each elem In arrTargetPaths
If UCase(elem) = UCase(.TargetPath) Then
WScript.Echo vbTab, "Name: ", objFSO.GetBaseName(objFile.Name)
WScript.Echo vbTab, "Path: ", objFile.Path
WScript.Echo vbTab, "Target: ", .TargetPath
WScript.Echo vbTab

'objFile.Delete True

Exit For
End If
Next
End With
End If
Next

For Each objSubFolder In objFolder.SubFolders
ScanSubFolders objSubFolder, arrTargetPaths
Next

If objFolder.Files.Count = 0 And objFolder.SubFolders.Count = 0 Then
'objFolder.Delete True
End If
End Sub
'=======================================================


Предполагается, что каждый такой аддон будет проверять только наличие ранее установленной версии одной конкретной программы, и если находит, то удаляет её папку и ярлыки. Устанавливаемые программы (в подавляющем большинстве случаев) имеют всего один исполняемый файл, а при инсталляции создают в меню "Пуск" свою собственную папку с 1-5 ярлыками в ней, так что если пользователь ничего не менял, »
А как быть с теми программами, которые используют одну папку в Главном меню, например, MS Office и FrontPage?!

P.S. Есть подозрение, что Вы не сможете его использовать при установке в виде Addon'ов в таком виде из-за «CreateObject("Shell.Application")».

Nun-Nun
05-03-2011, 10:35
А как быть с теми программами, которые используют одну папку в Главном меню, например, MS Office и FrontPage?!»
Скрипт для таких монстров использоваться не будет. В основном предполагается установка-удаление небольших программ-утилит.
Есть подозрение, что Вы не сможете его использовать при установке в виде Addon'ов в таком виде из-за «CreateObject("Shell.Application")».»
В принципе, для аддона, интегрируемого в дистрибутив Windows, этот скрипт и не нужен, т.к. в дистрибутиве нет предыдущих версий устанавливаемых (интегрируемых) программ, а вот для установки на живую систему - самое то! Так что, если после интеграции никаких сюрпризов не возникнет - можно считать, что цель достигнута.

P.S. Может в скрипт стОит добавить что-то типа функции определения, запущен ли скрипт на живой системе или нет? Если запущен не наживой системе, то не выполняется. Правда не представляю, возможно ли такое реализовать в принципе.

Iska
05-03-2011, 11:00
…а вот для установки на живую систему - самое то! »
Ясно.
P.S. Может в скрипт стОит добавить что-то типа функции определения, запущен ли скрипт на живой системе или нет? Если запущен не наживой системе, то не выполняется. »
Да нет проблем. Скажите, на что ориентироваться — сделаем :).

Установкой приложений через addon'ы я не стал заниматься, ограничившись более удобным для меня методом «RunOnceEx», посему не особо представляю, на что там следует ориентироваться. Попробуйте спросить в соответствующей ветке по аддонам, а здесь дайте ссылку на свой пост, дабы я тоже мог смотреть на ответы.

gora
05-03-2011, 16:47
Nun-Nun, интересно, а какова конечная цель всех этих действий? Ну удалили Вы ярлыки, а что с самими программами будет? С их записями в реестр?
Теперь давайте разберем использование задуманного Вами деяния в виде аддона. Пусть это будет SVCPACK аддон. Отличить его установку на T13 и на живую систему наверное можно. На T13 не существует некоторых системных переменных, например, HOMEDRIVE, APPDATA, TEMP, HOMEPATH и т.д. и можно проверять их существование, но что это даст? Аддон кастрируемой программы может устанавливаться и позже чем Ваш аддон. Он может устанавливаться и из RunOnceEx, и из Run, и из WPI, что сведет на нет деятельность Вашего, ибо он не увидит, устанавливаемых позже, аддонов.
Теперь про установку на живую систему "бедного" пользователя. Он привык к одному расположению ярлыков, а тут пришел Nun-Nun и все "почикал". :clapping: Ярлык может использоваться не только для двойного клика, но и быть ссылкой для запуска программы из какого-то скрипта в котором его место уже прописано, После Вашего аддона, переписывать скрипты прикажете?
Не увидев ярлыка в привычном месте, пользователь может решить, что программы у него больше нет и, не проверив в Установка/удаление поставить поверх новую версию. Это не всегда безболезненно для программы да и мусор может оставаться.
Если Вы еще собираетесь по такому же принципу удалять сами программы (поиском на компьютере исполняемого файла), то у меня на компьютере упомянутого 7z.exe, разных версий, наберется не один десяток в разных закоулках для разных целей, как и ярлыков к ним. И все они мне нужны и доверять наводить порядок в ярлыках и программах Вашему скрипту я бы не решился.

Хотелось бы услышать: концепцию Вашего аддона, его конечную цель и круг его предполагаемых пользователей.

Nun-Nun
05-03-2011, 18:43
Установкой приложений через addon'ы я не стал заниматься, ограничившись более удобным для меня методом «RunOnceEx», посему не особо представляю, на что там следует ориентироваться. »
Да хотя бы на переменные HOMEDRIVE, APPDATA, TEMP, HOMEPATH, о которых говорит gora. Или могу в интегрируемый аддон подкладывать какой-нибудь файл-пустышку (например, NoLiveOS), на наличие которого можно ориентировать Ваш скрипт.
дайте ссылку на свой пост, дабы я тоже мог смотреть на ответы. »
Обязательно.
Аддон кастрируемой программы может устанавливаться и позже чем Ваш аддон. Он может устанавливаться и из RunOnceEx, и из Run, и из WPI, что сведет на нет деятельность Вашего, ибо он не увидит, устанавливаемых позже, аддонов. »
Увы, Вы не верно поняли мою идею. Я не собираюсь применять обсуждаемый скрипт и аддоны, сделанные на его основе, к чьим-то аддонам или программам, а предполагаю применение только в отношении аддонов, которые создаю сам, и о которых знаю всё, что они делают - куда и какие в систему копируют файлы, где и какие делают записали в реестре. И согласитесь, если я знаю это, предусмотреть корректность действий более новых версий аддонов вполне возможно, и не только возможно, но и нужно (ну должен же автор по мере возможностей стараться обеспечить правильность работы своих программ). Не так ли?
Не увидев ярлыка в привычном месте, пользователь может решить, что программы у него больше нет и, не проверив в Установка/удаление поставить поверх новую версию. Это не всегда безболезненно для программы да и мусор может оставаться. »
Думаю, что выше уже ответил и на это возражение.
Хотелось бы услышать: концепцию Вашего аддона, его конечную цель и круг его предполагаемых пользователей »
По поводу концепции я уже немного сказал выше. К этому добавлю, что ещё одним из интересных направлений считаю возможность установки новой версии прямо поверх более старой (без предварительного удаления старой). При этом аддон новой версии должен сначала корректно удалить аддон более старой версии и только после этого встать в систему. В общем-то весь сыр-бор пока вокруг этого. Кто аддонами воспользуется - пока не знаю, т.к. делаю их в первую очередь для себя, но если это ещё кого-то заинтересует - буду рад поделиться.

Iska
17-03-2011, 23:15
Жильцам от начальника ЖЭКа (http://www.google.ru/search?q=%D0%B6%D0%B8%D0%BB%D1%8C%D1%86%D0%B0%D0%BC+%D0%BE%D1%82+%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8 C%D0%BD%D0%B8%D0%BA%D0%B0+%D0%B6%D1%8D%D0%BA%D0%B0) Нет, что-то не то :lol:… А, вот как: Из письма в ПМ:
Прошу прощения, вот в этой теме (http://forum.oszone.net/thread-200555.html) Вы помогли мне сделать скрипт для удаления ярлыков, но остался нерешённым вопрос относительно определения скриптом типа системы, т.е. живая или нет. Хочу Вас попросить: могли бы Вы добавить эту функцию? Ориентироваться можно, например, на файл-пустышку LiveOS: если он в аддоне есть, значит скрипт запущен на живой системе, если нет - интегрирован в дистрибутив XP (перед интеграцией пользователь должен будет его удалить).
Расскажите мне, что это означает «…если он в аддоне есть».
P.S. И ещё один вопрос: поскольку скрипт написан на языке, отличающемся от языка обычного bat-ника, хотелось бы узнать как он должен быть оформлен: файл со скриптом просто сохранить как bat-ник, больше ничего не трогая, или в тексте bat-файла требуется добавить ещё какие-либо команды?
Сохранить текст скрипта в файл в кодировке ANSI (windows-1251) с расширением «vbs». Вызов осуществляется как:
wscript.exe "«путь к файлу скрипта.vbs»"
в GUI режиме, и:
cscript.exe //nologo "«путь к файлу скрипта.vbs»"
в консольном режиме. Для пакетного режима работы (подавление выводимых скриптом сообщений) дополнительно добавляется параметр «//b». Подробности, как обычно, в «wscript.exe /?».

P.S. Подобные вопросы следует задавать непосредственно в теме, ибо:
* ответ в любом случае появится там же, поскольку ограничение на размер письма в ПМ не позволяет ответить иначе, нежели в теме;
* задавая вопрос не на форуме, а одному человеку в ПМ, Вы резко сокращаете аудиторию, которая могла бы дать Вам ответ. Помимо Iska на форуме более чем достаточно участников, могущих и умеющих помочь.

Nun-Nun
18-03-2011, 10:14
Расскажите мне, что это означает «…если он в аддоне есть». »
Изначально он будет присутствовать в составе аддона и будет лежать рядом с исполняемым файлом аддона. Если пользователю необходима интеграция, то до запуска этого процесса пользователь должен будет файл удалить.
В принципе, если сочтёте, что лучше сделать по-другому - я возражать не буду, просто мне показалось, что предложенный вариант наиболее лёгкий в реализации (в крайнем случае могу даже и без этого обойтись: на живой системе запускать exe-шником, а из дистриба - батником, тогда вообще никаких проблем).

P.S. За подсказки спасибо, а вот юмор по поводу сообщения, перекочевавшего из ПМ, выглядит, мягко говоря, странно.




© OSzone.net 2001-2012