Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Запуск скрипта из папки (http://forum.oszone.net/showthread.php?t=336151)

BOBAT 12-08-2018 11:22 2826039

Запуск скрипта из папки
 
Находясь в папке нажимаю пкм и запускаю скрипт (находящийся в другом месте, например в C:\Windows), как сделать так, чтобы скрипт как бы запустился из этой папки

Iska 12-08-2018 11:59 2826046

Цитата:

Цитата BOBAT
Находясь в папке нажимаю пкм и запускаю скрипт »

Это то, что у Вас уже есть, или это то, что Вам бы хотелось получить, но не знаете — как?

BOBAT 12-08-2018 12:10 2826047

У меня есть скрипт cmd, который находясь в папке и запускаясь из неё производит определённые действия в этой папке, я хочу, чтобы находясь в любой папке я правой кнопкой из меню вызывал бы этот скрипт, и он бы отрабатывал, как бы находясь в этой папке. Сам скрипт я положил в C:\Windows, запускаю его через vbs, чтоб не мелькало консольное окно, добавил пункт в меню, который запускает этот vbs,, и он запускается и конечно запускает сам cmd, но из всех команд cmd отрабатывают только те, которые меняют атрибуты в той папке и атрибуты самой папки, той, где я нахожусь, остальные команды не отрабатывают, может есть возможность как то скопировать, что ли это cmd в папку, запустить его, он отработает, потом удалить его командой из этого же cmd

megaloman 12-08-2018 14:08 2826065

BOBAT, Я правильно понимаю: vbs запускает cmd? Где vbs (хотелось бы на него взглянуть)? Где cmd? В vbs явно прописан путь к cmd? В самом cmd нигде нет ссылки на его путь, что-то типа
%~dp0 ?

Iska 12-08-2018 16:57 2826083

BOBAT, тогда для начала приведите а) код пакетного файла, б) код скрипта WSH, в) опишите, как именно Вы реализовали:
Цитата:

Цитата BOBAT
добавил пункт в меню, который запускает этот vbs, »

От этого и будем дальше танцевать.

BOBAT 12-08-2018 20:44 2826112

Код zapusk.vbs
Код:

Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c icon_hide_icon_txt.cmd", 0, false

Код hide_icon_txt.cmd
Код:

@Echo Off
ChCp 1251>Nul
Attrib -H "*.ico"
Set fldr=%~dp0
If Exist "%~dp0desktop.ini" Attrib -H -S "%~dp0desktop.ini"
For %%i In ("%~dp0*.ico") Do (
        (Echo [.ShellClassInfo]
        Echo IconResource=%%~nxi,0
        Ver | Find "6.">Nul || (Echo IconFile=%%~nxi& Echo IconIndex=0)
        )>"%~dp0desktop.ini"
)
Attrib +H +S "%~dp0desktop.ini"
Attrib +R "%fldr:~0,-1%"
Attrib +H "*.ico"

Добавил пункт в меню через реестр
Код:

[HKEY_CLASSES_ROOT\Directory\Background\shell\HHFF]
@="Изменить иконку папки"
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\Directory\Background\shell\HHFF\command]
@="WScript C:\\Windows\\zapusk.vbs"


Iska 13-08-2018 00:17 2826122

BOBAT, ясно. Понимаете, в чём дело… Скрипт у Вас находится в каталоге %SystemRoot%, пакетный файл, надо полагать, там же, рядом с ним (иначе Вы его таким кодом не запустите). Пакетный файл (из какой бы папки Вы не запускали скрипт) считает целевым каталогом тот, в котором находится сам (Set fldr=%~dp0), и всякий раз отрабатывает на том же каталоге %SystemRoot%.

Для начала давайте избавимся от пакетного файла вовсе. Назовём скрипт «Attach Icon to Folder.vbs» и поместим его в собственный каталог «Attach Icon to Folder» в «%ProgramFiles%»:
C:\Program Files\Attach Icon to Folder\Attach Icon to Folder.vbs
Код:

