2012-06-22 37 views
6

cscript.exeを使用して実行するJScriptスクリプトがあります。それは、cscript.exeを実行し、別のJScriptスクリプトを実行するためのパラメータを持つデスクトップ(およびスタートメニュー)にショートカットを作成します。関連する部分では次のようになります: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をインストールすることができますが、それが機能したとしても、それは明らかな理由のためにひどい考えです。

ダミースクリプトを使用しない方が良いでしょう。それは対処する余分なファイルで、一見合理的な解決策があります。ショートカットの[管理者として実行]チェックボックスをオンにします。

30秒間の調査の結果、WScript.Shell ActiveXオブジェクトにはこのために必要なインターフェイスがないことが明らかになりました。追加の調査では、IShellLinkDataListが行うことを示しています。ただし、IShellLinkDataListは汎用COMインターフェイスです。私はインターネットの周りにいくつかの例を見ています。ほとんどの例はhereです。しかし、すべての例では、コンパイルされたコード(C++、C#、さらにはJScript.NET)でそれを行います。私は、JScriptで直接cscript.exeから実行できるようにすることを大いに好んでいます。

私は、私が考えなかったアイデアや他の解決策だと言いました。

答えて

4

ショートカットファイルを標高を必要とする公式の方法は、IShellLinkDataListです。そのインターフェースをオートメーション環境から使用するのは難しいです。

しかし、ハッキングに満足している場合は、.lnkファイルのビットを反転するだけでスクリプトで実行できます。

シェルプロパティボックスの[詳細設定]タブで[管理者として実行]チェックボックスをオンにした場合、またはuse IShellLinkDataList to set the flagsSLDF_RUNAS_USERを含めると、基本的にファイルに1ビットしか設定されません。

「手動で」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(); 
} 
+0

このソリューションを必要とする将来の人々を助けるために、.LNKフォーマットはここで指定されていますhttp://msdn.microsoft.com/en-us/library/dd871305( v = prot.13)。特に、これはhttp://msdn.microsoft.com/en-us/library/dd891314(v=prot.13)を使用しています。非常に賢い解決、ありがとう! – alficles

関連する問題