UNPKG

cejs

Version:

A JavaScript module framework that is simple to use.

303 lines (260 loc) 10.9 kB
/** * @name CeL function for executing program * @fileoverview 本檔案包含了 executing program 的 functions。 * @since */ 'use strict'; // 'use asm'; // -------------------------------------------------------------------------------------------- // 不採用 if 陳述式,可以避免 Eclipse JSDoc 與 format 多縮排一層。 typeof CeL === 'function' && CeL.run({ // module name name : 'application.OS.Windows.execute', require : 'application.OS.Windows.new_COM' // + '|application.OS.Windows.is_COM', // 設定不匯出的子函式。 // no_extend : '*', // 為了方便格式化程式碼,因此將 module 函式主體另外抽出。 code : module_code }); function module_code(library_namespace) { // requiring var new_COM = this.r('new_COM'), is_COM = this.r('is_COM'); /** * null module constructor * * @class executing program 的 functions */ var _// JSDT:_module_ = function() { // null module constructor }; /** * for JSDT: 有 prototype 才會將之當作 Class */ _// JSDT:_module_ .prototype = {}; /** * @see also: application.OS.Windows.file.show_in_file_manager() * * <code> 2008/8/8 18:29:44 run them with administrator rights runs under administrator privileges. 帳戶控制 Windows Vista:使用軟體限制原則對抗未授權的軟體 http://www.microsoft.com/taiwan/technet/windowsvista/security/rstrplcy.mspx http://4sysops.com/archives/vista%E2%80%99s-uac-how-to-elevate-scripts-vbscript-and-jscript/ http://blogs.msdn.com/aaron_margosis/archive/2007/07/01/scripting-elevation-on-vista.aspx Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA c:\windows\system32\control.exe /name Microsoft.UserAccounts http://www.dashken.net/index.php?/archives/280-VBScript-Check-if-OS-is-Vista-and-Vistas-UAC-status.html http://msdn.microsoft.com/en-us/magazine/cc163486.aspx HKEY_LOCAL_MACHINESOFTWARE MicrosoftWindowsCurrentVersionPoliciesSystem\ConsentPromptBehaviorAdmin http://hsu.easynow.com.tw/index.php?load=read&id=28 http://vistavitals.blogspot.com/2008/02/logon-scripts-token-effort.html runas http://www.merawindows.com/Forums/tabid/324/forumid/82/postid/32458/scope/posts/Default.aspx http://www.winhelponline.com/articles/185/1/VBScripts-and-UAC-elevation.html http://forums.techarena.in/vista-security/654643.htm Set objShell = CreateObject("Shell.Application") Set objFolder = objShell.Namespace("C:\") Set objFolderItem = objFolder.ParseName("myhta.hta") objFolderItem.InvokeVerb "runas" var WinShell=new ActiveXObject("Shell.Application"),p=location.pathname.replace(/[^\\]+$/,''),o=WinShell.Namespace(p).ParseName(location.pathname.slice(p.length)); o.InvokeVerb("runas"); http://www.zaoxue.com/article/tech-28339_2.htm http://www.lob.cn/vbs/20071126203237.shtml TODO: 對 prompt 回應不允許時的處理: 若想在受限的情況下使用? 不使用自訂程式 http://msdn.microsoft.com/en-us/library/bb776820(VS.85).aspx 有時執行完就無消息,得多執行幾次。 </code> */ function runas(path) { if (!path) path = typeof WScript === 'object' ? WScript.ScriptFullName : unescape(location.pathname); var host = { js : 'wscript.exe', vbs : 'wscript.exe', hta : 'mshta.exe' }, extension = path.match(/([^.]+)$/); host = extension && ((extension = extension[1].toLowerCase()) in host) ? host[extension] : ''; // 判斷是否有權限 if (!registryF.checkAccess('HKLM\\SOFTWARE\\')) { // 以管理者權限另外執行新的. // It will get the UAC prompt if this feature is not disabled. new ActiveXObject("Shell.Application").ShellExecute(host || path, host ? path : '', '', 'runas'/* ,5 */); // 執行完本身則退出: bug: 有時執行完就無消息,得多執行幾次。 if (typeof WScript === 'object') WScript.Quit(); else if (typeof window === 'object') window.close(); } } // run_command[generateCode.dLK]='initialization_WScript_Objects'; /** * 執行 command。<br /> * JScript file: check owner, .exe file.<br /> * * TODO:<br /> * run_command([path, Verb],3): use Shell.Application InvokeVerb<br /> * run_command([path, arg1, arg2,..]): use Shell.Application.ShellExecute<br /> * set timeout.<br /> * cd. WshShell.Run('%COMSPEC% /K ' + ドライブ +' | cd /D '+ パス);// cd * で他ドライブへ移れないので。 * * @example <code> // usage: // use <a href="http://msdn.microsoft.com/en-us/library/ateytk4a.aspx" accessdate="2012/11/7 18:30" title="Exec Method (Windows Script Host)">WshShell.Exec</a>, // return [ExitCode, StdOut, StdErr]. run_command(command); // use <a href="http://msdn.microsoft.com/en-us/library/ateytk4a.aspx" accessdate="2012/11/7 18:30" title="Exec Method (Windows Script Host)">WshShell.Exec</a>, // run callback.call(WshScriptExec Object, ExitCode, StdOut, StdErr) when done. run_command(command, function callback(){}); // use <a href="http://msdn.microsoft.com/en-us/library/d5fk67ky.aspx" accessdate="2012/11/7 18:30" title="Run Method (Windows Script Host)">WshShell.Run</a> run_command([strCommand, [intWindowStyle 0-10], [bWaitOnReturn false: nowait & return 0, true: wait & return error code]]); // use WshRemote run_command(script path, remote computer) // use WMI run_command(command, remote computer) * </code> * * @param {String}command * @param {Function|String}[option] * @param {String}remoteserver * @returns * * @see <a * href="http://www.microsoft.com/taiwan/technet/scriptcenter/resources/qanda/nov04/hey1115.mspx">我能使用指令碼鎖定工作站嗎?</a> */ function run_command(command, callback, remoteserver) { library_namespace.debug('Run command: [' + command + ']', 1, 'run_command'); var process; try { if (!remoteserver) if (is_COM(process = new_COM('WScript.Shell'))) if (Array.isArray(command)) { // WshShell.Run(command, [WindowStyle 0-10], // [WaitonReturn false: nowait & return 0, true: wait & // return error code]) library_namespace.debug('using WshShell.Run()', 2); // return process.Run.apply(null, command); var length = command.length; return length > 2 ? process.Run(command[0], command[1], command[2]) : // length > 1 ? process.Run(command[0], command[1]) : // process.Run(command[0]); if (typeof callback === 'function') callback(); } else { // WshShell.Exec(), objFolderItem.InvokeVerb() library_namespace.debug('using WshShell.Exec()', 2); process = process.Exec(command); // 預防要輸入密碼。 process.StdIn.Close(); if (typeof WScript !== 'object') { if (typeof callback === 'function') run_command.waiting.call({ StdOut : [], StdErr : [] }, process, callback); return; } while (process.Status === 0) WScript.Sleep(100); if (typeof callback === 'function') callback.call(process, process.ExitCode, process.StdOut.ReadAll(), process.StdErr .ReadAll()); else return [ process.ExitCode, process.StdOut.ReadAll(), process.StdErr.ReadAll() ]; } else { library_namespace.error('No COM get!'); return; } if (/^[^ ]+\.(js|vbs)$/i.test(command) && is_COM(process = new_COM('WSHController'))) { process = process.CreateScript(command, remoteserver); // TODO // http://msdn.microsoft.com/en-us/library/d070t67d(v=vs.84).aspx process.Execute(); // <a // href="http://msdn.microsoft.com/en-us/library/9z4dddwa.aspx" // accessdate="2012/11/7 18:55">Status Property (WshRemote)</a>. // [NoTask, Running, Finished] while (process.Status !== 2) WScript.Sleep(100); return callback.call(process); } // TODO process = GetObject("winmgmts:{impersonationLevel=impersonate}//" + (remoteserver || '.') + "/root/cimv2:Win32_Process"); if (false) if (/^[^ ]+\.(j|vb)s$/i.test(command)) command = "wscript.exe " + command; // Create 方法會讓這個指令碼在「遠端電腦」上執行。 return process.Create(command/* , null, null, intProcessID */); } catch (e) { library_namespace.error(e); return e; } finally { process = null; } } // <a href="http://msdn.microsoft.com/en-us/library/2f38xsxe.aspx" // accessdate="2012/11/8 18:47">WshScriptExec Object</a> run_command.waiting = function(process, callback) { // <a // href="http://us.generation-nt.com/answer/wsh-exec-hangs-getting-stdout-readall-command-line-winzip-help-59169522.html" // accessdate="2012/11/8 19:12">Answer : Wsh.exec hangs getting // StdOut.ReadAll from command line Winzip</a>. // <a href="http://support.microsoft.com/kb/960246" // accessdate="2012/11/8 19:44">Hang When Reading StdErr/StdOut // Properties of WshScriptExec Object</a> // 因為 <a href="http://msdn.microsoft.com/en-us/library/312a5kbt.aspx" // accessdate="2012/11/8 19:32">TextStream Object</a> 的 buffer size // limit 為 4KB,超過後 .ReadAll() 便會 hangs (deadlock),因為 .ReadAll() 會等 // EndOfStream character。只好盡可能快點讀出。 // 當程式輸出過快時,仍可能來不及讀,只能使用 output 至檔案的方法。 while (!process.StdOut.AtEndOfStream) this.StdOut.push(process.StdOut.Read(4096)); while (!process.StdErr.AtEndOfStream) this.StdErr.push(process.StdErr.Read(4096)); library_namespace.debug('process status: [' + process.Status + ']<br />\nStdOut: [' + this.StdOut + '],<br />\nStdErr: [' + this.StdErr + ']', 3, 'run_command.waiting'); if (process.Status === 0) { // The job is still running. // DoEvent. // TODO: set timeout. setTimeout(run_command.waiting.bind(this, process, callback), 0); return; } try { library_namespace.debug('run callback [' + callback + '].', 3, 'run_command.waiting'); // if (typeof callback === 'function') callback.call(process, process.ExitCode, this.StdOut.join(''), this.StdErr.join('')); } catch (e) { library_namespace .warn('run_command.waiting: fault to run callback [' + callback + '].'); library_namespace.error(e); } finally { process = null; } }; // Unicode pipe run_command.Unicode = function(command, callback, remoteserver) { command = '%COMSPEC% /U /C "' + command + '"'; return run_command(command, callback, remoteserver); }; _.run_command = run_command; return (_// JSDT:_module_ ); }