Option Explicit

Const ReadOnly = 1
Const Hidden  = 2
Const System  = 4


Dim strSourceFolder

Dim objFSO
Dim objFile

Dim strDesktopIniFile


If WScript.Arguments.Count = 1 Then
        strSourceFolder = WScript.Arguments.Item(0)
       
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
       
        If objFSO.FolderExists(strSourceFolder) Then
                strDesktopIniFile = objFSO.BuildPath(strSourceFolder, "desktop.ini")
               
                For Each objFile In objFSO.GetFolder(strSourceFolder).Files
                        If StrComp(objFSO.GetExtensionName(objFile.Name), "ico", vbTextCompare) = 0 Then
                                objFile.Attributes = objFile.Attributes Or Hidden
                               
                                If objFSO.FileExists(strDesktopIniFile) Then
                                        With objFSO.GetFile(strDesktopIniFile)
                                                .Attributes = .Attributes And Not (System Or Hidden)
                                        End With
                                End If
                               
                                With objFSO.CreateTextFile(strDesktopIniFile, True)
                                        .WriteLine "[.ShellClassInfo]"
                                        .WriteLine "IconResource=" & objFile.Name & ",0"
                                       
                                        If Left(objFSO.GetFileVersion("C:\Windows\System32\ntdll.dll"), 2) <> "6." Then
                                                .WriteLine "IconFile=" & objFile.Name
                                                .WriteLine "IconIndex=0"
                                        End If
                                       
                                        .Close
                                End With
                               
                                With objFSO.GetFile(strDesktopIniFile)
                                        .Attributes = .Attributes Or (System Or Hidden)
                                End With
                               
                                With objFSO.GetFolder(strSourceFolder)
                                        .Attributes = .Attributes Or ReadOnly
                                End With
                               
                                Exit For
                        End If
                Next
        Else
                WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
                WScript.Quit 2
        End If
       
        Set objFSO = Nothing
Else
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source folder>"
        WScript.Quit 1
End If

WScript.Quit 0


Для внедрения в контекстное меню используем следующий файл реестра:
Код:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\Background\shell\Attach Icon to Folder]
@="Назначить значок папке"
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\Directory\Background\shell\Attach Icon to Folder\command]
@=hex(2):22,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,\
  00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,77,00,\
  73,00,63,00,72,00,69,00,70,00,74,00,2e,00,65,00,78,00,65,00,22,00,20,00,22,\
  00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,\
  73,00,25,00,5c,00,41,00,74,00,74,00,61,00,63,00,68,00,20,00,49,00,63,00,6f,\
  00,6e,00,20,00,74,00,6f,00,20,00,46,00,6f,00,6c,00,64,00,65,00,72,00,5c,00,\
  41,00,74,00,74,00,61,00,63,00,68,00,20,00,49,00,63,00,6f,00,6e,00,20,00,74,\
  00,6f,00,20,00,46,00,6f,00,6c,00,64,00,65,00,72,00,2e,00,76,00,62,00,73,00,\
  22,00,20,00,22,00,25,00,56,00,22,00,00,00

здесь значение параметра по умолчанию раздела command — «"%SystemRoot%\System32\wscript.exe" "%ProgramFiles%\Attach Icon to Folder\Attach Icon to Folder.vbs" "%V"» с типом REG_EXPAND_SZ (вместо типичного REG_SZ).

Сохраните скрипт по указанному месту, импортируйте файл реестра в реестр, пользуйте.

P.S. Но идея реализации мне всё равно категорически не нравится. Я бы привязывался не к папке (HKEY_CLASSES_ROOT\Directory\Background), а к файлам *.ico — так будет и правильнее, и надёжнее, и позволит указать конкретный файл ico, если их будет несколько.

BOBAT 13-08-2018 07:15 2826131

