[release] Simple Wine Helper: 3rd shell script tool

Open forum for end-user questions about Wine. Before asking questions, check out the Wiki as a first step.
Forum Rules
Locked
tim110011
Level 2
Level 2
Posts: 30
Joined: Wed Jul 05, 2017 2:29 am

[release] Simple Wine Helper: 3rd shell script tool

Post by tim110011 »

This is a command-line helper tool.
It's aim is to simplify configuration and management of different versions of wine binary package and wineprefix.

Features:

work with distro package manager and winehq/wine-staging repository: create your own wine binary package repository
help you create and use wineprefix with your specified wine version, from your own wine binary package repository
work with winetricks: ablility to modify various wine settings
multiple command-line operation: store wine to your own repositoy, create wineprefix, run winecfg, run wine regedit, run winetricks, launch application
write with shell script, easy to modify and reuse

code here for some advice:

Code: Select all

#!/bin/sh

SWH_VER="1.0.20171001"

# This is a UTF-8 file
# You should see an o with two dots over it here [ö]
# You should see a micro (u with a tail) here [µ]
# You should see a trademark symbol here [™]

# Simple Wine Helper (SWH)
#   This shell script help you configure, create and use your own wine binary repository and wineprefix.
# Features:
# - work with distro package manager and winehq/wine-staging repository: create your own wine binary package repository
# - help you create and use wineprefix with your specified wine version, from your own wine binary package repository
# - work with winetricks: ablility to modify various wine settings
# - multiple command-line operation: store wine to your own repositoy, create wineprefix, run winecfg, run wine regedit, run winetricks, launch application
# - write with shell script, easy to modify and reuse
#
#   Copyright (C) 2017 佟大维 <tim110011!163.com>
#
# License:
#   This program is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later
#   version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU Lesser General Public License for more details.
#
#   You should have received a copy of the GNU Lesser General Public
#   License along with this program.  If not, see
#   <https://www.gnu.org/licenses/>.

app_config()  # application config, modify me!
{
    # ( Example Application Description )
    # Recommended dll override: xact (swh -w xact)

    export prefix="example_prefix"
    export working_version="2.18"
    #export LC_ALL=zh_CN.utf8        # for non-unicode program

    export app1dir="C:\example"
    export app1name="app.exe"
    #export app1_args=""

    #export app2dir=""
    #export app2name=""
    #export app2_args=""

    if [ -z "$app1_args" ] ; then
        export app1="$app1dir\\$app1name"
    else
        export app1="$app1dir\\$app1name $app1args"
    fi
    #if [ -z "$app2_args" ] ; then
    #    export app2="$app2dir\\$app2name"
    #else
    #    export app2="$app2dir\\$app2name $app2args"
    #fi
}

app_regsetup() # leave for application registry work
{
    :
}

swh_config()  # swh config, modify me!
{
    export swh_factory="/opt/wine-devel"      #use wine development
    #export swh_factory="/opt/wine-staging"   #use wine staging
    export swh_cellar="$HOME/_wine_cellar"    #store wine here
    export swh_table="$HOME/_wine"            #wineprefix dirs cluster
    export WINEARCH=win64
    export WINEDEBUG=fixme-all
    export WINEDLLOVERRIDES=winemenubuilder.exe=d    #swh default setting
}

swh_pinfo()
{
    echo "$(basename $0) [INFO] $1"
}

swh_error()
{
    echo "$(basename $0) [ERROR] $1" >&2
    exit 1
}

