diff --git a/tools/linuxfs/overlay/usr/local/bin/droiddeck-xbox b/tools/linuxfs/overlay/usr/local/bin/droiddeck-xbox index 2fa1199a1..e9fd668ce 100755 --- a/tools/linuxfs/overlay/usr/local/bin/droiddeck-xbox +++ b/tools/linuxfs/overlay/usr/local/bin/droiddeck-xbox @@ -129,10 +129,12 @@ def register_classes(proton, prefix, env): source = Path(temporary) / 'classes.reg' source.write_bytes(b'\xff\xfe' + text.encode('utf-16-le')) try: - subprocess.run([proton, 'run', 'reg.exe', 'import', 'Z:' + str(source).replace('/', '\\')], - stdout=sys.stderr, env=env, timeout=90) + failed = subprocess.run([proton, 'run', 'reg.exe', 'import', 'Z:' + str(source).replace('/', '\\')], + stdout=sys.stderr, env=env, timeout=90).returncode != 0 except subprocess.TimeoutExpired: - print('droiddeck-xbox: Windows Runtime class registration timed out', file=sys.stderr) + failed = True + if failed: + print('droiddeck-xbox: Windows Runtime class registration failed; launching without it', file=sys.stderr) def wine(argv, source_env=None): diff --git a/tools/tests/test_xbox_launch.py b/tools/tests/test_xbox_launch.py index f578ef0e5..2d7aaecd9 100644 --- a/tools/tests/test_xbox_launch.py +++ b/tools/tests/test_xbox_launch.py @@ -1,8 +1,10 @@ +import io import json import os from pathlib import Path import runpy import socket +import subprocess import tempfile import threading import unittest @@ -140,6 +142,7 @@ class XboxLaunchTest(unittest.TestCase): imported = [] def run(argv, **kwargs): imported.append(Path(argv[4][2:].replace('\\', '/')).read_bytes()[2:].decode('utf-16-le')) + return subprocess.CompletedProcess(argv, 0) with patch('subprocess.run', side_effect=run) as child: xbox['register_classes']('/selected/proton', prefix, {'A': '1'}) self.assertEqual(child.call_args.args[0][:4], ['/selected/proton', 'run', 'reg.exe', 'import']) @@ -154,3 +157,13 @@ class XboxLaunchTest(unittest.TestCase): (prefix / 'system.reg').unlink() xbox['register_classes']('/selected/proton', prefix, {}) child.assert_not_called() + + def test_failed_class_registration_is_reported_and_launch_continues(self): + with tempfile.TemporaryDirectory() as root: + prefix = Path(root) + (prefix / 'system.reg').write_text('') + for outcome in ({'return_value': subprocess.CompletedProcess([], 1)}, + {'side_effect': subprocess.TimeoutExpired('reg.exe', 90)}): + with patch('subprocess.run', **outcome), patch('sys.stderr', new_callable=io.StringIO) as err: + self.assertIsNone(xbox['register_classes']('/selected/proton', prefix, {})) + self.assertIn('registration failed', err.getvalue())