Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for installing Mono via winetricks? #1236

Closed
kenorb opened this issue May 16, 2019 · 19 comments
Closed

Support for installing Mono via winetricks? #1236

kenorb opened this issue May 16, 2019 · 19 comments
Labels
enhancement Request for an enhancement

Comments

@kenorb
Copy link
Contributor

kenorb commented May 16, 2019

Can Winetricks install Mono MSI instead of installing it manually as per Wiki?

I'm aware it can remove_mono, but I can't see option to install it. I can see the Mono popup asking to install it when running wineboot -u, or by overriding WINEDLLOVERRIDES, e.g. WINEDLLOVERRIDES=fixme+all winetricks -v, but I'm looking for non-interactive way with minimum hassle (like winetricks mono).

Is there any reason why Mono is not on the list of libraries to install? I think in the past Mono was supported. Was there some reason to remove it?

@DarkShadow44
Copy link
Contributor

Wine automatically installs Mono, the Wiki even lists the search paths.

@kenorb
Copy link
Contributor Author

kenorb commented Jun 3, 2019

It doesn't install automatically, it shows the popup with the installer.
image
Which is not what I'm looking for.

@DarkShadow44
Copy link
Contributor

Because, as it says, it doesn't find a Mono package. Put the right msi installer in the right folder, and it'll install automatically.

For the path, see the wiki.
For the mono version, see dlls/appwiz.cpl/addons.c of the version of wine you're using.

@austin987
Copy link
Contributor

Fwiw: https://bugs.winehq.org/show_bug.cgi?id=47316

@austin987 austin987 added the enhancement Request for an enhancement label Jun 25, 2019
@a-berg
Copy link

a-berg commented Nov 14, 2020

Because, as it says, it doesn't find a Mono package. Put the right msi installer in the right folder, and it'll install automatically.

For the path, see the wiki.
For the mono version, see dlls/appwiz.cpl/addons.c of the version of wine you're using.

I think the OP was referring to that already, that he/she doesn't want to use that "manual" method of copying the msi to a folder, and instead would like to do something like winetricks mono and have it done automatically

@Botspot
Copy link

Botspot commented Jan 8, 2022

Any updates on this? I'm interested in doing the same thing.

@austin987
Copy link
Contributor

No updates. The main problem is that I can't see an easy way to figure out what version of mono a given wine version needs without hard coding it (i.e., the value isn't in the registry/plain text anywhere, just embedded in mscoree.dll/appwiz.cpl).

And given that wine automatically gets mono on first boot/has an automated option already, it's a lower priority.

@Botspot
Copy link

Botspot commented Jan 10, 2022

And given that wine automatically gets mono on first boot/has an automated option already, it's a lower priority.

On my system, when updating a prefix, wine displays two pop-up windows asking if I want to download Mono and asking if I want to download Gecko. This might not seem like a big deal for one wine prefix, but when managing many prefixes, it's very boring to click OK hundreds of times... There has got to be a way to install Mono and Gecko unattended.

@austin987
Copy link
Contributor

There is:
https://wiki.winehq.org/Gecko

TL;DR: put the .msi files for gecko/mono in ~/.cache/wine.

@Botspot
Copy link

Botspot commented Jan 10, 2022

TL;DR: put the .msi files for gecko/mono in ~/.cache/wine.

Would it be possible to place those files in a universal location, rather than in one user's home directory?
And yes, I've seen the wiki, and how it says to place files in /usr/share/wine/gecko, problem is that folder doesn't exist. I have manually installed wine to /opt/wine. (So the wine command is a symlink to /opt/wine/bin/wine)
In my case, where would I place the .msi file?

@austin987
Copy link
Contributor

Look closer at the wiki:
If you installed Wine in some $prefix rather than /usr, $prefix/share/wine/gecko/ before /usr/share/wine/gecko. (e.g. if you installed it from source, then place the files in /usr/local/share/wine/gecko).

(or if you have wine in /usr, then make that directory and put the msi files there).

@Botspot
Copy link

Botspot commented Jan 11, 2022

