feat: windows install guidance (#63)

* build: add dmg/appimage and artifact metadata

* feat: enhance packaging outputs and add Windows install-path notice
This commit is contained in:
vin authored and GitHub committed 2026-02-04 18:10:26 +08:00
1 parent 080fb67974
commit ce7147025d
7 files changed
+2280 -11

No files matched your search

+120
View File
@@ -0,0 +1,120 @@
import path from 'path';
export type InstallNoticeLanguage = 'zh-CN' | 'en' | 'ru';
const installNoticeText: Record<
InstallNoticeLanguage,
{
title: string;
message: string;
detailPrefix: string;
buttons: [string, string];
}
> = {
'zh-CN': {
title: '建议从开始菜单启动',
message:
'检测到你正在从非安装路径启动应用。为了确保自动更新生效,请从开始菜单或桌面快捷方式启动。如果没有快捷方式,请重新运行安装包。',
detailPrefix: '安装目录:',
buttons: ['打开安装目录', '知道了'],
},
en: {
title: 'Please launch from the Start menu',
message:
'We detected the app is running from a non-install location. To ensure auto-updates work, launch it from the Start menu or desktop shortcut. If no shortcut exists, run the installer again.',
detailPrefix: 'Install location: ',
buttons: ['Open install folder', 'OK'],
},
ru: {
title: 'Запускайте приложение из меню «Пуск»',
message:
'Обнаружен запуск из неустановленного пути. Чтобы автообновления работали, запускайте приложение из меню «Пуск» или ярлыка. Если ярлыка нет, запустите установщик ещё раз.',
detailPrefix: 'Папка установки: ',
buttons: ['Открыть папку', 'Понятно'],
},
};
export function resolveInstallNoticeLanguage({
configLanguage,
locale,
}: {
configLanguage?: string | null;
locale?: string | null;
}): InstallNoticeLanguage {
const rawLanguage = configLanguage || locale;
if (!rawLanguage) {
return 'en';
}
const normalized = rawLanguage.toLowerCase();
if (normalized.startsWith('zh')) {
return 'zh-CN';
}
if (normalized.startsWith('ru')) {
return 'ru';
}
return 'en';
}
export function getInstallNoticeText(language: InstallNoticeLanguage) {
return installNoticeText[language] || installNoticeText.en;
}
function getPathApi(platform: string) {
if (platform === 'win32') {
return path.win32;
}
return path;
}
export function getExpectedInstallRoot({
platform,
localAppData,
appName,
}: {
platform: string;
localAppData?: string | null;
appName: string;
}) {
if (platform !== 'win32') {
return null;
}
if (!localAppData) {
return null;
}
const pathApi = getPathApi(platform);
return pathApi.resolve(pathApi.join(localAppData, appName));
}
export function isRunningFromExpectedInstallDir({
platform,
isPackaged,
localAppData,
appName,
execPath,
}: {
platform: string;
isPackaged: boolean;
localAppData?: string | null;
appName: string;
execPath: string;
}) {
if (platform !== 'win32' || !isPackaged) {
return true;
}
const expectedRoot = getExpectedInstallRoot({ platform, localAppData, appName });
if (!expectedRoot) {
return true;
}
const pathApi = getPathApi(platform);
const normalizedExecPath = pathApi.resolve(execPath);
return normalizedExecPath.toLowerCase().startsWith(expectedRoot.toLowerCase() + pathApi.sep);
}