deepin-wine icon indicating copy to clipboard operation
deepin-wine copied to clipboard

【解决办法】容器重新启动后被重置问题

Open thep0y opened this issue 2 years ago • 3 comments

下面的内容不一定是最恰当的方法,仅供参考。


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 "$@"
}

thep0y avatar Apr 04 '22 03:04 thep0y

建议写在下方为好,本机测试 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 "$@"
}

由于执行 UpdateAppDeployApp 后容器一定是最新版本,这样写是安全的。

Rongronggg9 avatar May 10 '22 05:05 Rongronggg9

感谢。此方案优于您在 #217 的方案。

yi-ge avatar Jun 12 '22 14:06 yi-ge

最简单的方法是把/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命令恢复这个文件,再按照上面那个方法修改。

zq1997 avatar Nov 26 '22 07:11 zq1997