Цитата Iska:
Понимаете, в чём дело… Скрипт у Вас находится в каталоге %SystemRoot%, пакетный файл, надо полагать, там же, рядом с ним (иначе Вы его таким кодом не запустите). Пакетный файл (из какой бы папки Вы не запускали скрипт) считает целевым каталогом тот, в котором находится сам (Set fldr=%~dp0), и всякий раз отрабатывает на том же каталоге %SystemRoot%. »
Я думал, может быть, если vbs как то определит каталог запуска, то може быть он и скопирует мой cmd в этот каталог и запустит его оттуда, а cmd в этой папке отработает и удалится.
Как я понимаю, по Вашему коду Ваш vbs всё таки определяет каталог запуска? И потом уже отрабатывает код как бы из него??
Всё сделал по Вашему, при нажатии Назначить иконку папке выскакивает



Моя ошибка, простите, папку положил в C:\Program Files (x86) (у меня 64 бита) а в ошибке ясно пишет путь запуска, переложил в C:\Program Files - ВСЁ прекрасно заработало. Огромное спасибо.
И можно ли как то вставить в Ваш vbs код, чтобы он брал название папки и присваивал его иконке, которая находится там же?

Iska 13-08-2018 07:35 2826134

Цитата:

Цитата BOBAT
Я думал, может быть, если vbs как то определит каталог запуска, »

Чтобы он «как-то определил» — этим нужно предварительно озаботиться.

Цитата:

Цитата BOBAT
то може быть он и скопирует мой cmd в этот каталог и запустит его оттуда, а cmd в этой папке отработает и удалится. »

Зачем всё вот это — скопирует, запустит, отработает, удалится? Ничего этого уже не нужно.

Цитата:

Цитата BOBAT
Как я понимаю, по Вашему коду Ваш vbs всё таки определяет каталог запуска? »

Да. Путь передаётся ему посредством параметра:
Цитата:

Цитата Iska
здесь значение параметра по умолчанию раздела command — «"%SystemRoot%\System32\wscript.exe" "%ProgramFiles%\Attach Icon to Folder\Attach Icon to Folder.vbs" "%V"» с типом REG_EXPAND_SZ (вместо типичного REG_SZ). »

Цитата:

Цитата BOBAT
Всё сделал по Вашему, при нажатии Назначить иконку папке выскакивает »

Покажите скриншот каталога C:\Program Files\Attach Icon to Folder с находящемся в нём скриптом Attach Icon to Folder.vbs. Хочу увидеть.

Цитата:

Цитата BOBAT
От cmd конечно нужно отказываться, есть ли способ переконвертировать мой cmd в vbs, »

Не нужно переконвертировать. Уже не нужно. Пакетный файл больше не нужен. Совсем.

Цитата:

Цитата BOBAT
иконок в папке не может быть больше одной, »

Тем не менее, код Вашего пакетного файла перебирает их все, сколько бы ни было, и назначает самую последнюю. Мой код — самую первую. Но как я писал, мне не нравится сам подход.

Цитата:

Цитата BOBAT
также мой cmd не выводит никаких сообщений в случае отсутствия каких либо иконок в папке, »

Мой код — тоже. Он ничего в этом случае не делает. Ваш — независимо от наличия иконок в любом случае назначает каталогу атрибут «Только для чтения».

Цитата:

Цитата BOBAT
хотелось бы ещё код вставить в cmd чтобы он, »

Забудьте уже про пакетный файл.

Цитата:

Цитата BOBAT
и переименовывал иконку, которая лежит в этой папке на полученное (то есть название папки и название иконки совпадают), »

Э… Можно, но… зачем?!

BOBAT 13-08-2018 08:17 2826136

Цитата:

Цитата Iska
Э… Можно, но… зачем?! »

Для эстетики... Ваш код и файл всё прекрасно отрабатывет. Большое спасибо!!!

Iska 13-08-2018 09:39 2826140

Цитата:

Цитата BOBAT
Для эстетики... »

Скрытый текст
Код:

