内外联动 — wine环境内的外部应用程序关联

wine 的出现为 linux 环境中使用 windows 程序提供了高效的轻量级的解决方案。使用 wine,可以在 linux 环境中轻松使用原来只能在 windows 中才能使用的那些优秀软件。

由此带来诸多益处,首先,可以将原来用户在 windows 下的软件良好使用体验,“平滑”的带到 linux 中来。用户可以不用顾虑因操作系统平台的差异而带来软件差异,及由此导致的 UI、信息格式、使用习惯等不同,而可以完全专注于软件所生产的数据本身。从而,真正实现了“以数据为核心”。

而更为重要的是,wine 极大的丰富的 linux 系统的软件生态,相当与将原来 windows 的软件生态“整体”迁移到 linux 平台下,加之 linux 原有的优秀软件,在同一平台上同时运作,取长补短,强强组合,优势明显。近年来,这种不同操作系统平台软件融合的思路日益明显,windows 上也不断加入 linux 的运行环境特征就是明显的例子。

这种软件生态的融合趋势,必然也强化了数据共享协同、软件互操作的需求。这种需求在 wine 环境下可以体现为两个方面:

  • linux 原生环境中调用 wine 环境(windows 环境)的软件
  • wine 环境下调用其他软件(linux 原生软件或其他 wine 环境下软件)

第一个方面的需求,即是 wine 环境设计的初衷,满足了 linux 环境下应用 windows 软件的直接诉求。在 wine 环境中安装好相关 windows 软件,按照 wine 的使用要求,必要时设置相关 MIME 关联,在 linux 环境中(如 bash)直接调用即可。

第二个方面的需求,则体现了软件协同的深入需求。为了高效完成任务,wine 环境下的软件也常常需要借助其他非本环境的软件的协助。比如,

wine 环境下使用一个邮件客户端软件,除了完成邮件收发的基本功能外,还需查看邮件携带的附件文档,而本 wine 环境没有文档查看软件。此时,无外两种选择,一种是先将附件文档存储到 linux 本地环境,再使用 linux 环境的文档编辑软件打开查看(既可以是 linux 原生软件,也可以是另一个 wine 环境软件),另一种选择是在 wine 环境中直接调用其他外部环境的应用程序查看(既可以是 linux 原生软件,也可以是另一个 wine 环境软件)。

显见,第二种选择更为符合用户的使用习惯,简单直接,软件应用效率更高。为此,需要解决在 wine 环境下调用其他外部应用程序的需求,具体则表现为如何利用外部软件程序打开 wine 环境中文件的需求,wine 也提供了相应的解决方案。

wine 环境中调用外部应用程序的关键问题

每个 wine 环境本身就“有限”模拟了一个 windows 系统环境,基于这个前提,当考虑 wine 环境中的文件关联,本质上回归到考虑 windows 系统下文件与应用程序关联问题


(完成了 API 级的模拟,也就提供了一个“虚拟”的操作系统环境。一个应用层软件所能“感知”到的,只是操作系统 API 的行为!)
(wine 原理与软件保护领域中的虚拟机保护技术似乎有相似的思路,都是针对 API 级的一种“替换”操作!)

在借助传统 windows 注册表方法进行文件与应用程序关联时,由于 wine 的特殊性,也随着带来一些新的问题需要解决,其中最为重要的一个就是目标文件(对象)的路径问题。

为了支撑 windows 下软件运行,则需要模拟出 windows 的文件系统,每个 wine 环境在其所属文件夹内均构造了一套 windows 文件系统,即使用 c、d、e 等盘符表示文件分区,其中 z 盘分区对应的 linux 的文件系统。windows 软件无感透明运行,软件本质运行在 wine 环境内,以为自己运行在一个 windows 系统上,所以使用包含 c、d 等盘符的 windows 路径表示法来访问资源,其感知的环境参数是“虚拟” windows 的环境参数。而 wine 环境之外的软件,其使用的是 linux 的环境参数,使用 linux 的路径定位资源。如此,造成了一个 wine 环境之内的软件与该 wine 环境之外的软件,对同一个资源的路径定位方法不同。

比如,wine 环境下 Foxmail 软件运行时的缓存文件 pdf_m.png,在 wine 环境下,Foxmail 认为该缓存文件的访问路径为:

c:\users\gogetter\Application Data\Foxmail7\Temp-103\pdf_m.png

而在 linux 下,其真实路径为:

/home/gogetter/.deepinwine/wine-Foxmail/c:/users/gogetter/Application\ Data/Foxmail7/Temp-103/pdf_m.png

