Is there a way of Creating lnk file using javascript
我想让我网站上的用户能够下载" lnk"文件。
我的想法是生成包含一个只能使用一次的地址的文件。
有没有办法在javascript中生成此文件?
流程类似于-
在客户端的javascript中是否可以执行类似的操作?还是我需要使用Java服务器端生成此文件?
这是mslink.sh的忠实翻译。
我只在Windows 8.1中测试了答案,但我认为它也可以在Windows的较早版本中使用。
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 | function create_lnk_blob(lnk_target) { function hex_to_arr(s) { var result = Array(s.length / 2); for (var i = 0; i < result.length; ++i) { result[i] = +('0x' + s.substr(2*i, 2)); } return result; } function str_to_arr(s) { var result = Array(s.length); for (var i = 0; i < s.length; ++i) { var c = s.charCodeAt(i); if (c >= 128) { throw Error("Only ASCII paths are suppored :-("); } result[i] = c; } return result; } function convert_CLSID_to_DATA(s) { var idx = [[6,2], [4,2], [2,2], [0,2], [11,2], [9,2], [16,2], [14,2], [19,4], [24,12]]; var s = idx.map(function (ii) { return s.substr(ii[0], ii[1]); }); return hex_to_arr(s.join('')); } function gen_IDLIST(s) { var item_size = (0x10000 + s.length + 2).toString(16).substr(1); return hex_to_arr(item_size.replace(/(..)(..)/, '$2$1')).concat(s); } var HeaderSize = [0x4c, 0x00,0x00,0x00], LinkCLSID = convert_CLSID_to_DATA("00021401-0000-0000-c000-000000000046"), LinkFlags = [0x01,0x01,0x00,0x00], // HasLinkTargetIDList ForceNoLinkInfo FileAttributes_Directory = [0x10,0x00,0x00,0x00], FileAttributes_File = [0x20,0x00,0x00,0x00], CreationTime = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], AccessTime = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], WriteTime = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], FileSize = [0x00,0x00,0x00,0x00], IconIndex = [0x00,0x00,0x00,0x00], ShowCommand = [0x01,0x00,0x00,0x00], //SW_SHOWNORMAL Hotkey = [0x00,0x00], // No Hotkey Reserved = [0x00,0x00], Reserved2 = [0x00,0x00,0x00,0x00], Reserved3 = [0x00,0x00,0x00,0x00], TerminalID = [0x00,0x00], CLSID_Computer = convert_CLSID_to_DATA("20d04fe0-3aea-1069-a2d8-08002b30309d"), CLSID_Network = convert_CLSID_to_DATA("208d2c60-3aea-1069-a2d7-08002b30309d"), PREFIX_LOCAL_ROOT = [0x2f], PREFIX_FOLDER = [0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], PREFIX_FILE = [0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], PREFIX_NETWORK_ROOT = [0xc3,0x01,0x81], PREFIX_NETWORK_PRINTER = [0xc3,0x02,0xc1], END_OF_STRING = [0x00]; if (/.*\\\\+$/.test(lnk_target)) { lnk_target = lnk_target.replace(/\\\\+$/g, ''); var target_is_folder = true; } var prefix_root, item_data, target_root, target_leaf; if (lnk_target.substr(0, 2) === '\\\\\\\') { prefix_root = PREFIX_NETWORK_ROOT; item_data = [0x1f, 0x58].concat(CLSID_Network); target_root = lnk_target.subtr(lnk_target.lastIndexOf('\\\')); if (/\\\\\\\\.*\\\\.*/.test(lnk_target)) { target_leaf = lnk_target.substr(lnk_target.lastIndexOf('\\\') + 1); } if (target_root === '\\\') { target_root = lnk_target; } } else { prefix_root = PREFIX_LOCAL_ROOT; item_data = [0x1f, 0x50].concat(CLSID_Computer); target_root = lnk_target.replace(/\\\\.*$/, '\\\'); if (/.*\\\\.*/.test(lnk_target)) { target_leaf = lnk_target.replace(/^.*?\\\\/, ''); } } var prefix_of_target, file_attributes; if (!target_is_folder) { prefix_of_target = PREFIX_FILE; file_attributes = FileAttributes_File; } else { prefix_of_target = PREFIX_FOLDER; file_attributes = FileAttributes_Directory; } target_root = str_to_arr(target_root); for (var i = 1; i <= 21; ++i) { target_root.push(0); } var id_list_items = gen_IDLIST(item_data); id_list_items = id_list_items.concat( gen_IDLIST(prefix_root.concat(target_root, END_OF_STRING))); if (target_leaf) { target_leaf = str_to_arr(target_leaf); id_list_items = id_list_items.concat( gen_IDLIST(prefix_of_target.concat(target_leaf, END_OF_STRING))); } var id_list = gen_IDLIST(id_list_items); var data = [].concat(HeaderSize, LinkCLSID, LinkFlags, file_attributes, CreationTime, AccessTime, WriteTime, FileSize, IconIndex, ShowCommand, Hotkey, Reserved, Reserved2, Reserved3, id_list, TerminalID); return new Blob([new Uint8Array(data)], { type: 'application/x-ms-shortcut' }); } var blob = create_lnk_blob('C:\\\\Windows\\\\System32\\\\Calc.exe'); |
使用方式如下:
1 2 | var blob_to_file = create_lnk_blob('C:\\\\Windows\\\\System32\\\\Calc.exe'); var blob_to_folder = create_lnk_blob('C:\\\\Users\\\\Myself\\\\Desktop\\\'); // with a trailing slash |
演示:http://jsfiddle.net/5cjgLyan/2/
如果您的网站允许使用php,这将很简单。
如果您的脚本是html文件的一部分,则只需编写javascript,就如同编写它来发送静态lnk文件一样。然后,在lnk地址部分,将javascript分为两部分,分成html。然后在这一点上,输入
1 2 | <?php /*PHP code set a variable *? /* PHP code to generate proper string*/ PRINT /*PHP variable*/ ?> |
我认为使其成为纯粹的客户是不可能的。
甚至Web rtc协议也需要至少一个iceServer来向其他客户端发出信号。
我认为最简单的方法是使用http://peerjs.com/
您可以先创建会议室所有者的客户身份标记
1 2 3 4 | //room owner side peer.on('open', function(my_peer_id) { console.log('My peer ID is: ' + my_peer_id); }); |
并将令牌发送给您想要的其他令牌(通过文本文件,网络聊天等)
然后使用上面的令牌进行其他连接
1 2 | //the other one var conn = peer.connect(other_peer_id); |
房间所有者检测到有人进入房间后。
与信号服务器断开连接,因此令牌将变得不可用
1 2 | //room owner side peer.disconnect() |
关于由客户端生成和读取文件,我建议您阅读以下文章。
我相信fileReader api和blob的兼容性并不重要。
因为永远不会有支持webrtc但不支持fileReader api
的浏览器