2013-02-20 2 views
6

"XY 문제"에 대한 오해를 피하기 위해 먼저 목표를 설명하겠습니다. Windows 컴퓨터에 다운로드하여 두 번 클릭하면 알려진 경로의 (ms office이지만 IIUC와 관련이없는) 파일이 로컬 (로컬 컴퓨터)에 열리는 파일을 Linux에서 생성 할 수 있기를 원합니다. windows 컴퓨터)를 미리 설정합니다.GNU/Linux에서 lnk 파일을 생성하여 창문으로 전송

lnk 파일에서 열려는 파일의 경로 (다른 볼륨의 내용과 관련 없음)를 포함하면 가능한 작업입니다. 파이썬 스크립트에서 파일을 생성하려고 시도한 lnk 파일 형식 사양을 먼저 확인했지만 이는 내 케이크 조각이 아닙니다. 이전에는 이진 파일을 처리하는 코드를 작성하지 않았습니다. 게다가, 내가 도랑 싶지 그 형식의 많은 기능이 있습니다,하지만 난 여전히 자신의 플래그/필드/길이/종료 등 grok해야만합니다

그럼 나는 winedump 유틸리티 및 와인에 의해 만들어진 일부 .lnk 파일을 발견 내 ~/.wine 폴더에. WINE 코드베이스에서 lnk 파일을 생성 할 수있는 기능이 있어야하지만 찾지 못했습니다. 어디입니까? win의 mklink와 같은 명령 형식입니까? 그렇지 않다면 (어쩌면 그것이 어딘가에있는 함수라고 생각할 수 있습니다.) 랩퍼 명령을 쓸 수 있도록 나에게 그것을 가리킬 수 있습니까?

또는 lnk 파일을 작성하고 GNU/Linux에서 실행할 수있는 라이브러리가 있습니까?

답변

6

이 날에 의해 검증되지 않은하지만 나는 다음과 같이이 도구를 서술 않는 this site에이 도구를 발견했다 :

이 응용 프로그램은 Windows를 필요로하지 않고 Windows 바로 가기 파일 (확장자 .LNK)를 만들 수 있습니다 OS.

첫 번째 앱은 C app이고 두 번째 앱은 배쉬 쉘 스크립트입니다. 쉘 스크립트는 다음과 같습니다. mslink.sh :

#!/bin/bash 

############################################################################################# 
# mslink.sh v1.0 
############################################################################################# 
# Ce script permet de créer un Raccourci Windows (Fichier .LNK) 
# Script créé en se basant sur la doc 
# http://msdn.microsoft.com/en-us/library/dd871305.aspx 
############################################################################################# 

OPTIONS=$(getopt -q -n ${0} -o hl:o:p -l help,lnk-target:,output-file:,printer-link -- "[email protected]") 

eval set -- ${OPTIONS} 

IS_PRINTER_LNK=0 
while true; do 
    case "$1" in 
    -h|--help) HELP=1 ;; 
    -l|--lnk-target) LNK_TARGET="$2" ; shift ;; 
    -o|--output-file) OUTPUT_FILE="$2" ; shift ;; 
    -p|--printer-link) IS_PRINTER_LNK=1 ;; 
    --)  shift ; break ;; 
    *)   echo "Option inconnue : $1" ; exit 1 ;; 
    esac 
    shift 
done 