由于这种路径描述的不一致情况,在 wine 环境内部,当需要调用外部的应用程序访问内部文件资源时,无法直接使用 wine 环境内部相关参数所传递的资源位置信息,因为这些内部参数所传递的位置信息都是基于 c、z 盘符的 windows 路径,linux 环境下的外部应用程序无法识别这些路径,必须将 wine 环境内部的资源路径位置信息转换成外部应用可直接访问的 linux 下资源路径。这一点也是 wine 环境中调用外部应用必须解决的核心问题。

wine 为上述问题提供相应的手段。

wine 环境中特定文件与应用程序的关联

windows 系统通过注册表机制完成文件与应用程序的关联,wine 环境也是如此,在每个 wine 环境的注册表根键 HKEY_CLASSES_ROOT 下完成文件与应用程序关联。总体上,还是分为(1)注册文件类型、(2)关联打开方式两个步骤进行。

在进行文件关联过程中,必须解决上述 wine 环境内部资源描述路径外部应用程序无法访问的问题,为此,wine 提供了多种解决方案。

不进行内部路径转换

wine 环境中,默认提供了一种应用程序调用指令 — winebrowser.exe,指令存储在 wine 环境内的 c:\windows\system32\ 路径下。该指令有如下特点:

  • 在 wine 环境内,针对特定文件类型使用 winebrowser,会直接调用外部系统中该类型文件的默认打开程序,比如,在 linux 桌面下其直接调用 xdg-open 指令寻找特定文件类型的 linux 关联应用程序,进而打开文件。
  • winebrowser 本身就是 wine 环境内的一个 windows 程序,其可以直接使用 wine 环境内部的路径作为参数,无需进行任何的路径转换。

以下是一个利用 winebrowser 针对 .pdf 文件的注册表解决方案实例。

[HKEY_CLASSES_ROOT\.pdf]
@="PDFfile"
"Content Type"="application/pdf"
[HKEY_CLASSES_ROOT\PDFfile\Shell\Open\command]
@="C:\\windows\\system32\\winebrowser \"%1\""

winebrowser 直接调用 wine 环境的父环境中的文件默认打开程序,针对任何类型的文件,只要 wine 环境的父环境有相应的打开程序,都可以使用此指令。由此可见,该指令是一个“一揽子、傻瓜式”的解决方案,但基本没有可定制的空间。

强制进行内部路径转换

另一种思路是将 wine 环境的内部路径先转换成外部父环境的路径,再以此作为参数,提供给外部应用程序使用。为此,wine 软件提供了一个专门的路径转换指令 — winepath。

winepath – Tool to convert Unix paths to/from Win32 paths

  • -u, –unix
    converts a Windows path to a Unix path.
  • -w, –windows
    converts a Unix path to a long Windows path.

winepath,专门用来完成 Unix/Win32 之间路径转换任务。有了 winepath 进行路径的转换,就可以准确获取的目标文件在父环境路径信息,用户可自由建立任何期望的外部应用程序与目标文件的关联,而不拘泥于父环境中默认的文件类型与应用程序关联。这种方式定制性很强,极大的拓展 wine 环境内调用外部应用程序灵活性。

还是以 .doc 文件为例。

1、编写脚本(runinwine)完成路径转换,及外部应用程序的参数递送

#!/bin/sh
#/usr/local/bin/runinwine

$1 "`/opt/wine-stable/bin/winepath "$2"`";
exit 1;

2、在注册表中完成文件类型与应用程序的关联

  • 使用 OpenOffice 关联 .doc 文件
[HKEY_CLASSES_ROOT\.doc]
@="DOCfile"
"Content Type"="application/msword"

[HKEY_CLASSES_ROOT\DOCfile\Shell\Open\command]
@="/usr/local/bin/runinwine /usr/bin/ooffice \"%1\"" 
  • 使用 WPS 关联 .doc 文件
[HKEY_CLASSES_ROOT\.doc]
@="DOCfile"
"Content Type"="application/msword"

[HKEY_CLASSES_ROOT\cusDOCfile\Shell\Open\command]
@="/usr/local/bin/runinwine /usr/bin/wps \"%1\""
  • 使用自定义脚本关联 .doc 文件
[HKEY_CLASSES_ROOT\.doc]
@="DOCfile"
"Content Type"="application/msword"

[HKEY_CLASSES_ROOT\cusDOCfile\Shell\Open\command]
@="/usr/local/bin/runinwine /home/gogetter/Documents/myscrips/offdoc.sh \"%1\""

reference:

  1. WINE FAQ
  2. https://www.winehq.org/pipermail/wine-users/2008-January/028728.html
  3. http://www.jrnguyen.com/2009/11/16/windows-file-associations-in-linux-wine/
  4. Best Practices for Windows File Associations
  5. winepath
  6. Windows 注册表中 % 变量参数意义

发表评论

电子邮件地址不会被公开。 必填项已用*标注