Wine 용 프로그램을 리눅스 데스크탑 파일 관리자(돌핀)와 연동하기.

와인으로 MS 윈도우용 프로그램을 설치하면, ~/.local/share/applications/wine/Programs/)에 자동으로 .desktop 파일이 만들어지고, 리눅스 데스크탑용 런처에서 바로 실행할 수 있는 상태가 된다.
예를 들어, mp3tag 을 설치한다면,

[Desktop Entry]
Name=Mp3tag
Exec=env WINEPREFIX="/home/user/.wine" wine C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start\\ Menu\\\\Programs\\\\Mp3tag\\\\Mp3tag.lnk
Type=Application
StartupNotify=true
Path=/home/user/.wine/dosdevices/c:/Program Files (x86)/Mp3tag
Icon=5632_MP3TAG.0
StartupWMClass=mp3tag.exe

이런 식으로 .desktop 파일이 만들어진다.

이렇게 그냥 단독 실행했을 때는 별 문제가 없다. 그러나, 돌핀등 파일 관리자에서 파일을 선택한 뒤 우클릭하여 그 파일을 Wine 용 프로그램으로 불러오고 싶다면? 아예 파일 불러오기가 안될 수도 있고(그냥 프로그램만 실행된다.), 된다하더라도 경로 문제로 인해 원하는 결과를 얻을 수가 없게 된다(프로그램이 시작되지만, 경로를 찾을 수 없다는 오류가 뜬다.).

이건 리눅스 경로와 Wine(MS 윈도우) 경로가 다르기 때문이다. 이를 위해 Wine 에선 winepath 를 제공해주는데, 이상하게도 최근 winepath 가 한글을 무시하기 시작했다.

winepath -w '/다운로드' 
Z:\?ㅼ슫濡쒕뱶

제대로된 결과는 Z:\다운로드 가 돼야 하지만, 저렇게 코드가 깨져버린다. 이유는 알 수가 없다. 버그 보고하기도 번거롭고 복잡하고..

버그 보고를 했다. 의외로 답이 빨리 달렸다. 헌데 이게 생각보다 복잡한 문제라고 하는데..
글쓴이가 한대로, tee 를 붙였더니 제대로 작동은 한다.
그런데, 이게 또 문제. 스크립트를 직접 터미널에서 실행시키면 winepath 가 제대로 작동한다. 물론 tee 를 붙였을 때.
하지만 돌핀에서 연동하여 실행했을 때는 winepath 결과가 제대로 나오질 않는다. 그냥 null 값이 나오는 듯 한데.. 시험해볼 방법이 여의치 않아서(그냥 내용을 파일로 출력해보는 정도밖에..), 더 이상 확인해볼 순 없었다.
문제가 과연 뭐였을까?

하여, 그냥 winepath -w 를 regex 로 구현하는 간단한 스크립트를 만들어 일종의 wrapper 로 사용해보기로 했다.


.desktop 파일

mp3tag 을 예로 들면, 이런 식으로 변경해야 한다.

Name=Mp3tag
#Exec=env WINEPREFIX="/home/nemoarch/.wine" wine C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start\\ Menu\\\\Programs\\\\Mp3tag\\\\Mp3tag.lnk
Exec=wine_mp3tag_4DP %f
.... 나머지는 동일

Exec 항목을 저런 식으로 바꿨다. wine_mp3tag_4DP 가 wrapper 이고, 저건 실행경로(~/bin 등)에 있어야 한다.
%f 파일 1개를 넘기는 인수다. 여러 개를 넘기려면 %F 를 써야 하는데, 그리 되면 복잡해지기도 하고, 특히나 mp3tag 은 주로 디렉토리 단위로 작업을 하기 때문에, %f 를 써서 현재 선택한 파일만을 넘기기로 했다. 예전에는 %d 로 선택한 파일의 디렉토리만 넘길 수도 있었는데, 그건 없어졌다(deprecated).

wrapper

# 사용자 홈디렉토리를 알아낸 후, .wine 폴더 경로 추가.
WINE_HOME="$HOME/.wine"

# Argument (%f) 가 넘어왔을 때만 winepath 로 변환
if [[ $# -gt 0 ]]; then
        music_dir=$(dirname "$1")
        wine_music_dir=$(winepath-perl.sh "$music_dir")

        # Wine 을 사용, MS 윈도우 프로그램 호출
        env WINEPREFIX="$WINE_HOME" wine 'C:\Program Files (x86)\Mp3tag\Mp3tag.exe' /fp:"$wine_music_dir"
else
        # Arg. 가 없으므로 /fp 를 사용하지 않음.
        env WINEPREFIX="$WINE_HOME" wine 'C:\Program Files (x86)\Mp3tag\Mp3tag.exe'
fi

exit 0

Argument 가 있을 때만, 즉 돌핀등에서 컨텍스트 메뉴로 실행하여 %f 가 같이 넘어왔을 때만 winepath 를 사용하기로 했다. 또, dirname 으로 경로만을 넘긴다. 선택한 파일 1개만 넘기고 싶다면 dirname 을 사용하지 않으면 된다.
복잡할 여지가 아예 없는, 단순한 스크립트.

winepath-perl.sh

wine 용으로 경로를 변환해주는 스크립트. 파일명에 perl 이 들어갔지만, perl 스크립트는 아니고 regex 에서 perl 을 사용했다.

file_names="$@"

for f in "$@"
do
        # pattern & subs
        pattern="/"
        subs="\\"
        export pattern subs
        to_wine_filename=$(echo "Z:$f" | perl -pe 's/$ENV{pattern}/$ENV{subs}/g')
        echo -E "$to_wine_filename"
done

sed 로 하지 않고 perl 을 쓴 이유는 다른 글에 장황하게 기록돼 있다. 간단하게 말하자면, 구분자(delimiter, /) 때문이다. 경로명에 슬래시가 들어있는데, 이게 구분자와 헷갈리기 때문에, 보다 편하게 쓸 수 있는 방법을 찾았고, 그게 perl 이었다.

다만, 위 스크립트 상태로는 파일 1개(%f) 를 넘겼을 때만 제대로 작동할 듯. 스크립트만 보면 여러 개(%F)를 처리할 수 있듯은 보이지만, 그걸 Wine 용 프로그램에서 제대로 처리하려면 뭔가 더 방법이 필요하다.
덧붙이자면, %F 가 되어 파일명이 여러개 넘어오면, 위 작업도 여러번 반복되면서 파일명을 계속 넘기게 된다. winepath-perl.sh 를 실행한 쪽에선 그 파일명들을 받아서 처리하는 방식으로 처리해야한다.
현재는 %F 가 필요하진 않아서 그냥 이렇게만 해놨다. 즉, 아직 궁하지 않아 여기까지만 생각해 봤을 뿐이다.

또, 경로명이 길 경우(255 bytes 초과?) 오류가 발생한다. 이건 wine, 또는 MS 윈도우 자체 문제로 보인다. 이런 현상을 방지하기 위해 winepath 에는 –short 선택사항이 있는데.. 그것까지 구현하기엔 실력이 한참 모자라기에..


주로 쓰는 mp3tag, foobar2000 등으로 시험해봤는데 원하는대로 잘 작동했다.

Author: 아무도안

안녕하세요. 글 남겨주셔서 고맙습니다.