簡體   English   中英

從在 WINE 中運行的程序執行 Shell 命令

[英]Execute Shell Commands from Program running in WINE

我有一個使用 WINE 在 Linux 上運行的 Windows 程序。

如何從 Windows 程序調用 Linux shell 命令?

使用較新的 Wine 版本(使用 Wine 1.7.38 測試) ,您可以通過以下方式在 Wine 中運行 Linux 程序(這里以啟動 gedit 為例):

wineconsole cmd

...從那個葡萄酒控制台:

start /unix /usr/bin/gedit

如果您想直接從 Windows 應用程序中啟動 Linux 程序,以下行對我有用:

cmd /c start /unix /usr/bin/gedit

要對此進行測試,您可以直接在 Linux 控制台上調用:

wine cmd /c start /unix /usr/bin/gedit

需要注意的一件重要事情:您要啟動的程序需要設置可執行位,否則從 Wine 調用它會失敗!

試試這個(在我的 Linux Mint 系統上運行 Gnome 計算器):

wineconsole cmd

...從葡萄酒控制台:

/bin/sh gcalctool

根據這個一般原則,您還可以通過編輯 wine 注冊表來打開文檔並將文件與 linux 應用程序關聯。 在葡萄酒常見問題中有一個關於它的部分:

6.6.3 如何在 Wine 中關聯本地程序和文件類型?

所以你應該能夠編寫 shell 腳本並調用它們。

如何從 Wine 程序調用 Linux 程序——API 方面的五點。

1. 正確的PATHEXT

在新的 Wine 版本中(至少從 2.0.1 開始),需要在PATHEXT環境變量中的可執行文件擴展名列表中添加擴展名(即只是點字符: . )。 如果沒有此添加,錯誤消息可能會顯示如下內容:

Can't recognize '/bin/bash' as an internal or external command, or batch script.

要修復注冊表中的初始PATHEXT值,可以使用以下命令片段(對於每個WINEPREFIX ):

k='HKLM\System\CurrentControlSet\Control\Session Manager\Environment'
pathext_orig=$( wine reg query "$k" /v PATHEXT | tr -d '\r' | awk '/^  /{ print $3 }' )
echo "$pathext_orig" | grep -qE '(^|;)\.(;|$)' \
  || wine reg add "$k" /v PATHEXT /f /d "${pathext_orig};."

此代碼檢查然后修改PATHEXT如果它不包含. 僅項目。

另請參閱: 如何從 Windows 應用程序啟動本機應用程序? 在 WineHQ 常見問題解答中; 注意

請注意,每次升級 Wine 時都必須進行此更改,因為只要更新 wineprefix,它就會恢復。

2. 可執行文件路徑

默認情況下,您可能需要指定可執行文件的完整(或相對)路徑(例如, /bin/bash ),因為 Wine 進程不會從父 Linux 進程繼承PATH環境變量。 請注意,Wine 進程中的當前驅動器默認映射到 Linux 根文件夾,因此無需指定驅動器號。 /bin/bash只是有效,但不是bash

另一種方法是相應地更改 Wine 中的PATH環境變量,或更改當前目錄。

當路徑包含非 ASCII 字符時——作為CreateProcessA參數——路徑應該在 Wine 語言環境中並根據LANG環境變量; 另請參閱Eugene在本主題中的回答,以及如何設置編碼以與 Wine 中的非 Unicode 應用程序一起使用的論壇帖子。 在任何情況下,對於CreateProcessW ,路徑都應該是 UTF-16。

3. 可執行格式

共享對象格式的 Linux 可執行文件不能從 Wine 執行。 請參閱: 可執行文件與共享對象以及如何在 64 位 Linux 上從 32 位 Wine 執行 shell 腳本 例如, /bin/dash可以是“ELF 64 位 LSB 共享對象”(參見file /bin/dash輸出)並且在這種情況下不能從 Wine 執行。 錯誤信息說:

wine: Bad EXE format for Z:\bin\dash..
Can't recognize '/bin/dash' as an internal or external command, or batch script.

4.無需等待

父 Wine 進程不能在子 Linux 進程上等待(例如,通過WaitForSingleObject ),因為它沒有提供子進程句柄——它只是 0。請參閱錯誤報告:啟動 Linux 程序時 CreateProcess 沒有正確設置 hProcess (狀態:關閉 WONTFIX)。

然而,如果子進程使用 stdout(另見下文),父進程可以通過在特定管道上阻塞讀取來間接等待子進程。

