关于html:是否有使用javascript创建lnk文件的方法

Is there a way of Creating lnk file using javascript

我想让我网站上的用户能够下载" lnk"文件。
我的想法是生成包含一个只能使用一次的地址的文件。
有没有办法在javascript中生成此文件?
流程类似于-

  • 用户按下一个按钮
  • 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()

    关于由客户端生成和读取文件,我建议您阅读以下文章。

  • http://www.html5rocks.com/zh-CN/tutorials/file/dndfiles/从文件中读取
  • 如何使用filesaver.js另存为文件
  • 我相信fileReader api和blob的兼容性并不重要。
    因为永远不会有支持webrtc但不支持fileReader api

    的浏览器