如何在Docker中使用Wine运行我的Win32应用程序?

12

我有一个使用Delphi编写的Win32应用程序,它公开了一个REST端点并显示一个窗口以记录请求。该应用程序是32位的。

我在Ubuntu(20.04)上使用Wine(4.0.4)运行它。它可以直接运行,并且我创建了一个32位前缀并启动它。一切都很好。这是一个只安装了Wine的干净的Ubuntu虚拟机。

现在,我正在尝试将其放入Docker容器中,但我无法使其运行。我正在使用xvfb-run来支持UI。

当我尝试在我的容器中运行应用程序时,我会收到以下消息/警告/错误:

0010:err:ole:marshal_object couldn't get IPSFactory buffer for interface {00000131-0000-0000-c000-000000000046}
0010:err:ole:marshal_object couldn't get IPSFactory buffer for interface {6d5140c1-7436-11ce-8034-00aa006009fa}
0010:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hres=0x80004002
0010:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, 80004002
0010:err:ole:get_local_server_stream Failed: 80004002

该应用程序似乎确实启动了。当我向端口9000(应用程序侦听的端口)发送请求时,会报告更多错误(并且没有收到响应,只看到套接字关闭)。这些错误是:
0019:err:ole:CoGetClassObject class {88d96a05-f192-11d4-a65f-0040963251e5} not registered
0019:err:ole:create_server class {88d96a05-f192-11d4-a65f-0040963251e5} not registered
0019:err:ole:CoGetClassObject no class object {88d96a05-f192-11d4-a65f-0040963251e5} could be created for context 0x5

我不确定我的容器缺少了什么,因为它在桌面环境下正常运行。

我的Dockerfile如下:

FROM ubuntu:20.04

RUN apt-get update

RUN apt-get install -y wget software-properties-common gnupg2 xvfb

RUN dpkg --add-architecture i386
RUN wget -nc https://dl.winehq.org/wine-builds/winehq.key
RUN apt-key add winehq.key
RUN add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main'
RUN apt-get update
RUN apt-get install -y winehq-stable winetricks winbind

RUN apt-get clean -y
RUN apt-get autoremove -y

ENV WINEDEBUG=fixme-all

ENV WINEPREFIX=/root/.catalyst
ENV WINEARCH=win32
RUN xvfb-run winecfg

RUN winetricks msxml6

WORKDIR /root

COPY app catalyst

EXPOSE 9000

CMD ["xvfb-run", "wine", "/root/catalyst/CATALYSTWeb.exe"]

88d96a05-f192-11d4-a65f-0040963251e5 是 MS XML 6 COM 对象。 - mj2008
我已经通过winetricks添加了msxml6(请参见更新的Dockerfile)。似乎没有帮助。仍然出现相同的错误。 - dommer
2个回答

12
我解决了。下面是Dockerfile。
在启动我的应用程序之前,我还需要添加sleep 1s以允许一些服务启动。
FROM ubuntu:20.04

RUN apt-get update

RUN apt-get install -y wget software-properties-common gnupg2 winbind xvfb

RUN dpkg --add-architecture i386
RUN wget -nc https://dl.winehq.org/wine-builds/winehq.key
RUN apt-key add winehq.key
RUN add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main'
RUN apt-get update
RUN apt-get install -y winehq-stable

RUN apt-get install -y winetricks

RUN apt-get clean -y
RUN apt-get autoremove -y

ENV WINEDEBUG=fixme-all

RUN winetricks msxml6

COPY app /root/catalyst
COPY startup.sh /root/startup.sh
RUN chmod gou+x /root/startup.sh

EXPOSE 9000

CMD ["/root/startup.sh"]

startup.sh is

#!/usr/bin/env bash

sleep 1s
xvfb-run wine /root/catalyst/CATALYSTMWeb.exe

4
这个Dockerfile写得不好。有太多冗余的层只会增加镜像大小。比如,执行apt-get cleanapt-get autoremove命令并没有起到实际作用,因为它们是在不同的层上运行的。 - iBug
@iBug,你能提供一个改进的例子作为答案吗?对于一个Docker新手来说,不清楚如何在同一层中运行它们。 - Andre M
@AndreM Siri-Piell的回答是一个更好的例子,只是没有将清理步骤(例如apt-get clean)整合到相同的apt-get install层中。 - iBug

2

这是一个更好的DockerFile版本:

FROM ubuntu:20.04

# Specify a workdir, to better organize your files inside the container. 
WORKDIR /yourapp

# Update package lists and install required packages
RUN apt-get update && \
    apt-get install -y wget software-properties-common gnupg2 winbind xvfb

# Add Wine repository and install Wine
RUN dpkg --add-architecture i386 && \
    wget -nc https://dl.winehq.org/wine-builds/winehq.key && \
    apt-key add winehq.key && \
    add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \
    apt-get update && \
    apt-get install -y winehq-stable

# Install additional packages and configure Wine
RUN apt-get install -y winetricks && \
    winetricks msxml6

# Cleanup unnecessary files
RUN apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ENV WINEDEBUG=fixme-all

COPY app /root/catalyst
COPY startup.sh /root/startup.sh
RUN chmod gou+x /root/startup.sh

EXPOSE 9000

CMD ["/root/startup.sh"]

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community
你能解释一下这种方式更好的原因吗?这将有助于超越具体的解决方案,让人们理解你为什么做某些事情。 - Andre M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接