refactor: windows7 support

This commit is contained in:
kangfenmao 2025-05-07 10:14:27 +08:00
parent f844a7e024
commit 8fd57d0271
20 changed files with 534 additions and 431 deletions

View File

@ -38,24 +38,21 @@ files:
- '!node_modules/mammoth/{mammoth.browser.js,mammoth.browser.min.js}' - '!node_modules/mammoth/{mammoth.browser.js,mammoth.browser.min.js}'
asarUnpack: asarUnpack:
- resources/** - resources/**
- '**/*.{metal,exp,lib}' - '**/*.{node,dll,metal,exp,lib}'
win: win:
executableName: Cherry Studio executableName: Cherry Studio
artifactName: ${productName}-${version}-${arch}-setup.${ext} artifactName: ${productName}-${version}-portable.${ext}
target: target:
- target: nsis - target: nsis
- target: portable - target: portable
nsis: nsis:
artifactName: ${productName}-${version}-${arch}-setup.${ext} artifactName: ${productName}-${version}-setup.${ext}
shortcutName: ${productName} shortcutName: ${productName}
uninstallDisplayName: ${productName} uninstallDisplayName: ${productName}
createDesktopShortcut: always createDesktopShortcut: always
allowToChangeInstallationDirectory: true allowToChangeInstallationDirectory: true
oneClick: false oneClick: false
include: build/nsis-installer.nsh include: build/nsis-installer.nsh
buildUniversalInstaller: false
portable:
artifactName: ${productName}-${version}-${arch}-portable.${ext}
mac: mac:
entitlementsInherit: build/entitlements.mac.plist entitlementsInherit: build/entitlements.mac.plist
notarize: false notarize: false
@ -67,11 +64,20 @@ mac:
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
target: target:
- target: dmg - target: dmg
arch:
- arm64
- x64
- target: zip - target: zip
arch:
- arm64
- x64
linux: linux:
artifactName: ${productName}-${version}-${arch}.${ext} artifactName: ${productName}-${version}-${arch}.${ext}
target: target:
- target: AppImage - target: AppImage
arch:
- arm64
- x64
maintainer: electronjs.org maintainer: electronjs.org
category: Utility category: Utility
desktop: desktop:
@ -80,13 +86,15 @@ linux:
mimeTypes: mimeTypes:
- x-scheme-handler/cherrystudio - x-scheme-handler/cherrystudio
publish: publish:
provider: generic # provider: generic
url: https://releases.cherry-ai.com # url: https://cherrystudio.ocool.online
provider: github
repo: cherry-studio
owner: CherryHQ
electronDownload: electronDownload:
mirror: https://npmmirror.com/mirrors/electron/ mirror: https://npmmirror.com/mirrors/electron/
afterPack: scripts/after-pack.js afterPack: scripts/after-pack.js
afterSign: scripts/notarize.js afterSign: scripts/notarize.js
artifactBuildCompleted: scripts/artifact-build-completed.js
releaseInfo: releaseInfo:
releaseNotes: | releaseNotes: |
新增对 grok-2-image 和 gpt-4o-image 图像支持 新增对 grok-2-image 和 gpt-4o-image 图像支持

View File

@ -1,5 +1,6 @@
import react from '@vitejs/plugin-react-swc' import react from '@vitejs/plugin-react-swc'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite' import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import fs from 'fs'
import { resolve } from 'path' import { resolve } from 'path'
import { visualizer } from 'rollup-plugin-visualizer' import { visualizer } from 'rollup-plugin-visualizer'
@ -37,7 +38,27 @@ export default defineConfig({
}, },
build: { build: {
rollupOptions: { rollupOptions: {
external: ['@libsql/client'] external: ['@libsql/client'],
plugins: [
{
name: 'inject-windows7-polyfill',
generateBundle(_, bundle) {
// 遍历所有生成的文件
for (const fileName in bundle) {
const chunk = bundle[fileName]
if (
chunk.type === 'chunk' &&
chunk.isEntry &&
chunk.fileName.includes('index.js') // 匹配主进程入口文件
) {
const code = fs.readFileSync('src/main/polyfill/windows7-patch.js', 'utf-8')
// 在文件末尾插入自定义代码
chunk.code = code + '\r\n' + chunk.code
}
}
}
}
]
} }
} }
}, },
@ -50,6 +71,10 @@ export default defineConfig({
} }
}, },
renderer: { renderer: {
define: {
// 使用方法 (Windows CMD): set CUSTOM_APP_NAME=AppName && yarn run dev
'process.env.CUSTOM_APP_NAME': JSON.stringify(process.env.CUSTOM_APP_NAME)
},
plugins: [ plugins: [
react({ react({
plugins: [ plugins: [

View File

@ -26,6 +26,7 @@
"build:win": "dotenv npm run build && electron-builder --win --x64 --arm64", "build:win": "dotenv npm run build && electron-builder --win --x64 --arm64",
"build:win:x64": "dotenv npm run build && electron-builder --win --x64", "build:win:x64": "dotenv npm run build && electron-builder --win --x64",
"build:win:arm64": "dotenv npm run build && electron-builder --win --arm64", "build:win:arm64": "dotenv npm run build && electron-builder --win --arm64",
"build:win7": "xcopy \"src\\patch\\windows7\\\" \"node_modules\\\" /E /Y && dotenv npm run build && electron-builder --win --x64",
"build:mac": "dotenv electron-vite build && electron-builder --mac --arm64 --x64", "build:mac": "dotenv electron-vite build && electron-builder --mac --arm64 --x64",
"build:mac:arm64": "dotenv electron-vite build && electron-builder --mac --arm64", "build:mac:arm64": "dotenv electron-vite build && electron-builder --mac --arm64",
"build:mac:x64": "dotenv electron-vite build && electron-builder --mac --x64", "build:mac:x64": "dotenv electron-vite build && electron-builder --mac --x64",
@ -70,15 +71,19 @@
"@electron-toolkit/utils": "^3.0.0", "@electron-toolkit/utils": "^3.0.0",
"@electron/notarize": "^2.5.0", "@electron/notarize": "^2.5.0",
"@langchain/community": "^0.3.36", "@langchain/community": "^0.3.36",
"@libsql/client": "^0.15.2",
"@libsql/win32-x64-msvc": "^0.5.4",
"@strongtz/win32-arm64-msvc": "^0.4.7", "@strongtz/win32-arm64-msvc": "^0.4.7",
"@types/react-infinite-scroll-component": "^5.0.0", "@types/react-infinite-scroll-component": "^5.0.0",
"adm-zip": "^0.5.16", "adm-zip": "^0.5.16",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"async-mutex": "^0.5.0", "async-mutex": "^0.5.0",
"blob-polyfill": "^9.0.20240710",
"bufferutil": "^4.0.9", "bufferutil": "^4.0.9",
"color": "^5.0.0", "color": "^5.0.0",
"diff": "^7.0.0", "diff": "^7.0.0",
"docx": "^9.0.2", "docx": "^9.0.2",
"domexception": "^4.0.0",
"electron-log": "^5.1.5", "electron-log": "^5.1.5",
"electron-store": "^8.2.0", "electron-store": "^8.2.0",
"electron-updater": "patch:electron-updater@npm%3A6.6.3#~/.yarn/patches/electron-updater-npm-6.6.3-9269dbaf84.patch", "electron-updater": "patch:electron-updater@npm%3A6.6.3#~/.yarn/patches/electron-updater-npm-6.6.3-9269dbaf84.patch",
@ -90,7 +95,9 @@
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"got-scraping": "^4.1.1", "got-scraping": "^4.1.1",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
"libsql": "^0.5.4",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"node-fetch": "2",
"node-stream-zip": "^1.15.0", "node-stream-zip": "^1.15.0",
"officeparser": "^4.1.1", "officeparser": "^4.1.1",
"os-proxy-config": "^1.1.2", "os-proxy-config": "^1.1.2",
@ -99,6 +106,7 @@
"turndown": "^7.2.0", "turndown": "^7.2.0",
"turndown-plugin-gfm": "^1.0.2", "turndown-plugin-gfm": "^1.0.2",
"undici": "^7.4.0", "undici": "^7.4.0",
"web-streams-polyfill": "^4.1.0",
"webdav": "^5.8.0", "webdav": "^5.8.0",
"ws": "^8.18.1", "ws": "^8.18.1",
"zipread": "^1.3.3" "zipread": "^1.3.3"
@ -122,6 +130,7 @@
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.10.2",
"@mozilla/readability": "^0.6.0", "@mozilla/readability": "^0.6.0",
"@notionhq/client": "^2.2.15", "@notionhq/client": "^2.2.15",
"@peculiar/webcrypto": "^1.5.0",
"@reduxjs/toolkit": "^2.2.5", "@reduxjs/toolkit": "^2.2.5",
"@shikijs/markdown-it": "^3.2.2", "@shikijs/markdown-it": "^3.2.2",
"@swc/plugin-styled-components": "^7.1.3", "@swc/plugin-styled-components": "^7.1.3",
@ -153,8 +162,8 @@
"dexie": "^4.0.8", "dexie": "^4.0.8",
"dexie-react-hooks": "^1.1.7", "dexie-react-hooks": "^1.1.7",
"dotenv-cli": "^7.4.2", "dotenv-cli": "^7.4.2",
"electron": "31.7.6", "electron": "22.3.23",
"electron-builder": "26.0.13", "electron-builder": "^24.9.1",
"electron-devtools-installer": "^3.2.0", "electron-devtools-installer": "^3.2.0",
"electron-icon-builder": "^2.0.1", "electron-icon-builder": "^2.0.1",
"electron-vite": "^2.3.0", "electron-vite": "^2.3.0",
@ -216,6 +225,9 @@
"libsql@npm:^0.4.4": "patch:libsql@npm%3A0.4.7#~/.yarn/patches/libsql-npm-0.4.7-444e260fb1.patch", "libsql@npm:^0.4.4": "patch:libsql@npm%3A0.4.7#~/.yarn/patches/libsql-npm-0.4.7-444e260fb1.patch",
"openai@npm:^4.77.0": "patch:openai@npm%3A4.87.3#~/.yarn/patches/openai-npm-4.87.3-2b30a7685f.patch", "openai@npm:^4.77.0": "patch:openai@npm%3A4.87.3#~/.yarn/patches/openai-npm-4.87.3-2b30a7685f.patch",
"pkce-challenge@npm:^4.1.0": "patch:pkce-challenge@npm%3A4.1.0#~/.yarn/patches/pkce-challenge-npm-4.1.0-fbc51695a3.patch", "pkce-challenge@npm:^4.1.0": "patch:pkce-challenge@npm%3A4.1.0#~/.yarn/patches/pkce-challenge-npm-4.1.0-fbc51695a3.patch",
"@types/domexception": "^4",
"electron": "22.3.23",
"electron-builder": "^24.9.1",
"app-builder-lib@npm:26.0.13": "patch:app-builder-lib@npm%3A26.0.13#~/.yarn/patches/app-builder-lib-npm-26.0.13-a064c9e1d0.patch", "app-builder-lib@npm:26.0.13": "patch:app-builder-lib@npm%3A26.0.13#~/.yarn/patches/app-builder-lib-npm-26.0.13-a064c9e1d0.patch",
"shiki": "3.2.2" "shiki": "3.2.2"
}, },

View File

@ -1,6 +1,7 @@
import { app } from 'electron' import { app } from 'electron'
import { getDataPath } from './utils' import { getDataPath } from './utils'
import { isWindows7 } from './utils/runtime'
const isDev = process.env.NODE_ENV === 'development' const isDev = process.env.NODE_ENV === 'development'
@ -12,12 +13,12 @@ export const DATA_PATH = getDataPath()
export const titleBarOverlayDark = { export const titleBarOverlayDark = {
height: 40, height: 40,
color: 'rgba(0,0,0,0)', color: isWindows7() ? '#1c1c1c' : 'rgba(0,0,0,0)',
symbolColor: '#ffffff' symbolColor: '#ffffff'
} }
export const titleBarOverlayLight = { export const titleBarOverlayLight = {
height: 40, height: 40,
color: 'rgba(255,255,255,0)', color: isWindows7() ? '#f4f4f4' : 'rgba(255,255,255,0)',
symbolColor: '#000000' symbolColor: '#000000'
} }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,36 @@
console.info('inject polyfill win7')
// fix for node_modules\@libsql\isomorphic-fetch\node.cjs
if (!globalThis.fetch) {
globalThis.fetch = require('node-fetch')
}
if (!globalThis.Request) {
const { Request, Headers } = require('node-fetch')
globalThis.Request = Request
globalThis.Headers = Headers
}
// fix for node_modules/undici/lib/web/fetch/webidl.js
if (!globalThis.Blob) {
const { Blob } = require('blob-polyfill')
globalThis.Blob = Blob
}
// fix for node_modules/undici/lib/web/fetch/webidl.js
if (!globalThis.ReadableStream) {
const { ReadableStream, TransformStream } = require('web-streams-polyfill')
globalThis.ReadableStream = ReadableStream
globalThis.TransformStream = TransformStream
console.log('ReadableStream', ReadableStream)
}
if (!globalThis.DOMException) {
globalThis.DOMException = require('domexception')
}
if (!globalThis.crypto) {
const { Crypto } = require('@peculiar/webcrypto')
globalThis.crypto = new Crypto()
}
console.info('inject polyfill win7 ok')

View File

@ -315,7 +315,7 @@ class FileStorage {
fileName: string, fileName: string,
content: string, content: string,
options?: SaveDialogOptions options?: SaveDialogOptions
): Promise<string | null> => { ): Promise<string | null | undefined> => {
try { try {
const result: SaveDialogReturnValue = await dialog.showSaveDialog({ const result: SaveDialogReturnValue = await dialog.showSaveDialog({
title: '保存文件', title: '保存文件',

View File

@ -1,4 +1,8 @@
import { ProxyConfig as _ProxyConfig, session } from 'electron' // import { ProxyConfig as _ProxyConfig, session } from 'electron'
import { session } from 'electron'
declare type _ProxyConfig = any;
import { socksDispatcher } from 'fetch-socks' import { socksDispatcher } from 'fetch-socks'
import { getSystemProxy } from 'os-proxy-config' import { getSystemProxy } from 'os-proxy-config'
import { ProxyAgent as GeneralProxyAgent } from 'proxy-agent' import { ProxyAgent as GeneralProxyAgent } from 'proxy-agent'

View File

@ -7,6 +7,7 @@ import iconDark from '../../../build/tray_icon_dark.png?asset'
import iconLight from '../../../build/tray_icon_light.png?asset' import iconLight from '../../../build/tray_icon_light.png?asset'
import { configManager } from './ConfigManager' import { configManager } from './ConfigManager'
import { windowService } from './WindowService' import { windowService } from './WindowService'
import { APP_NAME } from '../../shared/app-meta'
export class TrayService { export class TrayService {
private static instance: TrayService private static instance: TrayService
@ -70,7 +71,7 @@ export class TrayService {
this.tray.setContextMenu(contextMenu) this.tray.setContextMenu(contextMenu)
} }
this.tray.setToolTip('Cherry Studio') this.tray.setToolTip(APP_NAME || 'Cherry Studio')
this.tray.on('right-click', () => { this.tray.on('right-click', () => {
this.tray?.popUpContextMenu(contextMenu) this.tray?.popUpContextMenu(contextMenu)

View File

@ -0,0 +1,7 @@
import os from 'os'
export function isWindows7() {
if (process.platform !== 'win32') return false
const version = os.release()
return version.startsWith('6.1') // Windows 7 的版本号为 6.1
}

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 550 KiB

View File

@ -21,7 +21,8 @@ import { setMinappsOpenLinkExternal } from '@renderer/store/settings'
import { MinAppType } from '@renderer/types' import { MinAppType } from '@renderer/types'
import { delay } from '@renderer/utils' import { delay } from '@renderer/utils'
import { Avatar, Drawer, Tooltip } from 'antd' import { Avatar, Drawer, Tooltip } from 'antd'
import { WebviewTag } from 'electron' // import { WebviewTag } from 'electron'
declare type WebviewTag = any
import { useEffect, useMemo, useRef, useState } from 'react' import { useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import BeatLoader from 'react-spinners/BeatLoader' import BeatLoader from 'react-spinners/BeatLoader'

View File

@ -1,4 +1,5 @@
import { WebviewTag } from 'electron' // import { WebviewTag } from 'electron'
declare type WebviewTag = any
import { memo, useEffect, useRef } from 'react' import { memo, useEffect, useRef } from 'react'
/** /**

View File

@ -1,5 +1,8 @@
import * as AppMeta from '../../../shared/app-meta'
export { default as UserAvatar } from '@renderer/assets/images/avatar.png' export { default as UserAvatar } from '@renderer/assets/images/avatar.png'
export { default as AppLogo } from '@renderer/assets/images/logo.png' export { default as AppLogo } from '@renderer/assets/images/logo.png'
export const APP_NAME = 'Cherry Studio' export const APP_NAME = AppMeta.APP_NAME
export const APP_IS_CUSTOM_PRODUCT = AppMeta.APP_IS_CUSTOM_PRODUCT
export const isLocalAi = false export const isLocalAi = false

View File

@ -3,6 +3,7 @@ import KeyvStorage from '@kangfenmao/keyv-storage'
import { startAutoSync } from './services/BackupService' import { startAutoSync } from './services/BackupService'
import { startNutstoreAutoSync } from './services/NutstoreService' import { startNutstoreAutoSync } from './services/NutstoreService'
import store from './store' import store from './store'
import { APP_NAME, APP_IS_CUSTOM_PRODUCT } from './config/env'
function initSpinner() { function initSpinner() {
const spinner = document.getElementById('spinner') const spinner = document.getElementById('spinner')
@ -32,3 +33,7 @@ function initAutoSync() {
initSpinner() initSpinner()
initKeyv() initKeyv()
initAutoSync() initAutoSync()
if (APP_IS_CUSTOM_PRODUCT) {
document.title = APP_NAME
}

4
src/shared/app-meta.ts Normal file
View File

@ -0,0 +1,4 @@
export const DEFAULT_APP_NAME = 'Cherry Studio'
export const APP_NAME = process.env.CUSTOM_APP_NAME || DEFAULT_APP_NAME
// 是否是定制化产品模式
export const APP_IS_CUSTOM_PRODUCT = APP_NAME !== DEFAULT_APP_NAME

View File

@ -2,6 +2,7 @@
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json", "extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
"include": [ "include": [
"electron.vite.config.*", "electron.vite.config.*",
"src/shared/*.ts",
"src/main/**/*", "src/main/**/*",
"src/preload/**/*", "src/preload/**/*",
"src/main/env.d.ts", "src/main/env.d.ts",

View File

@ -1,6 +1,7 @@
{ {
"extends": "@electron-toolkit/tsconfig/tsconfig.web.json", "extends": "@electron-toolkit/tsconfig/tsconfig.web.json",
"include": [ "include": [
"src/shared/*.ts",
"src/renderer/src/**/*", "src/renderer/src/**/*",
"src/preload/*.d.ts", "src/preload/*.d.ts",
"local/src/renderer/**/*", "local/src/renderer/**/*",

808
yarn.lock

File diff suppressed because it is too large Load Diff