Option Explicit

Const ReadOnly = 1
Const Hidden  = 2
Const System  = 4


Dim strSourceFolder

Dim objFSO
Dim objFile

Dim strDesktopIniFile


If WScript.Arguments.Count = 1 Then
        strSourceFolder = WScript.Arguments.Item(0)
       
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
       
        If objFSO.FolderExists(strSourceFolder) Then
                strDesktopIniFile = objFSO.BuildPath(strSourceFolder, "desktop.ini")
               
                For Each objFile In objFSO.GetFolder(strSourceFolder).Files
                        If StrComp(objFSO.GetExtensionName(objFile.Name), "ico", vbTextCompare) = 0 Then
                                objFile.Name = objFSO.GetBaseName(strSourceFolder) & ".ico"
                                objFile.Attributes = objFile.Attributes Or Hidden
                               
                                If objFSO.FileExists(strDesktopIniFile) Then
                                        With objFSO.GetFile(strDesktopIniFile)
                                                .Attributes = .Attributes And Not (System Or Hidden)
                                        End With
                                End If
                               
                                With objFSO.CreateTextFile(strDesktopIniFile, True)
                                        .WriteLine "[.ShellClassInfo]"
                                        .WriteLine "IconResource=" & objFile.Name & ",0"
                                       
                                        If Left(objFSO.GetFileVersion("C:\Windows\System32\ntdll.dll"), 2) <> "6." Then
                                                .WriteLine "IconFile=" & objFile.Name
                                                .WriteLine "IconIndex=0"
                                        End If
                                       
                                        .Close
                                End With
                               
                                With objFSO.GetFile(strDesktopIniFile)
                                        .Attributes = .Attributes Or (System Or Hidden)
                                End With
                               
                                With objFSO.GetFolder(strSourceFolder)
                                        .Attributes = .Attributes Or ReadOnly
                                End With
                               
                                Exit For
                        End If
                Next
        Else
                WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
                WScript.Quit 2
        End If
       
        Set objFSO = Nothing
Else
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source folder>"
        WScript.Quit 1
End If

WScript.Quit 0



BOBAT, и тем не менее, правильнее будет всё же привязываться к ico-файлу, а не к фону папки.
C:\Program Files\Attach Icon to Folder\Attach Icon to Folder 2.vbs
Код:

Option Explicit

Const ReadOnly = 1
Const Hidden  = 2
Const System  = 4


Dim strIconFile
Dim strSourceFolder

Dim objFSO

Dim strDesktopIniFile


If WScript.Arguments.Count = 1 Then
        strIconFile = WScript.Arguments.Item(0)
       
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
       
        If objFSO.FileExists(strIconFile) Then
                If StrComp(objFSO.GetExtensionName(strIconFile), "ico", vbTextCompare) = 0 Then
                        With objFSO.GetFile(strIconFile)
                                strSourceFolder = .ParentFolder.Path
                               
                                .Attributes = .Attributes Or Hidden
                        End With
                       
                        strDesktopIniFile = objFSO.BuildPath(strSourceFolder, "desktop.ini")
                       
                        If objFSO.FileExists(strDesktopIniFile) Then
                                With objFSO.GetFile(strDesktopIniFile)
                                        .Attributes = .Attributes And Not (System Or Hidden)
                                End With
                        End If
                       
                        With objFSO.CreateTextFile(strDesktopIniFile, True)
                                .WriteLine "[.ShellClassInfo]"
                                .WriteLine "IconResource=" & objFSO.GetFileName(strIconFile) & ",0"
                               
                                If Left(objFSO.GetFileVersion("C:\Windows\System32\ntdll.dll"), 2) <> "6." Then
                                        .WriteLine "IconFile=" & objFSO.GetFileName(strIconFile)
                                        .WriteLine "IconIndex=0"
                                End If
                               
                                .Close
                        End With
                       
                        With objFSO.GetFile(strDesktopIniFile)
                                .Attributes = .Attributes Or (System Or Hidden)
                        End With
                       
                        With objFSO.GetFolder(strSourceFolder)
                                .Attributes = .Attributes Or ReadOnly
                        End With
                Else
                        WScript.Echo "Icon file [" & strIconFile & "] contain not an <ico> extension."
                        WScript.Quit 3
                End If
        Else
                WScript.Echo "Can't find icon file [" & strIconFile & "]."
                WScript.Quit 2
        End If
       
        Set objFSO = Nothing