Look closer at the wiki: If you installed Wine in some $prefix rather than /usr, $prefix/share/wine/gecko/ before /usr/share/wine/gecko. (e.g. if you installed it from source, then place the files in /usr/local/share/wine/gecko).

(or if you have wine in /usr, then make that directory and put the msi files there).

After some more investigation, I have no idea what is happening!
After trial and error, I found that these commands will prevent the Mono and Gecko dialogs from appearing when booting a prefix for the first time. (Presumably that means that Gecko and Mono are installed automatically)

#mono
mkdir -p /opt/wine/mono
wget -O /opt/wine/mono.tar.xz "https://dl.winehq.org/wine/wine-mono/5.1.0/wine-mono-5.1.0-x86.tar.xz"
tar -xf /opt/wine/mono.tar.xz -C /opt/wine/mono
rm /opt/wine/mono.tar.xz

#gecko
mkdir -p /opt/wine/gecko
wget -O /opt/wine/gecko/gecko.tar.bz2 "https://dl.winehq.org/wine/wine-gecko/2.47.1/wine-gecko-2.47.1-x86.tar.bz2" 
tar -xf /opt/wine/gecko/gecko.tar.bz2 -C /opt/wine/gecko
rm /opt/wine/gecko/gecko.tar.bz2

Booting a Wine prefix now finishes completely unattended! :)
Except for one thing: I don't think gecko or mono are fully installed.
Here's a screenshot of wine uninstaller:
2022-01-10-103707_1920x1080_scrot
As you can see, there is only one item in the list. Strange.

After deleting /opt/wine/mono and /opt/wine/gecko, I tried booting a new wine prefix. Two dialogs appeared, asking to install gecko and mono. I clicked Install for each one. After wineboot finished, here's what wine uninstaller looked like:
2022-01-10-190852_1920x1080_scrot
Any idea what is going on here?

@Botspot
Copy link

Botspot commented Jan 11, 2022

I figured it out. Turns out you had to download the .msi files to /opt/wine/gecko and /opt/wine/mono, and retain the original filenames!
Everything has been sorted out, no need to reply.

@austin987
Copy link
Contributor

I don't think this is likely to be implemented, without changes upstream (see #1236 (comment))

@jflemer
Copy link

jflemer commented Apr 8, 2023

I understand this ticket is closed, but for future implementation in winetricks, or for others who end up here...

The script below works reasonably well on Ubuntu 22.04 with Wine 7.22 (winehq-devel). The detection of the wine install prefix dir might not work everywhere.
https://gist.github.com/jflemer/a1125763ea3fdb1fde2ca296675c7039

@austin987
Copy link
Contributor

I understand this ticket is closed, but for future implementation in winetricks, or for others who end up here...

The script below works reasonably well on Ubuntu 22.04 with Wine 7.22 (winehq-devel). The detection of the wine install prefix dir might not work everywhere. https://gist.github.com/jflemer/a1125763ea3fdb1fde2ca296675c7039

A neat idea, but unfortunately, not portable. strings -e seems to be a GNU extension. Running strings on macOS doesn't show the version string, afaict:

$ strings /Applications/Wine\ Devel.app/Contents/Resources/wine/lib/wine//i386-windows/appwiz.cpl | grep -i -e msi -e gecko -e mono
MsiInstallProduct failed: %lu
No MSI file
http://source.winehq.org/winegecko.php
GeckoUrl
GeckoCabDir
http://source.winehq.org/winemono.php
MonoUrl
MonoCabDir
FOLDERID_CommonOEMLinks
IID_ITfLangBarItemSink
__wine_delay_load_msi
__wine_import_msi_desc
__wine_import_msi_name
MsiInstallProductW

@jflemer
Copy link

jflemer commented Apr 21, 2023

Yeah, quite true, it is a GNU extension. So... less pretty (and slightly more error prone), but portable:

grep -a -o 'w.i.n.e.-.m.o.n.o.-.[^-]*-.[^.]*..m.s.i.' /opt/wine-devel/lib64/wine/x86_64-windows/appwiz.cpl | sed 's/\o000//g'