if [ $# -ne 0 ]; then 
    echo "Option(s) inconnue(s) : [email protected]" 
    exit 1 
fi 

[ ${#LNK_TARGET} -eq 0 ] || [ ${#OUTPUT_FILE} -eq 0 ] && echo " 
Usage : 
${0} -l cible_du_fichier_lnk -o mon_fichier.lnk [-p] 

Options : 
-l, --lnk-target    Précise la cible du raccourci 
-o, --output-file    Enregistre le raccourci dans un fichier 
-p, --printer-link    Génère un raccourci de type imprimante réseau 
" && exit 1 

############################################################################################# 
# Fonctions 
############################################################################################# 

function ascii2hex() { 
    echo $(echo -n ${1} | hexdump -v -e '/1 " x%02x"'|sed s/\ /\\\\/g) 
} 

function gen_IDLIST() { 
     ITEM_SIZE=$(printf '%04x' $((${#1}/4+2))) 
     echo '\x'${ITEM_SIZE:2:2}'\x'${ITEM_SIZE:0:2}${1} 
} 

function convert_CLSID_to_DATA() { 
    echo -n ${1:6:2}${1:4:2}${1:2:2}${1:0:2}${1:11:2}${1:9:2}${1:16:2}${1:14:2}${1:19:4}${1:24:12}|sed s/"\([A-Fa-f0-9][A-Fa-f0-9]\)"/\\\\x\\1/g 
} 

############################################################################################# 
# Variables issues de la documentation officielle de Microsoft 
############################################################################################# 

HeaderSize='\x4c\x00\x00\x00'       # HeaderSize 
LinkCLSID=$(convert_CLSID_to_DATA "00021401-0000-0000-c000-000000000046") # LinkCLSID 
LinkFlags='\x01\x01\x00\x00'       # HasLinkTargetIDList ForceNoLinkInfo 

FileAttributes_Directory='\x10\x00\x00\x00'     # FILE_ATTRIBUTE_DIRECTORY 
FileAttributes_File='\x20\x00\x00\x00'      # FILE_ATTRIBUTE_ARCHIVE 

CreationTime='\x00\x00\x00\x00\x00\x00\x00\x00' 
AccessTime='\x00\x00\x00\x00\x00\x00\x00\x00' 
WriteTime='\x00\x00\x00\x00\x00\x00\x00\x00' 

FileSize='\x00\x00\x00\x00' 
IconIndex='\x00\x00\x00\x00' 
ShowCommand='\x01\x00\x00\x00'       # SW_SHOWNORMAL 
Hotkey='\x00\x00'        # No Hotkey 
Reserved='\x00\x00'        # Valeur non modifiable 
Reserved2='\x00\x00\x00\x00'       # Valeur non modifiable 
Reserved3='\x00\x00\x00\x00'       # Valeur non modifiable 
TerminalID='\x00\x00'        # Valeur non modifiable 

CLSID_Computer="20d04fe0-3aea-1069-a2d8-08002b30309d"    # Poste de travail 
CLSID_Network="208d2c60-3aea-1069-a2d7-08002b30309d"    # Favoris réseau 

############################################################################################# 
# Constantes trouvées à partir de l'analyse de fichiers lnk 
############################################################################################# 

PREFIX_LOCAL_ROOT='\x2f'       # Disque local 
PREFIX_FOLDER='\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'  # Dossier de fichiers 
PREFIX_FILE='\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'   # Fichier 
PREFIX_NETWORK_ROOT='\xc3\x01\x81'      # Racine de serveur de fichiers réseau 
PREFIX_NETWORK_PRINTER='\xc3\x02\xc1'      # Imprimante réseau 

END_OF_STRING='\x00' 

############################################################################################# 

# On retire l'anti-slash final s'il y en a un 
LNK_TARGET=${LNK_TARGET%\\} 

# On sépare le chemin racine du lien de la cible finale 
# On distingue aussi si le lien est de type local ou réseau 
# On définie la valeur Item_Data suivant le cas d'un lien réseau ou local 

IS_ROOT_LNK=0 
IS_NETWORK_LNK=0 

if [[ ${LNK_TARGET} == \\\\* ]]; then 
    IS_NETWORK_LNK=1 
    PREFIX_ROOT=${PREFIX_NETWORK_ROOT} 
    Item_Data='\x1f\x58'$(convert_CLSID_to_DATA ${CLSID_Network}) 

     TARGET_ROOT=${LNK_TARGET%\\*} 
     if [[ ${LNK_TARGET} == \\\\*\\* ]]; then 
       TARGET_LEAF=${LNK_TARGET##*\\} 
     fi 
     if [ ${TARGET_ROOT} == \\ ]; then 
       TARGET_ROOT=${LNK_TARGET} 
     fi 
else 
    PREFIX_ROOT=${PREFIX_LOCAL_ROOT} 
    Item_Data='\x1f\x50'$(convert_CLSID_to_DATA ${CLSID_Computer}) 

    TARGET_ROOT=${LNK_TARGET%%\\*} 
     if [[ ${LNK_TARGET} == *\\* ]]; then 
     TARGET_LEAF=${LNK_TARGET#*\\} 
     fi 
    [[ ! ${TARGET_ROOT} == *\\ ]] && TARGET_ROOT=${TARGET_ROOT}'\' 
fi 

if [ ${IS_PRINTER_LNK} -eq 1 ]; then 
    PREFIX_ROOT=${PREFIX_NETWORK_PRINTER} 
    TARGET_ROOT=${LNK_TARGET} 
    IS_ROOT_LNK=1 
fi 

[ ${#TARGET_LEAF} -eq 0 ] && IS_ROOT_LNK=1 

############################################################################################# 

# On sélectionne le préfixe qui sera utilisé pour afficher l'icône du raccourci 

if [[ ${TARGET_LEAF} == *.??? ]]; then 
    PREFIX_OF_TARGET=${PREFIX_FILE} 
    TYPE_TARGET="fichier" 
    FileAttributes=${FileAttributes_File} 
else 
    PREFIX_OF_TARGET=${PREFIX_FOLDER} 
    TYPE_TARGET="dossier" 
    FileAttributes=${FileAttributes_Directory} 
fi 

# On convertit les valeurs des cibles en binaire 
TARGET_ROOT=$(ascii2hex ${TARGET_ROOT}) 
TARGET_ROOT=${TARGET_ROOT}$(for i in `seq 1 21`;do echo -n '\x00';done) # Nécessaire à partir de Vista et supérieur sinon le lien est considéré comme vide (je n'ai trouvé nul part d'informations à ce sujet) 

TARGET_LEAF=$(ascii2hex ${TARGET_LEAF}) 

# On crée l'IDLIST qui représente le cœur du fichier LNK 

if [ ${IS_ROOT_LNK} -eq 1 ];then 
    IDLIST_ITEMS=$(gen_IDLIST ${Item_Data})$(gen_IDLIST ${PREFIX_ROOT}${TARGET_ROOT}${END_OF_STRING}) 
else 
    IDLIST_ITEMS=$(gen_IDLIST ${Item_Data})$(gen_IDLIST ${PREFIX_ROOT}${TARGET_ROOT}${END_OF_STRING})$(gen_IDLIST ${PREFIX_OF_TARGET}${TARGET_LEAF}${END_OF_STRING}) 
fi 

IDLIST=$(gen_IDLIST ${IDLIST_ITEMS}) 

############################################################################################# 

if [ ${IS_NETWORK_LNK} -eq 1 ]; then 
    TYPE_LNK="réseau" 
    if [ ${IS_PRINTER_LNK} -eq 1 ]; then 
     TYPE_TARGET="imprimante" 
    fi 
else 
    TYPE_LNK="local" 
fi 

echo "Création d'un raccourci de type \""${TYPE_TARGET}" "${TYPE_LNK}"\" avec pour cible "${LNK_TARGET} 1>&2 

echo -ne ${HeaderSize}${LinkCLSID}${LinkFlags}${FileAttributes}${CreationTime}${AccessTime}${WriteTime}${FileSize}${IconIndex}${ShowCommand}${Hotkey}${Reserved}${Reserved2}${Reserved3}${IDLIST}${TerminalID} > "${OUTPUT_FILE}" 
+1

이 두 도구는 적어도 제한된 테스트에서 보았을 때처럼 작동하는 것으로 보입니다. 둘 다 같은 방식으로 작동하기 때문에 C와 쉘 스크립트 버전 사이의 기능에는 차이가 없습니다. C 프로그램은 수천 개의 .lnk를 빨리 작성해야하지만 쉘 스크립트 버전이 완벽하게 적합하면 더 빠를 수 있습니다. 프랑스어 의견과 사용법에도 불구하고 프랑스어를 읽을 수 없더라도 쉽게 이해할 수 있습니다. 두 경우 모두 ** 대상 경로에 백 슬래시를 사용하고 작은 따옴표로 묶어야합니다. ** mklink -l '\\ server \ dir \ file'-o my.lnk'와 같습니다. – wojtow

관련 문제