Else
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Icon file>"
        WScript.Quit 1
End If

WScript.Quit 0


Файл реестра для него:
Код:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\icofile\shell\Attach Icon to Folder 2]
@="Назначить выбранный значок папке"
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\icofile\shell\Attach Icon to Folder 2\command]
@=hex(2):22,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,\
  00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,77,00,\
  73,00,63,00,72,00,69,00,70,00,74,00,2e,00,65,00,78,00,65,00,22,00,20,00,22,\
  00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,\
  73,00,25,00,5c,00,41,00,74,00,74,00,61,00,63,00,68,00,20,00,49,00,63,00,6f,\
  00,6e,00,20,00,74,00,6f,00,20,00,46,00,6f,00,6c,00,64,00,65,00,72,00,5c,00,\
  41,00,74,00,74,00,61,00,63,00,68,00,20,00,49,00,63,00,6f,00,6e,00,20,00,74,\
  00,6f,00,20,00,46,00,6f,00,6c,00,64,00,65,00,72,00,20,00,32,00,2e,00,76,00,\
  62,00,73,00,22,00,20,00,22,00,25,00,31,00,22,00,00,00

Назначает указанный скрипт контекстному меню ico-файла.

BOBAT 13-08-2018 10:00 2826143

Большое спасибо!!! Всё работает, но есть один нюанс (вариант первый, привязка к папке): если изначально иконка в папке не совпадает с названием папки, то всё работает - иконка переименовывается и создаётся desktop.ini если его нет, если он есть - то перезаписывается, но если название иконки уже совпадает с названием папки, то иконка НЕ переименовывается, а выводится сообщение об ошибке

и и после нажатия на кнопку ОК desktop.ini НЕ создаётся, можно ли сделать, чтобы эта ошибка не появлялась, иконка независимо от её названия всё равно переименовывалась и desktop.ini создавался. Заранее спасибо
И вот ещё что. Раньше мне приходилось заходить в папку, переименовывать значок, потом находясь в этой же папке нажимать пкм и выбирать назначить значок этой папке, теперь, когда значок переименовывается автоматически, можно ли изменить модель запуска - не заходить в папку, а прямо нажимать на папке и выбирать Назначить иконку этой папке, и vbs определит название папки, переименует иконку внутри папки и там же создаст desktop.ini и скроет оба файла? А в случае отсутствия значка в папке ничего не делать?

BOBAT 13-08-2018 11:07 2826154