yields:

wine-mono-7.4.0-x86.msi

@austin987
Copy link
Contributor

That grep doesn't work on BSD grep for me:

$ grep --version
grep (BSD grep, GNU compatible) 2.6.0-FreeBSD
$ grep -a 'w.i.n.e.-.m.o.n.o.-.[^-]*-.[^.]*..m.s.i.' appwiz.cpl ; echo $?
1
$ grep -a 'w.i.n.e.-.m.o.n.o.' appwiz.cpl  ; echo $?
1 

@WheezyE
Copy link
Contributor

WheezyE commented Jun 3, 2024

fwiw, I'm also interested in winetricks verbs for winemono and winegecko.

I did some sleuthing and found a way to trigger the wine-mono or wine-gecko install window prompts:
wine control.exe appwiz.cpl install_gecko
wine control.exe appwiz.cpl install_mono

But I don't yet know how to run them silently. Using the DISPLAY=0 wine COMMANDS trick doesn't work here unfortunately. I can't find any silent flags to pass in either. As stated before, if the mono or gecko .msi files are inside of ~/.cache/wine/ or other cache's, then triggering the installers will install them silently.

wine-gecko is required for the winetricks autohotkey verb to install quietly, so a silent install option would be amazing (although the AHK verb could be re-written to just rip out its contents using 7zip). Other apps may require dotnetxx or winemono as dependencies and it would be great to have a winetricks verb for that option too.

This might be a bit messy, but one could manually install AHK into tmp and run an AHK script to press the Install button. It wouldn't work for a headless install without xserver, but otherwise a winetricks verb could be written with a silent option that way.


Some Sleuthing

Debug Setup:

  • Deleted rm -rf ~/.wine and then ran winetricks autohotkey in one console and top and a loop of pgrep -a wine in two other consoles.
  • I wiggled wine's "Wine Gecko Installer" window around with the mouse, then top reported that control.exe used more CPU cycles. Deleted the wineprefix and ran winetricks autohotkey install again with pgrep -a control.

Some interesting lines from the console output:
/opt/wine-devel/bin/wine cmd /c echo init
C:\windows\system32\control.exe appwiz.cpl install_gecko

Using grep -r appwiz inside ~/.wine, I found appwiz.cpl installed in ~/.wine/drive_c/windows/syswow64 & ~/.wine/drive_c/windows/system32.

Running wine ~/.wine/drive_c/windows/system32/control.exe starts the Wine Control Panel window.
Running wine ~/.wine/drive_c/windows/system32/control.exe appwiz.cpl starts the Wine Add/Remove Programs window.

Downloading and unzipping wine-9.9 sourcecode and using notepad++ to set folder as workspace and search all files finds install_gecko mentioned in wine9.9source\dlls\appwiz.cpl\appwiz.c & wine9.9source\dlls\mshtml\nsembed.c

From here, I can't find a way to launch silently (and no helpful strings related to 'help' 'silent' or 'quiet'), but these are relevant methods
In appwiz.c

static LONG start_params(const WCHAR *params)
{
    if(!params)
        return FALSE;

    if(!wcscmp(params, L"install_gecko")) {
        install_addon(ADDON_GECKO);
        return TRUE;
    }

    if(!wcscmp(params, L"install_mono")) {
        install_addon(ADDON_MONO);
        return TRUE;
    }

In nsembed.c

static BOOL install_wine_gecko(void)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    WCHAR app[MAX_PATH];
    WCHAR *args;
    LONG len;
    BOOL ret;

    static const WCHAR controlW[] = L"\\control.exe";
    static const WCHAR argsW[] = L" appwiz.cpl install_gecko";

    len = GetSystemDirectoryW(app, MAX_PATH-ARRAY_SIZE(controlW));
    memcpy(app+len, controlW, sizeof(controlW));

    args = malloc(len * sizeof(WCHAR) + sizeof(controlW) + sizeof(argsW));
    if(!args)
        return FALSE;

    memcpy(args, app, len*sizeof(WCHAR) + sizeof(controlW));
    memcpy(args + len + ARRAY_SIZE(controlW)-1, argsW, sizeof(argsW));

    TRACE("starting %s\n", debugstr_w(args));

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    ret = CreateProcessW(app, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    free(args);
    if (ret) {
        CloseHandle(pi.hThread);
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
    }else {
        WARN("installation failed\n");
    }

    return ret;
}

In control.c

extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);

