Repository navigation
feat(shell): ярлык в меню «Пуск» и пробуждение работающей копии (XIC-106) - #104
Merged
Merged
Conversation
…106) Пакет winget у нас portable и ярлыков не создаёт, поэтому ярлык кладёт само приложение — только по желанию: тумблер в Настройки → Общие или клик по приветствию первого запуска. Свой .lnk в Start Menu\Programs профиля через IShellLinkW, состояние — сам файл; аргумент --show сразу открывает настройки. Самопочинка на старте по правилам автозапуска: пропавший или более старый exe — переписать, другую папку той же версии не перехватывать. Вторая копия раньше молча выходила, и клик по exe давал только UAC. Теперь она сигналит сеансовое событие Local\XiControlShow (создаётся сразу за мьютексом — ранний сигнал не теряется), делится правом на передний план, и работающая копия открывает настройки или выводит вперёд уже открытое окно. Не нашла будильника — копия другого пользователя или старая версия: сообщение «уже запущен». Запуск с --autostart не будит: задача срабатывает и на возврат в сеанс. Тосты теперь ставят действие по клику на каждом показе — иначе клик по постороннему тосту исполнил бы чужое действие (создал бы ярлык без спроса). Проверено вживую на portable-копии: сообщение при старой версии, ярлык по клику на приветствие, пробуждение с окном на переднем плане, тишина на --autostart, старт ярлыком с окном, удаление тумблером. Тест на живом .lnk ловит сдвиг слотов vtable. Сборка 0/0, тесты 923/923. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Конфликт только в CHANGELOG [Unreleased]: обе ветки дописали «Добавлено». Оставлены обе стороны — сначала XIC-104 из main, затем два пункта XIC-106, «Исправлено» (XIC-103) как в main. Сборка 0/0, тесты 961/961. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Закрывает XIC-106: https://linear.app/oksion/issue/XIC-106
Проблема
Пользователи (Redmi Book Pro 2025, TM2409) просят ярлык в меню «Пуск». Пакет winget ставит XiControl как
portable, а такой пакет ярлыков не создаёт, инсталлятора у нас нет — найти приложение можно только по exe. Вторая копия при этом молча выходила (Global\XiControlMutex→return), так что повторный запуск не давал ничего, кроме запроса UAC.Что сделано
StartMenuShortcut.cs(новый) — свой.lnkв Start Menu\Programs профиля черезIShellLinkW, без зависимостей. Только по явному действию: тумблер или клик по приветствию первого запуска. Состояние — сам файл, поля в конфиге нет. Аргумент--showсразу открывает настройки. Самопочинка на старте по правиламAutoStart: пропавший или более старый exe — переписать, другую папку той же версии не перехватывать (две portable-копии не дерутся).InstanceWake.cs(новый) — будильник второй копии: auto-reset событиеLocal\XiControlShowсоздаётся сразу за мьютексом, поэтому ранний сигнал не теряется. Вторая копия делаетAllowSetForegroundWindowи сигналит, первая открывает настройки или выводит вперёд уже открытое окно без пересборки. Событие сеансовое при глобальном мьютексе: копия другого пользователя или старая версия будильника не найдёт — тогда сообщение «уже запущен».Program.cs—Main(string[] args); запуск с--autostartпо-прежнему молча выходит: задача срабатывает и на возврат в сеанс (ConsoleConnect), иначе окно выскакивало бы на каждом переключении пользователей.TrayApp.cs—AttachWake, предложение ярлыка в приветствии первого запуска, тосты через общийBalloon(...): действие по клику ставится на каждом показе. Раньше_pendingUpdateUrlпереживал показ следующего тоста — клик по постороннему уведомлению мог открыть страницу релиза; с ярлыком это создавало бы его без спроса.SettingsActions.GetStartMenu/SetStartMenu,AppController.StartMenuEnabled/ToggleStartMenu).SettingsForm.Reveal()— вывести окно вперёд без пересборки вкладок.settings.startmenu,settings.startmenu.desc,toast.firstrun.startmenu,toast.startmenu.added,toast.startmenu.failed,err.running.elsewhere.CHANGELOG.md,README.md/README.ru.md(фича, вкладка «Общие», portable-раздел, абзац про ярлык и повторный запуск),CLAUDE.md(Что это,Program.cs,StartMenuShortcut/InstanceWake). ROADMAP не трогал — состав v0.19.0 правится в ветке XIC-104.Решения и ограничения
requireAdministrator). Ярлык черезschtasks /runотвергнут: не будит уже запущенный экземпляр и работает только при включённом автозапуске.winget uninstallярлык не уберёт — хука на удаление у portable-пакета нет; в README сказано выключить тумблер перед удалением.Проверка
dotnet build0 ошибок / 0 предупреждений,dotnet test923/923. Новый тест пишет и читает настоящий.lnkво временной папке — ловит сдвиг слотов vtableIShellLinkW, которого компилятор не видит; плюс тесты на правила самопочинки.--show, рабочая папка); ярлык при работающем приложении → вторая копия выходит, «Настройки XiControl» на переднем плане;--autostartпри работающем → тишина; ярлык при закрытом → старт сразу с окном настроек; тумблер выкл → ярлык удалён.Set(true), что у клика по тосту), самопочинка (логика под тестами), сообщение для копии другого пользователя (код общий с путём «старая версия»).🤖 Generated with Claude Code