2014-09-02 5 views
9

Я хотел бы дать пользователям на моем сайте возможность загрузить файл «lnk». Моя идея состоит в том, чтобы сгенерировать этот файл, чтобы содержать адрес, который можно использовать только один раз. Есть ли способ создать этот файл в javascript? Поток что-то вроде -Есть ли способ создания файла lnk с помощью javascript

  1. пользователь нажимает кнопку
  2. Javascript генерирует этот файл и загружает его в компьютер пользователя
  3. пользователь отправляет этот файл другому пользователю использовать этот одноразовый -адрес с его машины

Что-то вроде этого можно сделать в javascript со стороны клиента? или мне нужно будет сгенерировать этот файл с помощью java-сервера?

+0

проверки этого http://www.codeproject.com/Articles/55488/File-Download-Using-JavaScript – mck

+1

@Cory что он делает - проверить 'Blob', вы может создавать произвольные файлы в JS и загружать их на компьютер. –

+0

Формат файла указан, но не совсем тривиален: http://msdn.microsoft.com/en-us/library/dd871305.aspx. – kay

ответ

5

Это верный перевод mslink.sh.

Я только проверял свой ответ в Windows 8.1, но я думаю, что он работает и в более старых версиях Windows.

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'); 

использовать его как:

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 

Demo: http://jsfiddle.net/5cjgLyan/2/

+0

Это лучшее решение, которое я нашел, но браузеры, кажется, ненавидят файлы .lnk (я также попытался создать сервер файлов lnk) – EKS

-3

Я думаю сделать это чистый клиент невозможно. Даже протокол web rtc должен, по крайней мере, один iceServer сигнализировать другому клиенту.

И я думаю, что самый простой способ сделать это состоит в использовании http://peerjs.com/

вы могли сначала создать clinet маркер владельца номера

//room owner side 
peer.on('open', function(my_peer_id) { 
    console.log('My peer ID is: ' + my_peer_id); 
}); 

И послать маркер на любой другой вы хотите (по тексту файл, веб-чат ... и т.д.)

Затем другой подключить его использовать маркер выше

//the other one 
var conn = peer.connect(other_peer_id); 

После того, как владелец помещения обнаружил, что кто-то вошел в комнату.

Отключение от сервера сигнала, поэтому маркер станет непригодным для использования

//room owner side 
peer.disconnect() 

О генерации и чтения файлов по стороне клиента, я рекомендую вам прочитать статью ниже.

  1. http://www.html5rocks.com/en/tutorials/file/dndfiles/ чтение из файла
  2. How to use filesaver.js Сохранить как файл

Я считаю, что совместимость FileReader апи и сгустка не имеет значения. Поскольку никогда не будет браузера, который поддерживает webrtc, но не поддерживает fileReader api

-1

Это было бы просто, если ваш сайт разрешает php.

Если ваш скрипт является частью html-файла, просто напишите javascript, как если бы вы писали его для отправки статического файла lnk. Затем, в адресной части lnk, разбейте javascript на две части, взломав html. Тогда в этой точке, положить в

<?php /*PHP code set a variable *? /* PHP code to generate proper string*/ PRINT /*PHP variable*/ 
?> 
Смежные вопросы