static void launch(LPCWSTR what)
{
  Control_RunDLLW(GetDesktopWindow(), 0, what, SW_SHOW);
  ExitProcess(0);
}

int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR lpszCmdLine, INT nCmdShow)
{
    InitCommonControls();

    /* no parameters - pop up whole "Control Panel" by default */
    if (!*lpszCmdLine) {
        launch(lpszCmdLine);
    }

    /* check for optional parameter */
    if (!lstrcmpiW(lpszCmdLine, L"COLOR"))
        launch(L"desk.cpl,,2");
    if (!lstrcmpiW(lpszCmdLine, L"DATE/TIME"))
        launch(L"timedate.cpl");
    if (!lstrcmpiW(lpszCmdLine, L"DESKTOP"))
        launch(L"desk.cpl");
    if (!lstrcmpiW(lpszCmdLine, L"INTERNATIONAL"))
        launch(L"intl.cpl");
    if (!lstrcmpiW(lpszCmdLine, L"KEYBOARD"))
        launch(L"main.cpl @1");
    if (!lstrcmpiW(lpszCmdLine, L"MOUSE"))
        launch(L"main.cpl");
    if (!lstrcmpiW(lpszCmdLine, L"PORTS"))
        launch(L"sysdm.cpl,,1");
    if (!lstrcmpiW(lpszCmdLine, L"PRINTERS"))
        launch(L"main.cpl @2");

    /* try to launch if a .cpl file is given directly */
    launch(lpszCmdLine);
    return 0;
}

For those who want to automate wine-mono and Gecko installs, more interesting info I learned from trial-and-error:

        # If a wine-mono .msi is already present in a cached area, then wine will install it silently by default.
        w_try "${WINE}" control.exe appwiz.cpl install_mono

        # wine-mono Installer only pays attention to .msi files (ignores .tar.gz / .tar.xz files). Version does not matter.
        #
        # wine-mono Installer will install a wine-mono*.msi if it is in any of these directories.
        #   $HOME/.cache/wine/
        #   /usr/share/wine/mono/
        #   /opt/wine/mono/
        #
        # wine-mono Installer will ignore a wine-mono*.msi if it is in any of these directories.
        #   /usr/local/share/wine/mono/
        #   $HOME/.wine/share/wine/mono/
        #   $HOME/.wine/drive_c/windows/system32/mono/
        #   $HOME/.wine/drive_c/windows/sysWoW64/mono/
        #   $HOME/.wine/drive_c/windows/syswow64/mono/
        # If a wine*gecko*.msi of the correct version for wine is already present in a cached area, then wine will install it silently by default.
        w_try "${WINE}" control.exe appwiz.cpl install_gecko
        
        # Wine Gecko Installer only pays attention to .msi files (ignores .tar.bz2 / .cab files) of the correct version for Wine.
        #
        # Wine Gecko Installer will install a proper wine-gecko*.msi if it is in any of these directories.
        #   $HOME/.cache/wine/
        #   /usr/share/wine/gecko/
        #   /opt/wine/gecko/
        #
        # Wine Gecko Installer will ignore a proper wine*gecko*.msi if it is in any of these directories.
        #   /usr/local/share/wine/gecko/
        #   $HOME/.wine/share/wine/gecko/
        #   $HOME/.wine/drive_c/windows/system32/gecko/
        #   $HOME/.wine/drive_c/windows/sysWoW64/gecko/
        #   $HOME/.wine/drive_c/windows/syswow64/gecko/

edits: Sorry to spam anybody's email inbox, just want to report this info properly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Request for an enhancement
Projects
None yet
Development

No branches or pull requests

7 participants