From 2ff04f04d446f37d3ddf8e343b1e31293b28059a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Wed, 19 Feb 2025 02:53:47 +0100 Subject: [PATCH] meson: add `mpv-install` and `mpv-uninstall` helpers on Windows They call `--install` / ``--uninstall` for users who don't want to open console and do it manually, this is one-click solution. --- .github/workflows/build.yml | 5 +++-- DOCS/man/options.rst | 4 ++-- ci/build-mingw64.sh | 2 +- meson.build | 25 ++++++++++++++++++------- osdep/w32_install.c | 4 ++++ osdep/win32-console-wrapper.c | 18 +++++++++++++++++- 6 files changed, 45 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 71bdb99b5de7a..cc16e1f5b2b72 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -195,9 +195,10 @@ jobs: with: name: mpv-x86_64-windows-msvc path: | - build/mpv.??? + build/mpv*.exe + build/mpv.com + build/mpv.pdb build/vulkan-*.dll - !build/mpv.lib - name: Save Cache uses: actions/cache/save@v4 diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 930c3a0fdb503..6a634888a2ac1 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -7952,7 +7952,7 @@ Miscellaneous more details. ``--install`` - (Windows only) + (Windows only) (available also as mpv-install helper) Registers mpv as a media player on Windows. This includes adding registry entries to associate mpv with media files and protocols, as well as enabling @@ -7991,7 +7991,7 @@ Miscellaneous variable, a semicolon-separated list of paths. ``--uninstall`` - (Windows only) + (Windows only) (available also as mpv-uninstall helper) Unregisters mpv as a media player on Windows, undoing all changes made by the ``--install`` option. This will not remove mpv binary itself. diff --git a/ci/build-mingw64.sh b/ci/build-mingw64.sh index c3739c54d643a..c98d8a32b1b9d 100755 --- a/ci/build-mingw64.sh +++ b/ci/build-mingw64.sh @@ -308,7 +308,7 @@ meson compile -C $build if [ "$2" = pack ]; then mkdir -p artifact/tmp echo "Copying:" - cp -pv $build/mpv.com $build/mpv.exe artifact/ + cp -pv $build/mpv.com $build/mpv*.exe artifact/ # copy everything we can get our hands on cp -p "$prefix_dir/bin/"*.dll artifact/tmp/ shopt -s nullglob diff --git a/meson.build b/meson.build index d1ace037d51e1..f0145101173c8 100644 --- a/meson.build +++ b/meson.build @@ -1813,13 +1813,24 @@ if get_option('cplayer') mpv = executable('mpv', main_fn_source, objects: libmpv.extract_all_objects(recursive: true), dependencies: dependencies, win_subsystem: get_option('win32-subsystem'), install: true) - if win32 and get_option('win32-subsystem') != 'console' - wrapper_sources= 'osdep/win32-console-wrapper.c' - executable('mpv', wrapper_sources, c_args: ['-municode', '-fno-asynchronous-unwind-tables'], - link_args: ['-municode', '-nostartfiles', '-nodefaultlibs'], - override_options: ['b_sanitize=none'], - dependencies: cc.find_library('pathcch'), - name_suffix: 'com', install: true) + wrapper_sources = 'osdep/win32-console-wrapper.c' + wrapper_c_args = ['-municode', '-fno-asynchronous-unwind-tables'] + wrapper_kwargs = { + 'dependencies': cc.find_library('pathcch'), + 'link_args': ['-municode', '-nostartfiles', '-nodefaultlibs'], + 'override_options': 'b_sanitize=none', + 'install': true, + } + if win32 + if get_option('win32-subsystem') != 'console' + executable('mpv', wrapper_sources, c_args: wrapper_c_args, name_suffix: 'com', kwargs: wrapper_kwargs) + endif + # `--install`/`--uninstall` wrappers for mpv.exe. These are explicitly not + # console; if users want a console, they can use mpv.com directly. + executable('mpv-install', wrapper_sources, c_args: wrapper_c_args + '-DMPV_INSTALL', + win_subsystem: 'windows', kwargs: wrapper_kwargs) + executable('mpv-uninstall', wrapper_sources, c_args: wrapper_c_args + '-DMPV_UNINSTALL', + win_subsystem: 'windows', kwargs: wrapper_kwargs) endif if darwin diff --git a/osdep/w32_install.c b/osdep/w32_install.c index ac9988625d23c..a46bba052bdef 100644 --- a/osdep/w32_install.c +++ b/osdep/w32_install.c @@ -267,6 +267,8 @@ static void w32_install(struct MPContext *mpctx) wchar_t *rpath_w = mp_from_utf8(tmp, rpath); reg_add_str(log, root, KEY_MPV_APP_PATH(".exe"), L"Path", rpath_w); reg_add_str(log, root, KEY_MPV_APP_PATH(".com"), L"Path", rpath_w); + reg_add_str(log, root, KEY_MPV_APP_PATH("-install.exe"), L"Path", rpath_w); + reg_add_str(log, root, KEY_MPV_APP_PATH("-uninstall.exe"), L"Path", rpath_w); } // Name of the "Open With" entry in the context menu @@ -426,6 +428,8 @@ static void w32_uninstall(struct MPContext *mpctx) reg_del(log, root, KEY_MPV_APP_PATH(".exe"), NULL); reg_del(log, root, KEY_MPV_APP_PATH(".com"), NULL); + reg_del(log, root, KEY_MPV_APP_PATH("-install.exe"), NULL); + reg_del(log, root, KEY_MPV_APP_PATH("-uninstall.exe"), NULL); reg_del(log, root, KEY_MPV_APP, NULL); reg_del(log, root, KEY_MPV_CAPABILITIES_APP, NULL); reg_del(log, root, L"Software\\RegisteredApplications", MPV_NAME); diff --git a/osdep/win32-console-wrapper.c b/osdep/win32-console-wrapper.c index 9795a0c2987b5..7c062a6474c27 100644 --- a/osdep/win32-console-wrapper.c +++ b/osdep/win32-console-wrapper.c @@ -82,7 +82,6 @@ static DWORD cr_runproc(wchar_t *name, wchar_t *cmdline) int mainCRTStartup(void); int mainCRTStartup(void) { - wchar_t *cmd = GetCommandLineW(); wchar_t *exe = LocalAlloc(LMEM_FIXED, MP_PATH_MAX * sizeof(wchar_t)); DWORD len = GetModuleFileNameW(NULL, exe, MP_PATH_MAX); if (len < 4 || len == MP_PATH_MAX) @@ -94,9 +93,26 @@ int mainCRTStartup(void) ExitProcess(1); } + // cmd has to be modifiable, as the documentation states: + // The Unicode version of this function, CreateProcessW, can modify the + // contents of this string. +#if defined(MPV_INSTALL) + wchar_t cmd[] = L"mpv.exe --install"; +#elif defined(MPV_UNINSTALL) + wchar_t cmd[] = L"mpv.exe --no-config --uninstall"; +#else + wchar_t *cmd = GetCommandLineW(); + // Set an environment variable so the child process can tell whether it // was started from this wrapper and attach to the console accordingly SetEnvironmentVariableW(L"_started_from_console", L"yes"); +#endif ExitProcess(cr_runproc(exe, cmd)); } + +int WinMainCRTStartup(void); +int WinMainCRTStartup(void) +{ + return mainCRTStartup(); +}