如何使用JScript创建使用“以管理员身份运行”的快捷方式

时间:2012-06-22 19:23:04

标签: com activex shortcut jscript wsh

我有一个使用cscript.exe运行的JScript脚本。它在桌面(以及开始菜单)中创建一个快捷方式,该快捷方式使用参数运行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”,因此我无法使用清单进行升级。我理论上可能会在windows目录中安装一个cscript.exe.manifest,但即使这样可行,但由于明显的原因,这将是一个可怕的想法。

我也不想使用虚拟脚本,因为这是一个需要处理的额外文件,并且还有另一个看似合理的解决方案:检查快捷方式上的“以管理员身份运行”框。

三十秒的调查显示WScript.Shell ActiveX对象没有此所需的接口。另外的调查显示IShellLinkDataList可以。但是,IShellLinkDataList是一个通用的COM接口。我在互联网上看到几个例子,大多数链接here。但是,所有示例都是在编译代码(C ++,C#,甚至是JScript.NET)中完成的。我非常希望能够直接在JScript中进行,从cscript.exe运行。

那就是说,我完全是出于我没想到的想法或其他解决方案。

1 个答案:

答案 0 :(得分:5)

将快捷方式文件标记为需要提升的官方方法是IShellLinkDataList。从自动化环境中使用该接口很困难。

但是,如果你对hack很满意,你可以在脚本中完成它,只需在.lnk文件中翻一下即可。

勾选"以管理员身份运行"在“外壳属性”框的“高级”选项卡中,或者当use IShellLinkDataList to set the flags包含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));

PS:

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();
}