Пожалуй, многие знают, что Windows начиная с версии 98 имеет по умолчанию в своем составе Windows Script Host (WSH), который позволяет исполнять скрипты на языках VBScript и JScript, но далеко не каждый хотя бы раз пользовался этой возможностью. В этой статье я приведу примеры полезных сниппетов и скриптов для WSH и попробую убедить вас в том, что вещь это действительно стоящая. Я также расскажу об очень занимательных и полезных возможностях WSH, о которых практически никто не знает, и информацию о которых в интернете найти весьма непросто.
Для начала немного о языках, поддерживающихся WSH. JScript - это, по сути, JavaScript с несколько измененной объектной моделью (например, в нем нет объекта window, как в браузерах, зато добавлен объект WScript, позволяющий взаимодействовать со средой, в которой исполняется скрипт). VBScript базируется на синтаксисе и возможностях Visual Basic 6 (и, возможно, более ранних версий). Оба языка имеют приблизительно одинаковые возможности. Кроме того, можно установить и другие языки для WSH, например, PerlScript, который, как вы уже догадались, базируется на Perl'е. Для этого следует воспользоваться, например, инсталлятором ActiveState Perl:
В Windows по умолчанию расширение файла .js ассоциировано с JScript-скриптами, .vbs - с VBScript. При установке PerlScript появляется ассоциация .pls - с PerlScript-скриптами. Скрипты js и vbs можно закодировать с помощью утилиты от Microsoft screnc.exe, получив на выходе файл с расширением .jse или .vbe, соответственно. К сожалению, такое кодирование защитит лишь от неопытных пользователей - множество раскодировщиков можно найти в Google. Кроме того, при закодировании бывают проблемы с русским текстом.
Еще одной замечательной особенностью WSH является то, что он позволяет комбинировать все установленные в системе скриптовые языки в одном файле с расширением .wsf. Например, VBScript предоставляет функцию, отображающую окошко для ввода текста (InputBox), и она вам очень нужна, но скрипт свой вы пишете на JScript, который такой функцией не располагает. Решается проблема очень просто - создать файл wsf со следующим содержанием:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="windows-1251"?> <job id="MyTestJob"> <script language="VBScript"> <![CDATA[ Function WSHInputBox(Message, Title, Value) WSHInputBox = InputBox(Message, Title, Value) End Function ]]> </script> <script language="JScript"> <![CDATA[ //Ваш код на JS var name = WSHInputBox("Введите ваше имя:", "Запрос", "Вася Пупкин"); WScript.Echo("Имя: " + name); ]]> </script> </job> |
Таким же образом можно скомбинировать, например, JScript и PerlScript, если PerlScript у вас установлен:
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 |
<?xml version="1.0" encoding="windows-1251"?> <job id="MyTestJob"> <script language="PerlScript"> <![CDATA[ use strict; our $WScript; use LWP::UserAgent; sub do_request { my $lwp = new LWP::UserAgent; my $response = $lwp->get($_[0]); if($response->is_success) { return $response->headers->as_string; } else { return $response->error_as_HTML; } } ]]> </script> <script language="JScript"> <![CDATA[ WScript.Echo(do_request("http://ya.ru")); ]]> </script> </job> |
Небольшое отступление - расскажу о запуске скриптов для WSH. По двойному клику мышкой они по умолчанию запускаются с помощью программы wscript.exe. В этом случае все вызовы WScript.Echo транслируются в обычные messagebox'ы. Если вы используете скрипт для автоматизации какого-либо процесса, например, сборки какого-либо проекта, и желаете выводить множество сообщений, то следует скрипт запускать с помощью программы cscript.exe, которая обращения к WScript.Echo транслирует в выводы в консоль. Запустить скрипт в консольном варианте можно, создав bat-файл с примерно таким содержимым:
1 2 3 |
@echo off cscript my_script.wsf [параметры] pause |
Можно также кликнуть на файле скрипта и вызвать меню "Open with command prompt".
Возможно, я кого-то удивлю, если скажу, что из скриптов для WSH можно с легкостью использовать классы .NET! Приведу пример на JScript (js-файл):
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 |
function vote_form() { //Создаем объект формы и всякие контролы this.form = WScript.CreateObject("System.Windows.Forms.Form"); this.radioButton1 = WScript.CreateObject("System.Windows.Forms.RadioButton"); this.radioButton2 = WScript.CreateObject("System.Windows.Forms.RadioButton"); this.radioButton3 = WScript.CreateObject("System.Windows.Forms.RadioButton"); this.radioButton4 = WScript.CreateObject("System.Windows.Forms.RadioButton"); this.button1 = WScript.CreateObject("System.Windows.Forms.Button"); this.button2 = WScript.CreateObject("System.Windows.Forms.Button"); this.linkLabel1 = WScript.CreateObject("System.Windows.Forms.LinkLabel"); //Настраиваем контролы with(this.radioButton1) { Parent = this.form; Checked = true; Left = 12; Top = 12; Width = 110; Height = 17; TabStop = true; Text = "VBScript"; } with(this.radioButton2) { Parent = this.form; Left = 12; Top = 35; Width = 110; Height = 17; TabStop = true; Text = "JScript"; } with(this.radioButton3) { Parent = this.form; Left = 12; Top = 58; Width = 110; Height = 17; TabStop = true; Text = "PerlScript"; } with(this.radioButton4) { Parent = this.form; Left = 12; Top = 81; Width = 110; Height = 17; TabStop = true; Text = "Единая Россия"; } with(this.button1) { Parent = this.form; Left = 12; Top = 112; Width = 85; Height = 23; Text = "Да!"; DialogResult = 1; } with(this.button2) { Parent = this.form; Left = 125; Top = 112; Width = 85; Height = 23; Text = "Идите вы!"; DialogResult = 0; } with(this.linkLabel1) { Parent = this.form; Left = 167; Top = 9; Width = 45; Height = 15; Text = "kaimi.io"; } //настраиваем форму with(this.form) { Width = 222; Height = 125; Text = "Какой язык вам больше по душе?"; AutoSize = true; FormBorderStyle = 5; //FixedToolWindow CancelButton = this.button1; CancelButton = this.button2; } //Отобразить форму и вернуть true, если пользователь нажал на первую кнопку this.show = function() { this.form.ShowDialog(); return this.form.DialogResult == 1; }; //Получить выбранный результат (см. выше, на форме 4 radio button'а) this.result = function() { if(this.radioButton1.Checked) return this.radioButton1.Text; else if(this.radioButton2.Checked) return this.radioButton2.Text; else if(this.radioButton3.Checked) return this.radioButton3.Text; else if(this.radioButton4.Checked) return this.radioButton4.Text; }; }; //Создаем форму var my_form = new vote_form; //Предлагаем пользователю сделать выбор while(true) { if(my_form.show()) { WScript.Echo("Вы выбрали: " + my_form.result()); break; } else { WScript.Echo("Ну как же так, надо же выбрать!"); } } |
Выполнив этот скрипт, увидим такую форму:
И все это создано с помощью .NET-классов! Есть, правда, в этом некоторые сложности. Во-первых, я не нашел путей для взаимодействия с делегатами, которые используются при обработке событий в .NET. Во-вторых, не существует способа вызвать через CreateObject конструктор COM-объекта, принимающий параметры (это относится не только к .NET, кстати). В-третьих, по умолчанию в скриптах доступны лишь некоторые .NET-сборки и классы:
System.Collections.Queue
System.Collections.Stack
System.Collections.ArrayList
System.Collections.SortedList
System.Collections.Hashtable
System.IO.StringWriter
System.IO.MemoryStream
System.Text.StringBuilder
System.Random
С другой стороны, опубликовать .NET-сборку, чтобы она стала доступной через COM-интерфейсы (которые и используются в WSH), совсем несложно. Если вышеприведенный скрипт с Windows Forms у вас не заработал (что, скорее всего, так и есть), наберите в консоли команду:
1 |
%WINDIR%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe System.Windows.Forms.dll /codebase |
либо, если вы пользуетесь 64-битной операционной системой, то
1 |
%WINDIR%\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe System.Windows.Forms.dll /codebase |
Эта команда опубликует сборку System.Windows.Forms и она станет доступной через COM-интерфейсы, после чего вы сможете использовать классы из нее в скриптах. К сожалению, не все сборки можно зарегистрировать, а только те, которые имеют аттрибут ComVisible=true (если такой аттрибут у сборки есть, об этом говорится на соответствующих страницах с описанием сборки в MSDN).
Для отмены регистрации сборки выполните приведенную выше команду с ключом /unregister.
Что еще следует знать при использовании .NET-сборок? Часто классы в .NET имеют перегруженные функции с одинаковыми именами и разными типами и количеством параметров. Как вызывать их? Ведь переменные в скриптах практически не типизируются! Все очень просто. Например, возьмем класс System.Random. Он уже зарегистрирован по умолчанию и доступен из WSH. Но он имеет три метода с именем Next. Как вызвать нужный? .NET маппит имена одинаковых методов следующим образом: первый с конца в таблице методов имеет имя Next (в данном случае), следующий - Next_2, далее - Next_3. Где увидеть эту таблицу с правильным порядком функций? Например, в ildasm'е:
Здесь я открыл сборку mscorlib.dll из %WINDIR%\Microsoft.NET\Framework64\v2.0.50727, после чего зашел в неймспейс System и нашел класс Random в нем. Теперь ясно - если мы хотим воспользоваться методом Next, предоставляющим возможность указать минимальное и максимальное значение при генерации рандома, то следует вызвать Next_2 (так как этот метод второй с конца в списке методов Next, смотрите скриншот выше):
1 2 |
var random = WScript.CreateObject("System.Random"); WScript.Echo(random.Next_2(10, 20)); //выводим рандомное число в диапазоне от 10 до 20 |
Еще одной из интересных возможностей скриптов для WSH является поддержка drag-drop'а. На файлы .js, .vbs, .jse, .vbe, .wsf можно перетаскивать другие файлы, и их имена будут доступны через WScript.Arguments.
Итак, подведем итоги. Чем же примечательно написание скриптов на JScript, VBscript или PerlScript? Почему это лучше и проще bat-файлов или PowerShell'а?
[+] Вы сами выбираете знакомый любимый синтаксис. Предпочитаете JavaScript - пишите на нем, обожаете Visual Basic - тогда VBScript для вас!
[+] Вы можете комбинировать эти языки в одном скрипте, тем самым дополняя возможности одного языка фичами другого.
[+] Вам доступны все стандартные особенности выбранного языка. Поддержка выполнения внешних программ, работа с текстовыми и двоичными файлами, регулярные выражения и многое другое прилагается. Поддержка работы с файлами по маске, с сетевыми путями (samba, например) - тоже.
[+] Вы можете использовать множество зарегистрированных COM-классов.
[+] Вы можете использовать многие COM-Visible .NET-сборки.
[+] Вы можете работать с WMI, так как он доступен через COM.
[+] Имеется полная поддержка Unicode, достаточно сохранить файл как Unicode Little Endian.
Масса очевиднейших плюсов. На WSH можно писать мощнейшие приложения и скрипты, которые облегчат вам жизнь и сделают какие-то полезные задачи автоматически.
Сейчас мне остается лишь привести несколько полезных сниппетов, которые пригодятся вам, если вы решите использовать WSH для написания скриптов, производящих автоматическую сборку проектов/парсинг/работу с файлами и т.д. Для примера я буду использовать свой любимый JScript, потому что он имеет наиболее привычный синтаксис и будет понятен большинству из вас. Кроме того, в JScript удобно перехватывать исключения, которые могут быть выброшены функциями COM-классов и объекта WScript, с помощью try-catch. Можно и самим бросать исключения (это штатная возможность языка JavaScript, и, разумеется, она есть в JScript).
1. Работаем с файловой системой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var fso = WScript.CreateObject("Scripting.FileSystemObject"); //Создаем объект, позволяющий работать с файловой системой fso.CopyFile("xx.txt", "yy.txt"); //копируем xx.txt в yy.txt fso.CopyFile("C:\\Test\\*.exe", "C:\\test2\\"); //копируем все exe-файлы из C:\Test в C:\test2 fso.DeleteFile("xx.txt"); //Удаляем xx.txt fso.DeleteFile("*.*"); //Удаляем все файлы из текущей папки if(!fso.FolderExists("C:\\Temp123")) fso.CreateFolder("C:\\Temp123"); //Создаем папку, если она не существует //Перечисляем имена всех подпапок на диске C: var folder = fso.GetFolder("C:\\"); if(folder) { var it = new Enumerator(folder.SubFolders); for(; !it.atEnd(); it.moveNext()) WScript.Echo(it.item().path); } |
2. Работаем с переменными окружения.
1 2 3 4 5 6 7 8 9 |
var shell = WScript.CreateObject("WScript.Shell"); WScript.Echo(shell.ExpandEnvironmentStrings("Windows folder: %WINDIR%")); //Получаем значение переменной окружения //Проверяем, установлена ли переменная окружения var check = "%VS100COMNTOOLS%"; if(shell.ExpandEnvironmentStrings(check) != check) WScript.Echo("У вас установлена Visual Studio 2010!"); else WScript.Echo("У вас нет Visual Studio 2010 :("); |
3. Выполнение внешних программ.
Выполнение программы с ожиданием ее завершения и получением кода возврата:
1 2 3 4 5 6 7 8 9 10 |
try { var shell = WScript.CreateObject("WScript.Shell"); var ret = shell.Run("calc.exe", 1, true); //Выполняем calc.exe WScript.Echo("Код возврата: " + ret); } catch(error) { WScript.Echo("Код ошибки: " + error.number + "\n" + error.description); } |
Выполнение внешней программы с перехватом ее вывода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
try { var shell = WScript.CreateObject("WScript.Shell"); var exec = shell.Exec("find.exe /?"); //Выполняем find.exe с параметром while(exec.Status == 0) //Ждем окончания выполнения команды WScript.Sleep(100); if(exec.ExitCode != 0) //Если произошла ошибка (обычно все консольные программы в случае ошибки возвращают ненулевое значение, но не всегда) throw new Error(exec.ExitCode, "Cannot execute command!"); var output = ""; if(!exec.StdOut.AtEndOfStream) output = exec.StdOut.ReadAll(); //Перехватываем вывод выполненной программы WScript.Echo("FIND.EXE help:\n\n" + output); } catch(error) { WScript.Echo("Код ошибки: " + error.number + "\n" + error.description); } |
Можно также вводить какие-либо данные в программу через Exec.StdIn.
4. Работаем с реестром Windows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var shell = WScript.CreateObject("WScript.Shell"); //Создаем в ветке HKCU\Software каталог Test123\WScriptTest. //Обратите внимание на то, что в конце пути я указал обратный слеш //Последний параметр - тип создаваемого значения - указывать необязательно. shell.RegWrite("HKCU\\Software\\Test123\\WScriptTest\\", 1, "REG_BINARY"); //Создаем в этом каталоге строковое значение shell.RegWrite("HKCU\\Software\\Test123\\WScriptTest\\myvalue", "xyz", "REG_SZ"); //Меняем значение тем же вызовом shell.RegWrite("HKCU\\Software\\Test123\\WScriptTest\\myvalue", "12345", "REG_SZ"); //Читаем записанное значение WScript.Echo("Записанное значение: " + shell.RegRead("HKCU\\Software\\Test123\\WScriptTest\\myvalue")); //Так как нельзя удалить каталог в реестре с вложенными каталогами, //удаляем сначала вложенный shell.RegDelete("HKCU\\Software\\Test123\\WScriptTest\\"); //А затем внешний shell.RegDelete("HKCU\\Software\\Test123\\"); |
5. Работаем с WMI.
Перечисляем все вложенные ключи реестра в заданной ветке:
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 |
//Необходимые константы для доступа к реестру var HKEY_CLASSES_ROOT = 0x80000000; var HKEY_CURRENT_USER = 0x80000001; var HKEY_LOCAL_MACHINE = 0x80000002; var HKEY_USERS = 0x80000003; var HKEY_CURRENT_CONFIG = 0x80000005; var locator = WScript.CreateObject("WbemScripting.SWbemLocator"); //Подключимся к WMI локального компьютера var server_conn = locator.ConnectServer(null, "root\\default"); //Получим доступ к реестру var registry = server_conn.Get("StdRegProv"); //Получим метод перечисления ключей var method = registry.Methods_.Item("EnumKey"); //Зададим параметры для вызова метода var input_params = method.InParameters.SpawnInstance_(); input_params.hDefKey = HKEY_CURRENT_USER; //Будем перечислять все ключи в этой ветке реестра input_params.sSubKeyName = "Software\\Microsoft\\Windows\\CurrentVersion\\"; //Выполняем метод перечисления ключей var output = registry.ExecMethod_(method.Name, input_params); var subkeys = output.sNames.toArray(); //Выводим полученные значения for(var key in subkeys) WScript.Echo(subkeys[key]); |
Такую вещь на VBScript можно сделать гораздо проще, как ни странно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const HKEY_CLASSES_ROOT = &H80000000 const HKEY_CURRENT_USER = &H80000001 const HKEY_LOCAL_MACHINE = &H80000002 const HKEY_USERS = &H80000003 const HKEY_CURRENT_CONFIG = &H80000005 'Получили доступ к локальному реестру через WMI Set registry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv") 'Перечислили имена ключей registry.EnumKey HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion", key_names 'Вывели их For i = 0 To UBound(key_names) WScript.Echo key_names(i) Next |
Выполнение запроса WMI (в этом примере - вывод всех аккаунтов на компьютере):
1 2 3 4 5 6 7 8 |
//Подключились к WMI локального компьютера (".") var root = GetObject("winmgmts:\\\\.\\root\\cimv2"); //Выполнили запрос на получение всех локальных аккаунтов на компьютере var items = root.ExecQuery("SELECT * FROM Win32_Account where LocalAccount = true and SIDType = 1"); //Вывели их имена и описания for(var it = new Enumerator(items); !it.atEnd(); it.moveNext()) WScript.Echo(it.item().Name + " - " + it.item().Description); |
На этом я закончу свое повествование. Думаю, если вы осилили эту статью до конца, вы осознали всю мощь и удобство скриптов для WSH и непременно воспользуетесь этой замечательной функциональностью Windows!
Для дальнейшего изучения могу посоветовать MSDN (там есть множество документации по WSH, и, конечно же, .NET и WMI), и Google (примеров скриптов для WSH там несчетное количество). Удачи в изучении!
Не смешная шутка кайми:))
0_о
Весьма интересная статья, никогда не думал, что в винде есть что то подобное. Почему-то думал, что вся автоматизация ограничивается .bat командами.
Действительно, очень интересно. Узнал много нового, так как до этого тоже юзал батники. Спасибо.
Вау! Удивил, как обычно. Спасибо.
>> Возможно, я кого-то удивлю, если скажу, что из скриптов для WSH можно с >>легкостью использовать классы .NET! Приведу пример на JScript (js-файл):
Не совсем понял как запустить этот скрипт в винде, с расширением js смог запустить только в Notepad++, js - файлы открываются у меня в редакторе, переименовал в wsр-но получил ошибку "Сценарий не указан"
У тебя, значит, Notepad++ имеет ассоциацию формата файлов js. По умолчанию они запускаются виндовой программой wscript.exe.
При запуске скрипта, загружающего форму - ошибка: "Не удаётся найти класс программируемых объектов с именем "System.Windows.Forms.Form"".
код - 80020009.
ОС Windows Vista.
Регистрация - %WINDIR%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe System.Windows.Forms.dll не помогает.
var form = new ActiveXObject("System.Windows.Forms.Form");//работает
var gridView = new ActiveXObject("System.Windows.Forms.DataGridView");//работает
var col = new ActiveXObject("System.Windows.Forms.DataGridViewColumn");//почему-то не работает :(
сборку зарегистрировал
Боюсь, делать сложные графические интерфейсы на скриптах с использованием COM - не лучшая идея. Из .NET далеко не все классы экспортируются в COM. Это можно узнать, открыв документацию и увидев строчку [ComVisibleAttribute(true)] перед объявлением класса - значит, такой класс экспортируется. А вот для DataGridViewColumn такой строчки нет, поэтому и не работает. Кроме того, .net-эвенты Вы через скрипты никак не реализуете.
Спасибо. Вот только не понятно, зачем делать видимым класс, который нельзя нормально использовать без дополнительных классов, которые почему-то невидимы.
на картинке шестерёнки не смогут крутиться
Не знаю поддерживаете ли вы эту тему. Просто у меня возникла проблема в написании скрипта.
Скрипт такого рода:
var WSHShell=WScript.CreateObject ("WScript.Shell");
WSHShell.Run ("C:\name.exe",0);
Запускаю его двойным щелчком, а он мне выдает:
Не удается найти указанный файл Код: 80070002
Что я не правильно сделал
WSHShell.Run ("C:\\name.exe",0);
Два обратных слэша надо. Иначе получается escape-последовательность "\n" - перевод строки.
Подскажите, как мне сделать отправку файла на почту?
А язык важен? Проще всего, вероятно, на Perl, если нужен именно WSH. А если не нужен, то, наверное, еще проще на PowerShell скрипт написать.
Добрый день! Подскажите пож-та, как можно управлять темами и дополнительными настройками Windows 7-XP(ПКМ НА МОЙ КОМПЬЮТЕР-СВОЙСТВА)? Необходимо убрать галки с некоторых доп. настроек-как можно это реализовать? перенести каталог TEMP НА диск С, и прописать его в системе автоматически? Перепрописать каталоги пользователя из C:\Users\Пользователь\Документы, загрузки рисунки, видео на D:\Documtnts, D:\Pictures, D:\Music итд? Как сменить тему на классическую, убрать эффекты итд?
клева
Скажите, с помощью этих скриптов можно, например, открыть Мозиллу Файрфокс, открыть страницу, сохранить страницу, отправить страницу на печать - а потом открыть другую страницу (ну, и так много раз)?
Не уверен. Нужно смотреть, предоставляет ли мозилла фаерфокс какие-либо возможности для внешнего взаимодействия с ней, чтобы это можно было использовать из скриптов. Вроде бы что-то такое было, но я уже не помню. А так, для подобных вещей есть Selenium.
Огромное спасибо за статью! Очень много чего нового и важного открыл для себя.
Вопрос такой:
Можно ли использовать закрытые классы, элементы управления (Windows.Forms) сборок .NET в не управляемом коде?
Может есть некие wrapperы или мосты?
Мое приложение позволяет подключать ActiveX элементы управления, работать с COM. Хочется взять .NET и работать с ним через COM, даже с теми объектами, которые COM-Visible(False)
Думаю, что com-visible(false) использовать все же не получится в скриптах. Если только самому писать сборку на .NET, которая обернет нужные фичи и сделает их доступными через COM.
А что имеется в виду под не управляемым кодом? Если это не скрипт, а какой-нибудь бинарник на C++, то использовать там компоненты из .NET возможно (будет mixed-сборка, где часть кода нативного, а часть - управляемого).
Так и делаю. Пишу сборку на C# (ActiveX/COM) которая по сути открывает то что закрыто. И главное это все работает!
Под неуправляемым кодом понимается приложение писаное на C++. Так и получается микс из управляемого и неуправляемого кода.
Просто я думал MS про такую связку думали и возможно даже есть нормальный Bridge. Но я встречал только платные рукодельные мосты...
Подскажите один момент, я вывел в эту форму , как в примере , но форме разместил не LinkLabel , а Label, но для Label не получается изменить размер шрифта. Это можно как то сделать?
Не уверен. Создать объект шрифта вряд ли получится (System.Drawing.Font, потому что его конструкторы принимают аргументы, а через WScript.CreateObject передать аргументы в конструктор не получится, насколько я знаю). Переопределить свойство FontHeight у самого лейбла тоже, скорее всего, не сработает, вот что на этот счет написано в MSDN: "The FontHeight property should not be set to any value other than the control's Font.Height value, or -1.".
Никто не подскажет, можно ли сделать с помощью WSH так, чтобы при выборе RadioButton форма закрывалась?
Здравствуйте.
Можно ли создать скрипт для вызова из контекстного меню в любой папке, чтобы в этой папке менялся тип группировки и сортировки файлов на заранее заданный? Если да - то как? Спасибо.
Не уверен, что это возможно. Думаю, что без расширения для explorer'а тут не обойтись. Но так как я такие расширения не писал и не в курсе, как они работают, точно не скажу, можно ли использовать скрипты для их реализации.
конечно интересный геморой, прикольно, годиться для мелких автоматизаций, а вот для серьёзных и сложных проектов нет. Проще скомпилить в Python скрипт с использованием eel