5.管道重定向的區別

也許這是 Wine 中的一個錯誤,但是父進程應該關閉傳遞給 CreateProcess 的 std 句柄,只有在關閉相應管道的自己的句柄(或就在它之前)之后。 而在 Windows 中,這些句柄可以在CreateProcess函數完成后立即關閉。 通過 MSDN,這些句柄可能會在傳遞后立即關閉(請參閱CreateProcess 函數):

STARTUPINFO 或 STARTUPINFOEX 中的句柄在不再需要時必須用 CloseHandle 關閉。

在 Wine 2.0.1 中,Linux 子進程中對應的管道會立即關閉,子進程會提前停止 但不是在子 Windows 進程的情況下。

嘗試(其中 yourprogram 是您要在 wine 中執行的 linux/unix 程序)

ln -s /path/to/yourprogram /path/to/wineprefix/drive_c/windows/system32/yourprogram

這就是我讓java工作的方式。

例如:

Z:\bin\ls

但也許您正在尋找類似http://gnuwin32.sourceforge.net/ 之類的東西,您將安裝到您的葡萄酒“窗口”中? 或者已經提到的cygwin。

對我來說,我在這個網站上找到的第一個解決方案有效 - 將擴展與 winebrowser 相關聯,並且當單擊 wine Explorer(或其他 Windows 應用程序)中的文件時,默認的 gnome 文件查看器從 wine 啟動。

以前在 wine 1.4中工作的shell scripts 解決方案不適用於 wine 1.6

但是,我注意到的問題是 Windows 編碼中的名稱不會轉換為 Linux 區域設置,從而阻止它與例如俄語目錄名稱一起使用

WineHQ 常見問題解答列出的 shell 腳本可以稍作修改,例如:

#!/bin/bash
WFILE=$(echo -E $2)
FILE=$(wine winepath $WFILE)
$1 $FILE

其余的工作就像常見問題解答中描述的那樣。

我喜歡Far Commander ,它確實在wine下運行,所以我設置了這兩個腳本:

  1. 從 Windows 啟動 Linux 應用程序

C:\\windows\\xt.bat

start /unix /usr/bin/xterm -e %*
  1. 從 wine 環境 (Far) 在 Linux 中打開文件:

C:\\windows\\xdg.bat

cd >C:\windows\command\mypwd
start /unix /etc/init.d/winopen.sh  %*

/etc/init.d/winopen.sh

#!/bin/sh
PWDF=`winepath -u 'C:\windows\command\mypwd'`
fromdos $PWDF
xdg-open $(winepath -u $(cat $PWDF)/$1)

現在我可以在 Far 命令行上輸入:

xdg SomeDocument.PDF

並在 Linux 環境中得到結果。

編輯:user1182474 的評論是正確的; Wine 不會隔離它運行的程序。 (它試圖隱藏它,但不是很徹底。)我完全沒有使用谷歌。 下面 Psen 的評論更正確,並參考了常見問題解答。 (請注意,要使其正常工作,您可能需要通過 Wine 驅動器映射提供程序目錄。或者,請參閱匿名回復者的回答。)

== 舊答案 ==

Wine 隔離它運行的程序。 如果所有應用程序都按預期運行,那么這些應用程序將呈現與 Windows 無法區分的環境。 不幸的是,這意味着您無法訪問主機操作系統 (Linux) 的功能。 我的意思是,你可以修補 Wine 來做到這一點,但我的印象是它會比它的價值更多的工作。

還有希望! Cygwin 是用於 Windows 的類 Unix 環境。 您可以在 Wine 中安裝 Cygwin,並使用 Cygwin 運行您的 shell 腳本。 (顯然,使用 'winetricks cygwin' 安裝是最簡單的)像這樣調用 Cygwin 的 bash shell(在一些 Wine 程序中):

c:\cygwin\bin\bash  myscript

當然,將 c:\\cygwin 更改為您安裝它的任何位置。

如果您需要等待命令完成並獲取其輸出,請使用 SSH。 否則(如果您只需要啟動它)任何這些方法都可以工作:

核心問題是 CreateProcess 返回零 PID 和 handle ,因此您不能等待子進程完成並獲取它的退出代碼。

我也嘗試過標准管道重定向,但沒有成功。 Linux 子進程的輸出丟失,管道為空。

所以,和 CreateProcess 和朋友一起,你必須使用某種觸發器文件,看起來不太漂亮。 就像我說的,我們將改用 SSH。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM