实现在win10的Linux子系统上运行windows的窗口程序
自从win10增加了Linux子系统功能之后,就可以免去虚拟机的安装,直接在windows上运行Linux命令行的命令了,还是十分方便的,笔者在win10上也配置linux子系统好久了,用的还算顺手,但是一直有个问题不太爽。因为它没有图形界面,同时也不能调用windows上的应用程序,所以不能很畅快的在子系统下进行目录管理的同时,用图形界面打开某个文件。以前用纯ubuntu的时候有些操作用vim不是很方便,所以喜欢用gedit编辑一些文件,所以每次在子系统上顺手输入gedit+文件名的时候,就会被出现的错误提示搞的很不爽。虽然gedit也有windows的版本,但是回到桌面系统上一层层目录点进去找文件也并不太方便,所以想找个方法让子系统上也能运行windows的窗口程序。倒腾了一上午,初步成型,在这里分享一下。
由于win10并没有给Linux子系统直接运行windows程序的接口(这个词或许不太准确?)所以要想调用windows的程序,只能通过windows里的程序来帮忙“转述”。据此,实现的大致思路是在win10中写一个守护进程,接收Linux子系统上传来的消息,然后相应的运行需要的程序。首先需要解决的是,两个系统中的通讯问题。好在win10和它的子系统本身具有两种通信的方式。一方面它们共用了文件系统,所以子系统和win10可以读取、修改同一个文件;另一方面,他们使用相同的网络环境,包括ip地址和端口,所以可以通过网络来交换数据。
一开始想通过文件的方式来交换数据,但是一方面怕同时打开文件会出现一些问题,另一方面也担心频繁的文件操作会不会占用很多系统资源(因为位于win10上的进程需要反复的扫描文件看是否有新的消息产生)。相反地,通过python可以很方便的利用socket进行网络数据的通信,而python又是一个多个平台都可以直接运行的语言,更为重要的是,本人曾经用python写过一些小项目,使用还算熟练,所以就选择使用python来进行网络通信的方式在两个系统中交换信息。
稍微总结一下,思路就是在windows中建立一个守护进程,子系统中将需要运行的命令发送给这个守护进程,守护进程收到信息后运行相应的程序。使用语言主要为python3,进程通信利用socket。
首先,是windows上的守护进程的脚本。
文件名:service_l2w.py
然后,再构建Linux子系统上的脚本
OK,主体内容基本完工,先喝杯咖啡休息一下。
接下来进行一些完善。
首先,是让win10中的脚本作为守护进程运行。
在win10的脚本所在文件夹中新建一个bat文件,用于启动文件,并将输出信息重定向到日志文件中,方便后面查看。文件名为service_l2w.bat,代码只有两行:
@echo off
py service_l2w.py >> log.txt 2>&1
然后,再建立一个文件,用于无界面运行上面这个文件。文件名为service_l2w.vbs,代码只有一行:
createobject(“wscript.shell”).run C:\Users\95628\Documents\Linux_bin\service_l2w.bat”,0
C:\Users\95628\Documents\Linux_bin是win10中脚本文件所在的目录全称
为了使其能够开启就可以运行,只需要把最后一个vbs文件放到开机启动的目录中就好。
其次, 将希望在Linux中运行的程序写一个脚本,来调用上面那个通用的python脚本,以gedit为例:
在任一个目录中创建文件gedit(不加任何后缀效果更佳)
非常简单的三行,第一行表示用bash运行这个脚本,这也是为什么不加.sh后缀也能运行的原因,第二行获取运行命令时的目录,第三行调用之前写的python脚本,将这些信息传给windows系统中的守护进程。
最后,只需要将自己写了文件gedit的那个目录加入到Linux搜素目录中就好,方法网上有,不赘述。
所有内容完工,做一个简单的测试:
需要进一步完善的地方,以及一些现存的bug;
- 不知道为什么,试过几次,log文件里没有内容,应该是哪个地方写错了。
- 只能单一的通过Linux命令调用窗口程序,一些命令行的输出不能实时的返回给Linux程序。比如说,输入gedit –hlep 在子系统上看不到帮助信息。
- 目录的“翻译还不够完善”,且只能“翻译”运行命令时所在目录,不能翻译后面参数的目录,比如gedit ../example.txt 可能无法正确完成想要的内容。