Как я могу использовать JScript для создания ярлыка, который использует "Запуск от имени администратора"

У меня есть сценарий JScript, который работает с cscript.exe, Он создает ярлык на рабочем столе (и в меню "Пуск"), который запускается cscript.exe с параметрами для запуска другого скрипта JScript. В соответствующей части это выглядит так:

function create_shortcut_at(folder, target_script_folder)
{
    var shell = new ActiveXObject("WScript.Shell");
    var shortcut = shell.CreateShortcut(folder + "\\Run The Script.lnk");
    shortcut.TargetPath = "cscript";
    shortcut.Arguments = "\""+target_script_folder+"\\script.js\" /aParam /orTwo";
    shortcut.IconLocation = target_script_folder+"\\icon.ico";
    shortcut.Save();
}

Это называется как create_shortcut_at(desktop_folder, script_folder),

И это работает, насколько это возможно. Он создает значок на рабочем столе, указывающий правильно на сценарий, и запускает его при двойном щелчке. Проблема в том, что ему действительно нужно запускать скрипт "от имени администратора".

И скрипт действительно должен запускаться "как администратор" - он устанавливает приложения (для всех пользователей) и перезагружает компьютер. (Для тех, кто интересуется, скрипт wpkg.js. Изменение его в самостоятельное повышение нежелательно.)

Поскольку целью ярлыка является "cscript.exe", я не могу использовать манифест для эскалации. Вероятно, я теоретически мог бы установить cscript.exe.manifest в каталог windows, но даже если бы это работало, это было бы ужасной идеей по очевидным причинам.

Я также предпочел бы не использовать фиктивный сценарий, так как это дополнительный файл для работы, и есть другое, на первый взгляд, разумное решение под рукой: установите флажок "Запуск от имени администратора" на ярлыке.

Тридцать секунд исследования показывают, что объект ActiveX WScript.Shell не имеет интерфейсов, необходимых для этого. Дополнительное исследование предполагает, что IShellLinkDataList делает. Тем не менее, IShellLinkDataList является универсальным интерфейсом COM. Я вижу несколько примеров в Интернете, большинство ссылок здесь. Однако все примеры делают это в скомпилированном коде (C++, C#, даже JScript.NET). Я предпочитаю делать это напрямую в JScript, используя cscript.exe,

Тем не менее, я все за идеи, которые я не рассматривал, или другие решения.

1 ответ

Решение

Официальный способ пометить файл ярлыка как требующий повышения - через IShellLinkDataList, Трудно использовать этот интерфейс из среды автоматизации.

Но, если вы довольны взломом, вы можете сделать это в скрипте, просто щелкнув немного в файле.lnk.

При установке флажка "Запуск от имени администратора" на вкладке "Дополнительно" в окне "Свойства оболочки" или при использовании IShellLinkDataList для установки флажков SLDF_RUNAS_USERвы просто устанавливаете один бит в файле.

Вы можете сделать это "вручную", не проходя через интерфейс COM. Это байт 21, и вам нужно установить бит 0x20.

(function(globalScope) {
    'use strict';
    var fso = new ActiveXObject("Scripting.FileSystemObject"),
        path = "c:\\path\\goes\\here\\Shortcut2.lnk",
        shortPath = path.split('\\').pop(),
        newPath = "new-" + shortPath;

    function readAllBytes(path) {
        var ts = fso.OpenTextFile(path, 1), a = [];
        while (!ts.AtEndOfStream)
            a.push(ts.Read(1).charCodeAt(0));
        ts.Close();
        return a;
    }

    function writeBytes(path, data) {
        var ts = fso.CreateTextFile(path, true),
            i=0, L = data.length;
        for (; i<L; i++) {
            ts.Write(String.fromCharCode(data[i]));
        }
        ts.Close();
    }

    function makeLnkRunAs(path, newPath) {
        var a = readAllBytes(path);
        a[0x15] |= 0x20; // flip the bit. 
        writeBytes(newPath, a);
    }

    makeLnkRunAs(path, newPath);

}(this));

пс:

function createShortcut(targetFolder, sourceFolder){
    var shell = new ActiveXObject("WScript.Shell"),
        shortcut = shell.CreateShortcut(targetFolder + "\\Run The Script.lnk"),
        fso = new ActiveXObject("Scripting.FileSystemObject"),
        windir = fso.GetSpecialFolder(specialFolders.windowsFolder);

    shortcut.TargetPath = fso.BuildPath(windir,"system32\\cscript.exe");
    shortcut.Arguments = "\"" + sourceFolder + "\\script.js\" /aParam /orTwo";
    shortcut.IconLocation = sourceFolder + "\\icon.ico";
    shortcut.Save();
}
Другие вопросы по тегам