И ещё прошу Вашей помощи.После все наших манипуляций с папками и файлами все файлы в папке создаются, атрибуты к файлам и папке выставлены правильно, но иконка на папке не меняется, или может поменяться через какое то время, или так и остаться стандартным видом. Но если, например, переименовать desktop.ini а потом отменить переименование, то иконка меняется сразу.Причём влияет, как я прочитал в интернете, только именно ручное переименование.
Предлагают использовать функцию shell, которая будет уведомлять обо всех запущенных обозревателях окна, чтобы использовать обновленный desktop.ini. Этот API отображается в VBScript через Shell.Application.NameSpace( "папка\" )
Код:

for /r %%I in (*.ico) do (
    attrib -h -s -r "%temp%\desktop.ini" >nul
    (
        echo [.ShellClassInfo]
        echo IconResource="%%~nxI",0
    )>"%temp%\desktop.ini"
    attrib +h +s "%temp%\desktop.ini"
    (
        echo set shell = CreateObject^("Shell.Application"^)
        echo set folder = shell.NameSpace^("%%~dpI"^)
        echo folder.MoveHere "%temp%\desktop.ini", 4+16+1024
    )>"%temp%\updateIcon.vbs"
    cscript //nologo //b "%temp%\updateIcon.vbs"
)

Может быть Вы знаете, как применить иконку сразу после отработки vbs?

Iska 13-08-2018 12:55 2826172

Цитата:

Цитата BOBAT
но есть один нюанс (вариант первый, привязка к папке): если изначально иконка в папке не совпадает с названием папки, то всё работает - иконка переименовывается и создаётся desktop.ini если его нет, если он есть - то перезаписывается, но если название иконки уже совпадает с названием папки, то иконка НЕ переименовывается, а выводится сообщение об ошибке »

Странно, я думал, что обновил код в сообщении. Оказалось, что нет, остался старый вариант, без проверки.

Замените:
Код:

                                objFile.Name = objFSO.GetBaseName(strSourceFolder) & ".ico"
на:
Код:

                                If Not StrComp(objFile.Name, objFSO.GetBaseName(strSourceFolder) & ".ico", vbTextCompare) = 0 Then
                                        objFile.Name = objFSO.GetBaseName(strSourceFolder) & ".ico"
                                End If

Цитата:

Цитата BOBAT
можно ли изменить модель запуска - не заходить в папку, а прямо нажимать на папке и выбирать Назначить иконку этой папке, и vbs определит название папки, переименует иконку внутри папки и там же создаст desktop.ini и скроет оба файла? А в случае отсутствия значка в папке ничего не делать? »

Полагаю, можно. Но я остановлюсь на варианте с привязкой к ico-файлу, как наиболее разумном.

Цитата:

Цитата BOBAT
Но если, например, переименовать desktop.ini а потом отменить переименование, то иконка меняется сразу.Причём влияет, как я прочитал в интернете, только именно ручное переименование. »

Дело не в переименовании, а в уведомлении приложения об изменениях.

Цитата:

Цитата BOBAT
Предлагают использовать функцию shell, которая будет уведомлять обо всех запущенных обозревателях окна, чтобы использовать обновленный desktop.ini. Этот API отображается в VBScript через Shell.Application.NameSpace( "папка\" )
Код:


echo folder.MoveHere "%temp%\desktop.ini", 4+16+1024

»

Не нравится мне это. И потому что тянем разрешения на файл из %temp%, и сама надежда на то, что Проводник получит таким макаром уведомление…

Цитата:

Цитата BOBAT
Может быть Вы знаете, как применить иконку сразу после отработки vbs? »

Ага. Отослать соответствующее сообщение всем окнам Проводника верхнего уровня. Токмо WSH этого делать не умеет :).

BOBAT 13-08-2018 13:23 2826179

Спасибо большое!!

BOBAT 13-08-2018 14:19 2826187

Цитата:

Цитата Iska
Отослать соответствующее сообщение всем окнам Проводника верхнего уровня. Токмо WSH этого делать не умеет . »

А какая программа это умеет? Может просто вставить её с параметрами в конец vbs и она отработает?

Iska 13-08-2018 14:40 2826192

BOBAT, не «программа». Любой язык высокого уровня, работающий с WinAPI. И даже некоторые из скриптовых, например, PowerShell, AutoIt, AutoHotKey.

BOBAT 13-08-2018 18:46 2826230

Iska, подскажите, пожалуйста, как точно называется эта команда-скрипт, наверное на Autoit или AutoHotKey смогу разобраться и сделать скрипт

Iska 13-08-2018 19:10 2826235

Раньше хватало широковещательной рассылки WM\_SETTINGCHANGE message | Microsoft Docs. Но рекомендуется SHChangeNotify function | Microsoft Docs.

BOBAT 14-08-2018 06:28 2826299

Спасибо


Время: 14:51.

Время: 14:51.
© OSzone.net 2001-