deepin-wine
deepin-wine copied to clipboard
【解决办法】容器重新启动后被重置问题
下面的内容不一定是最恰当的方法,仅供参考。
deepin wine 的运行脚本路径为/opt/deepinwine/tools/run_v4.sh
,
生成(部署)容器的函数如下:
RunApp()
{
progpid=$(ps -ef | grep "zenity --progress --title=${BOTTLENAME}" | grep -v grep)
debug_log "run ${BOTTLENAME} progress pid $progpid"
if [ -n "$progpid" ]; then
debug_log "$BOTTLENAME is running"
exit 0
fi
if [ -d "$WINEPREFIX" ]; then
UpdateApp | progressbar "$BOTTLENAME" "更新$BOTTLENAME中..."
else
# 第一次运行会 $WINEPREFIX 不存在,故执行下面的代码
DeployApp | progressbar $BOTTLENAME "初始化$BOTTLENAME中..."
fi
CallApp "$@"
}
DeployApp()
{
# 解压 files.7z 到 $WINEPREFIX
ExtractApp "$WINEPREFIX"
# 下面的代码好像是没有执行,创建的容器里没有 PACKAGE_VERSION 文件
if UsePublicDir;then
chgrp -R users "$WINEPREFIX"
chmod -R 0775 "$WINEPREFIX"
fi
echo "$APPVER" > "$WINEPREFIX/PACKAGE_VERSION"
}
以后再运行时就会执行:
UpdateApp | progressbar "$BOTTLENAME" "更新$BOTTLENAME中..."
此函数:
UpdateApp()
{
# 由于容器中没有 PACKAGE_VERSION 文件,这个 if 语句将不会 return,
if [ -f "$WINEPREFIX/PACKAGE_VERSION" ] && [ "$(cat "$WINEPREFIX/PACKAGE_VERSION")" = "$APPVER" ]; then
return
fi
if [ -d "${WINEPREFIX}.tmpdir" ]; then
rm -rf "${WINEPREFIX}.tmpdir"
fi
# 进而执行下面的删除容器、重新部署容器的语句,所以我们在 $WINEPREFIX 修改注册表就任何意义
case $BOTTLENAME in
"Deepin-Intelligent" | "Deepin-QQ" | "Deepin-TIM" | "Deepin-WeChat" | "Deepin-WXWork" | "Deepin-Dding")
rm -rf "$WINEPREFIX"
DeployApp
return
;;
esac
ExtractApp "${WINEPREFIX}.tmpdir"
$SHELL_DIR/updater -s "${WINEPREFIX}.tmpdir" -c "${WINEPREFIX}" -v
if UsePublicDir;then
chgrp -R users "$WINEPREFIX"
chmod -R 0775 "$WINEPREFIX"
fi
rm -rf "${WINEPREFIX}.tmpdir"
echo "$APPVER" > "$WINEPREFIX/PACKAGE_VERSION"
}
解决办法有两个,一个是修改微信或QQ等 wine 程序的 desktop 中的 Exec 语句为(微信为例):
sed -i "s#Exec=\"/opt/apps/com.qq.weixin.deepin/files/run.sh\" -f %f#Exec=env WINEPREFIX=\"$HOME/.deepinwine/Deepin-WeChat\" deepin-wine6-stable \"$HOME/.deepinwine/Deepin-WeChat/drive_c/Program Files/Tencent/WeChat/WeChat.exe\"#g" /opt/apps/com.qq.weixin.deepin/entries/applications/com.qq.weixin.deepin.desktop
另一个修改此脚本,将RunApp
函数修改为:
RunApp()
{
progpid=$(ps -ef | grep "zenity --progress --title=${BOTTLENAME}" | grep -v grep)
debug_log "run ${BOTTLENAME} progress pid $progpid"
if [ -n "$progpid" ]; then
debug_log "$BOTTLENAME is running"
exit 0
fi
if [ -d "$WINEPREFIX" ]; then
UpdateApp | progressbar "$BOTTLENAME" "更新$BOTTLENAME中..."
else
# 将上面没有执行的创建PACKAGE_VERSION的语句移动到这里
mkdir $WINEPREFIX
echo "$APPVER" > "$WINEPREFIX/PACKAGE_VERSION"
DeployApp | progressbar $BOTTLENAME "初始化$BOTTLENAME中..."
fi
CallApp "$@"
}
建议写在下方为好,本机测试 UpdateApp
也无法成功创建该文件,因此当前写法当且仅当用户手动删除容器 ($WINEPREFIX
) 才会写 PACKAGE_VERSION
。若从不删除容器,该 workaround 永远不生效,且也不能起到原有的容器版本管理的作用 (一旦发生版本升级,由于仅执行 UpdateApp
分支,将丢失 PACKAGE_VERSION
文件)。
RunApp()
{
progpid=$(ps -ef | grep "zenity --progress --title=${BOTTLENAME}" | grep -v grep)
debug_log "run ${BOTTLENAME} progress pid $progpid"
if [ -n "$progpid" ]; then
debug_log "$BOTTLENAME is running"
exit 0
fi
if [ -d "$WINEPREFIX" ]; then
UpdateApp | progressbar "$BOTTLENAME" "更新$BOTTLENAME中..."
else
DeployApp | progressbar $BOTTLENAME "初始化$BOTTLENAME中..."
fi
# 将上面没有执行的创建PACKAGE_VERSION的语句移动到这里
mkdir $WINEPREFIX
echo "$APPVER" > "$WINEPREFIX/PACKAGE_VERSION"
CallApp "$@"
}
由于执行 UpdateApp
或 DeployApp
后容器一定是最新版本,这样写是安全的。
感谢。此方案优于您在 #217 的方案。
最简单的方法是把/opt/deepinwine/tools/run_v4.sh
文件中基于zenity的progressbar禁用掉。
# Check if some visual feedback is possible
-if command -v zenity >/dev/null 2>&1; then
+if false && command -v zenity >/dev/null 2>&1; then
progressbar()
因为这个progressbar的存在,导致PACKAGE_VERSION
之前一直无法被正确的构建,再导致每次启动容器都会被重置。
禁用它,除了在部署和更新时候看不见小弹窗提醒,其他没有任何影响。
已经使用其他方法修改了/opt/deepinwine/tools/run_v4.sh
的话,建议使用sudo apt install --reinstall deepin-wine-helper
命令恢复这个文件,再按照上面那个方法修改。