swh_storewine()
{
    if ! [ -x "$swh_factory/bin/wineserver" ] ; then
        echo "swh_factory=$swh_factory"
        swh_error "wineserver in \$swh_factory/bin: missing or not executable. install winehq or check setting in swh_config()"
    fi

    if ! [ -x "$swh_factory/bin/wine" ] ; then
        echo "swh_factory=$swh_factory"
        swh_error "wineloader in \$swh_factory/bin: missing or not executable. install winehq or check setting in swh_config()"
    fi
        factory_version=$(wine --version | tr [:upper:] [:lower:] | cut -d - -f 2- | tr -d "()" | tr " " "-")
    swh_pinfo "\$factory_version=$factory_version"
    if [ -f "$swh_cellar/$factory_version/bin/wine" ] ; then
        swh_pinfo "$swh_cellar/$factory_version exists, nothing to do."
    else
        if ! (mkdir -p "$swh_cellar/$factory_version"); then
            swh_error "swh_storewine(): mkdir error"
        fi
        if ! (cp -r "$swh_factory"/* "$swh_cellar/$factory_version"); then
            swh_error "swh_storewine(): cp error"
        fi
    fi
}

swh_diag()
{
    echo 'WINEVERPATH=$swh_cellar/$working_version'
    echo "WINEVERPATH=$swh_cellar/$working_version"
    echo 'WINEPREFIX=$swh_table/$WINEARCH/$working_version/$prefix'
    echo "WINEPREFIX=$swh_table/$WINEARCH/$working_version/$prefix"
}

swh_init()
{
    if ! [ -d "$swh_cellar/$working_version" ] ; then
        swh_diag
        swh_error "swh_init(): wine-$working_version not exist, store wine to your own repository directory before use. try ./$(basename $0) -s"
    fi
    export WINEPREFIX="$swh_table/$WINEARCH/$working_version/$prefix"
    if ! [ -d "$WINEPREFIX" ]; then
        mkdir -p "$WINEPREFIX"
    fi
    export WINEVERPATH="$swh_cellar/$working_version"
    export PATH="$WINEVERPATH/bin:$PATH"
    export WINESERVER="$WINEVERPATH/bin/wineserver"
    export WINELOADER="$WINEVERPATH/bin/wine"
    export WINEDLLPATH="$WINEVERPATH/lib/wine/fakedlls"
    export LD_LIBRARY_PATH="$WINEVERPATH/lib:$LD_LIBRARY_PATH"
}

swh_checkwine()
{
    if ! [ -d "$swh_table/$WINEARCH/$working_version/$prefix" ] || [ -z "$(ls -A $swh_table/$WINEARCH/$working_version/$prefix)" ] ; then
        swh_diag
        swh_error "swh_checkwine(): wineprefix dir not exist or is empty, explicit create it. try ./$(basename $0) -c"
    fi
    if ! [ -d "$WINEVERPATH/bin" ] ; then
        swh_diag
        swh_error "\$WINEVERPATH/bin missing."
    fi
    if ! [ -x "$WINEVERPATH/bin/wineserver" ] ; then
        swh_diag
        swh_error "wineserver in \$WINEVERPATH/bin: missing or not executable."
    fi

    if ! [ -x "$WINEVERPATH/bin/wine" ] ; then
        swh_diag
        swh_error "wineloader in \$WINEVERPATH/bin:missing or not executable."
    fi
    if ! [ -d "$WINEVERPATH/lib" ] ; then
        swh_diag
        swh_error "\$WINEVERPATH/lib missing."
    fi
}

swh_regsetup()
{
    # disable winemenubuilder.exe ## not work as expect: wine still complain missing/err winemenubuilder
    #rq=$(wine reg query "HKEY_CURRENT_USER\Software\Wine\DllOverrides" /v winemenubuilder.exe)
    #rqv=$(echo ${rq//[[:blank:]*[:cntrl:]*]/-} | awk '{ gsub(/[-]+/, "\t"); print }' | cut -f 5)
    #if ! [[ X"$rqv" == X"" ]]; then
    #    if (wine reg add "HKEY_CURRENT_USER\Software\Wine\DllOverrides" /v winemenubuilder.exe); then
    #        swh_pinfo "winemenubuilder.exe disabled."
    #    else
    #        swh_error "swh_regsetup(): Disable winemenubuilder.exe error."
    #    fi
    #else
    #    swh_pinfo "winemenubuilder.exe already disabled, nothing to do."
    #fi
    #unset rq
    #unset rqv
    
    # disable GUI crash dialog
    rq=$(wine reg query "HKEY_CURRENT_USER\Software\Wine\WineDbg" /v ShowCrashDialog)
    rqv=$(echo ${rq//[[:blank:]*[:cntrl:]*]/-} | awk '{ gsub(/[-]+/, "\t"); print }' | cut -f 5)
    if ! [[ X"$rqv" == X"0x0" ]]; then
        if (wine reg add "HKEY_CURRENT_USER\Software\Wine\WineDbg" /v ShowCrashDialog /t REG_DWORD /d 0); then
            swh_pinfo "GUI crash dialog disabled."
        else
            swh_error "swh_regsetup(): Disable GUI crash dialog error."
        fi
    else
        swh_pinfo "GUI crash dialog already disabled, nothing to do."
    fi
    unset rq
    unset rqv
}

ww_d3dcompiler_42()  # work with winetricks, use .verb file
{
    swh_tempdir="$(mktemp -d "${TMPDIR:-/tmp}/swhtemp.XXXXXXXX")"
    if ( [ -d "$swh_tempdir" ] && [ -w "$swh_tempdir" ] ); then
        cat > "$swh_tempdir"/d3dcompiler_42.verb <<"_WW_D3DCOMPILER_42_EOF_"
w_metadata d3dcompiler_42 dlls \
    title="MS d3dcompiler_42.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dcompiler_42.dll" \

load_d3dcompiler_42()
{
    dllname=d3dcompiler_42

    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab
    do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab
        do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native $dllname
}
_WW_D3DCOMPILER_42_EOF_
        winetricks "$swh_tempdir"/d3dcompiler_42.verb
    else
        swh_error "WW_D3DCOMPILER(): mktemp error."
    fi
    rm -rf "$swh_tempdir"
}

swh_help()
{
    cat << _SWH_HELP_EOF_
Usage: $(basename $0) [OPTION]
Simple Wine Helper - SWH "$SWH_VER"

OPTION:

  -s, --store                              store wine binary to your repository
  -c, --cfg, --create                      winecfg or create wineprefix
  -r [regfile], --regedit [regfile]        regedit [regfile]
  -l [application], --launch [application]
                                           run default or specified application
  -w [winetricks option], --winetricks [winetricks option]
                                           winetricks
  -ww d3dcompiler_42                       let winetricks install d3dcompiler_42
  -h, --help                               display this help and exit
      --version                            output version information and exit
  NO ARGUEMENT                             show main menu

EXAMPLES:

  $(basename $0) -l 'C:\a b\xy.exe'     run specified application
  $(basename $0) -l cmd                 run wine cmd
  $(basename $0) -w d3dcompiler_43      work with winetricks, arguement

QUICK GUIDE:
1. Install wine pagkage from winehq or wine-staging repository 
    or set swh_factory variable to your own built wine dir, 
    this directory should contain these dirs: bin lib lib64
2. Install winetricks
3. Modify settings in swh_config() app_config() function
4. (Optional) Modify settings in app_menu() function and ##main() block
5. Store wine binary to your won repository (dir): $(basename $0) -s
6. Create wineprefix, configure basic settings via winecfg: $(basename $0) -c
7. (Optional) Configure advanced settings via winetricks: $(basename $0) -w
8. Copy or move windows application to wineprefix
9. Launch application: $(basename $0) -l

NOTE:
Any version of wine (mostly your distro) installed to /bin or /usr/bin directory
(cluttered with other files) is not supported.
Plese use binary package from winehq or wine-staging repository, 
or if you build wine yourself, install it to INDEPENDENT directory, 
for example: in fedora, winehq-staging package is installed to /opt/wine-staging
Using winetricks: "Select the default wineprefix" means select THIS wineprefix
_SWH_HELP_EOF_
}

app_menu()  # menu function, modify me (optional)
{
        cat << APP_MENU_EOF_

Simple Wine Helper - SWH "$SWH_VER"

  a. run "$app1name"
  b. run "$app2name"
  y. wine cmd
  z. winefile
  1. copy wine binary to your own repository dir
  2. create wineprefix or run winecfg
  3. regedit
  4. winetricks
  5. winetricks d3dcompiler_42
  9. help
  0. exit

APP_MENU_EOF_
    echo "Input id then press Enter key."
    read -p "(a/b/y/z/1/2/3/4/5/9/0)" app_menu_input
    case $app_menu_input in
    a | A)
        swh_init
        swh_checkwine
        wine start /d "$app1dir" "$app1"
        ;;
    b | B)
        swh_init
        swh_checkwine
        wine start /d "$app2dir" "$app2"
        ;;
    y | Y)
        swh_init
        swh_checkwine
        wine cmd
        ;;
    z | Z)
        swh_init
        swh_checkwine
        wine winefile
        ;;
    1)
        swh_storewine
        ;;
    2)
        swh_init
        wine winecfg
        swh_regsetup
        app_regsetup
        ;;
    3)
        swh_init
        swh_checkwine
        regedit
        ;;
    4)
        swh_init
        swh_checkwine
        winetricks
        ;;
    5)
        swh_init
        swh_checkwine
        ww_d3dcompiler_42
        ;;
    9)
        swh_help
        ;;
    0)
        exit 0
        ;;
    *)
        swh_help
        ;;
    esac
    unset app_menu_input
}

## main()
##{
swh_config
app_config

# command line arguements, modify me (optional)
if [ $# -ge 1 ] ; then
    case "$1" in
    -l | -l1 | -lapp1 | --launch | -lmb)
        swh_init
        swh_checkwine
        if [ $# -eq 1 ] ; then
            wine start /d "$app1dir" "$app1"
        else
            # FIXME: wine start not tested; better do not specity $appndir
            shift
            # start bug fixed in wine-2.14?
            #wine start /d "$app1dir" "$app1dir\\$@"
            wine "$@"
        fi
        ;;
    -ll | -l2 | -lapp2)
        swh_init
        swh_checkwine
        wine start /d "$app2dir" "$app2"
        ;;
    -s | --store)
        swh_storewine
        ;;
    -c | --cfg | --create)
        swh_init
        wine winecfg
        swh_regsetup
        app_regsetup
        ;;
    -r | --regedit)
        swh_init
        swh_checkwine
        if [ -f "$2" ] ; then
            regedit "$2"
        else
            regedit
        fi
        ;;
    -w | --winetricks)
        swh_init
        swh_checkwine
        if [ $# -eq 1 ] ; then
            winetricks
        else
            shift
            winetricks "$@"
        fi
        ;;
    -ww | --swhwinetricks)
        swh_init
        swh_checkwine
        if [ $# -eq 2 ] ; then
            shift
            case "$1" in
            d3dcompiler_42)
                ww_d3dcompiler_42
                ;;
            *)
                swh_error "unsupported arguement. try ./$(basename $0) -ww d3dcompiler_42"
                ;;
            esac
        else
            swh_error "bad arguement. try ./$(basename $0) -ww d3dcompiler_42"
        fi
        ;;
    -h | --help)
        swh_help
        ;;
    --version)
        echo "swh-$SWH_VER"
        ;;
    *)
        swh_help
        ;;
    esac
else
    app_menu
fi
##}
I also uploaded it to github:
https://github.com/tim110011/Simple-Wine-Helper
tim110011
Level 2
Level 2
Posts: 30
Joined: Wed Jul 05, 2017 2:29 am

Post by tim110011 »

Command-line interface warpper for wine.
It's updated at github, so don't use the pasted code.

Usage: Just conside this as a CLI playonlinux, modify it as an ordinary shell script or playonlinux script.
Locked