portable
This commit is contained in:
parent
b65ff88896
commit
7f90027647
@ -1,5 +1,5 @@
|
|||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path'); // 添加缺失的path模块导入
|
||||||
const { app } = require('electron');
|
const { app } = require('electron');
|
||||||
|
|
||||||
// 判断是否为开发环境
|
// 判断是否为开发环境
|
||||||
@ -7,14 +7,27 @@ const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged;
|
|||||||
|
|
||||||
// 检测是否为便携模式
|
// 检测是否为便携模式
|
||||||
let isPortable = false;
|
let isPortable = false;
|
||||||
const exePath = app.getPath('exe');
|
let appDir;
|
||||||
const appDir = path.dirname(exePath);
|
let portableFlagPath;
|
||||||
const portableFlagPath = path.join(appDir, 'portable.txt');
|
|
||||||
|
|
||||||
// 如果应用目录中存在portable.txt文件,则启用便携模式
|
// 确保app已经初始化后再获取路径
|
||||||
if (!isDev && fs.existsSync(portableFlagPath)) {
|
if (app && app.getPath) {
|
||||||
|
try {
|
||||||
|
const exePath = app.getPath('exe');
|
||||||
|
appDir = path.dirname(exePath);
|
||||||
|
portableFlagPath = path.join(appDir, 'portable.txt');
|
||||||
|
|
||||||
|
// 如果应用目录中存在portable.txt文件,则启用便携模式
|
||||||
|
if (!isDev && fs.existsSync(portableFlagPath)) {
|
||||||
isPortable = true;
|
isPortable = true;
|
||||||
console.log('启用便携模式');
|
console.log('启用便携模式');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取应用路径时出错:', error);
|
||||||
|
appDir = process.cwd();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appDir = process.cwd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据模式选择数据目录
|
// 根据模式选择数据目录
|
||||||
@ -49,5 +62,7 @@ function getUserDbPath() {
|
|||||||
// 导出函数供其他模块使用
|
// 导出函数供其他模块使用
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getSystemDbPath,
|
getSystemDbPath,
|
||||||
getUserDbPath
|
getUserDbPath,
|
||||||
|
dataDir, // 导出数据目录路径,方便其他地方使用
|
||||||
|
isPortable // 导出便携模式状态
|
||||||
};
|
};
|
@ -41,26 +41,40 @@ protocol.registerSchemesAsPrivileged([
|
|||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
|
|
||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
|
try {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 800, // 默认宽度(实际会被最大化覆盖)
|
width: 800,
|
||||||
height: 600, // 默认高度(实际会被最大化覆盖)
|
height: 600,
|
||||||
show: false, // 先隐藏窗口,避免闪烁
|
show: true, // 直接显示窗口,避免隐藏后显示可能导致的问题
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
// 改为使用绝对路径解析
|
// 修复preload路径,使用更可靠的解析方式
|
||||||
preload: require("path").join(process.cwd(), "src/preload.js"),
|
preload: path.join(__dirname, '..', 'src', 'preload.js'),
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置隐藏菜单栏
|
// 设置隐藏菜单栏
|
||||||
mainWindow.setMenu(null);
|
mainWindow.setMenu(null);
|
||||||
|
|
||||||
// 在窗口显示前设置最大化
|
// 设置窗口最大化(放在窗口创建后,确保窗口已经初始化)
|
||||||
|
try {
|
||||||
mainWindow.maximize();
|
mainWindow.maximize();
|
||||||
// 然后显示窗口
|
} catch (error) {
|
||||||
mainWindow.show();
|
console.warn('窗口最大化失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载URL
|
||||||
|
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||||
|
// Load the url of the dev server if in development mode
|
||||||
|
await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
|
||||||
|
if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
|
||||||
|
} else {
|
||||||
|
createProtocol("app");
|
||||||
|
// Load the index.html when not in development
|
||||||
|
mainWindow.loadURL("app://./index.html");
|
||||||
|
}
|
||||||
|
|
||||||
// 添加窗口关闭事件监听
|
// 添加窗口关闭事件监听
|
||||||
mainWindow.on("close", (event) => {
|
mainWindow.on("close", (event) => {
|
||||||
@ -104,14 +118,20 @@ async function createWindow() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
// 添加错误监听
|
||||||
// Load the url of the dev server if in development mode
|
mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
|
||||||
await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
|
console.error(`页面加载失败: ${errorCode} - ${errorDescription}`);
|
||||||
if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
|
});
|
||||||
} else {
|
|
||||||
createProtocol("app");
|
// 添加崩溃监听
|
||||||
// Load the index.html when not in development
|
mainWindow.webContents.on('crashed', (event, killed) => {
|
||||||
mainWindow.loadURL("app://./index.html");
|
console.error(`渲染进程崩溃: killed=${killed}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('创建窗口时出错:', error);
|
||||||
|
// 如果创建窗口失败,显示错误对话框
|
||||||
|
dialog.showErrorBox('应用启动失败', `无法创建应用窗口: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +195,7 @@ const sqlite3 = require("sqlite3").verbose();
|
|||||||
|
|
||||||
// 在app.on('ready')事件中添加
|
// 在app.on('ready')事件中添加
|
||||||
app.on("ready", async () => {
|
app.on("ready", async () => {
|
||||||
|
try {
|
||||||
// 禁用Vue DevTools扩展
|
// 禁用Vue DevTools扩展
|
||||||
/*
|
/*
|
||||||
if (isDevelopment && !process.env.IS_TEST) {
|
if (isDevelopment && !process.env.IS_TEST) {
|
||||||
@ -260,7 +281,18 @@ app.on("ready", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 检测是否为便携模式运行
|
// 检测是否为便携模式运行
|
||||||
|
try {
|
||||||
|
const isInitialized = await checkDatabaseInitialized();
|
||||||
|
console.log(`应用启动 - 数据库状态: ${isInitialized ? '已初始化' : '未初始化'}`);
|
||||||
createWindow();
|
createWindow();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查数据库状态时出错:', error);
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('应用初始化失败:', error);
|
||||||
|
dialog.showErrorBox('应用初始化失败', `无法初始化应用: ${error.message}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Exit cleanly on request from parent process in development mode.
|
// Exit cleanly on request from parent process in development mode.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs'); // 添加缺失的fs模块导入
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
|
|
||||||
@ -23,7 +23,6 @@ function deleteFolderRecursive(dir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建打包前的准备工作
|
// 创建打包前的准备工作
|
||||||
// 在prepareForBuild函数中添加
|
|
||||||
function prepareForBuild() {
|
function prepareForBuild() {
|
||||||
console.log('开始准备Windows 7便携应用打包...');
|
console.log('开始准备Windows 7便携应用打包...');
|
||||||
|
|
||||||
@ -69,20 +68,64 @@ function buildPortableApp() {
|
|||||||
process.env.ELECTRON_BUILDER_SKIP_NOTARIZATION = 'true';
|
process.env.ELECTRON_BUILDER_SKIP_NOTARIZATION = 'true';
|
||||||
process.env.ELECTRON_SKIP_NOTARIZE = 'true';
|
process.env.ELECTRON_SKIP_NOTARIZE = 'true';
|
||||||
|
|
||||||
// 使用最基本的命令行参数,移除不支持的--no-sign
|
// 使用最基本的命令行参数
|
||||||
execSync(
|
execSync(
|
||||||
'npm run electron:build -- --win portable --ia32 --x64 --publish never',
|
'npm run electron:build -- --win portable --ia32 --x64 --publish never',
|
||||||
{ stdio: 'inherit' }
|
{ stdio: 'inherit' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 构建完成后,创建最终的便携应用结构
|
||||||
|
console.log('创建便携应用最终结构...');
|
||||||
|
createPortableStructure();
|
||||||
|
|
||||||
console.log('Windows 7便携应用构建完成!');
|
console.log('Windows 7便携应用构建完成!');
|
||||||
console.log('构建产物位于 dist_electron 目录');
|
console.log('构建产物位于 dist_electron 目录下的 portable-app 文件夹');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('构建失败:', error);
|
console.error('构建失败:', error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建便携应用最终结构:可执行文件和data目录在同一级
|
||||||
|
function createPortableStructure() {
|
||||||
|
const distDir = path.join(__dirname, 'dist_electron');
|
||||||
|
const portableAppDir = path.join(distDir, 'portable-app');
|
||||||
|
|
||||||
|
// 创建目标目录
|
||||||
|
if (fs.existsSync(portableAppDir)) {
|
||||||
|
deleteFolderRecursive(portableAppDir);
|
||||||
|
}
|
||||||
|
fs.mkdirSync(portableAppDir, { recursive: true });
|
||||||
|
|
||||||
|
// 复制可执行文件
|
||||||
|
const exeFiles = fs.readdirSync(distDir).filter(file => file.endsWith('.exe'));
|
||||||
|
if (exeFiles.length > 0) {
|
||||||
|
const exeFile = exeFiles[0];
|
||||||
|
fs.copyFileSync(path.join(distDir, exeFile), path.join(portableAppDir, exeFile));
|
||||||
|
console.log(`已复制可执行文件: ${exeFile}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建data目录并复制数据库文件
|
||||||
|
const srcDataDir = path.join(__dirname, 'data');
|
||||||
|
const destDataDir = path.join(portableAppDir, 'data');
|
||||||
|
fs.mkdirSync(destDataDir, { recursive: true });
|
||||||
|
|
||||||
|
// 复制data目录下的所有文件
|
||||||
|
if (fs.existsSync(srcDataDir)) {
|
||||||
|
const dataFiles = fs.readdirSync(srcDataDir);
|
||||||
|
dataFiles.forEach(file => {
|
||||||
|
const srcPath = path.join(srcDataDir, file);
|
||||||
|
const destPath = path.join(destDataDir, file);
|
||||||
|
fs.copyFileSync(srcPath, destPath);
|
||||||
|
console.log(`已复制数据文件: ${file}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保portable.txt文件在可执行文件同级目录
|
||||||
|
fs.copyFileSync(path.join(__dirname, 'portable.txt'), path.join(portableAppDir, 'portable.txt'));
|
||||||
|
console.log('已复制便携模式标识文件');
|
||||||
|
}
|
||||||
|
|
||||||
// 主函数
|
// 主函数
|
||||||
function main() {
|
function main() {
|
||||||
console.log('==== Windows 7便携应用打包工具 ====');
|
console.log('==== Windows 7便携应用打包工具 ====');
|
||||||
|
@ -86,7 +86,11 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
from: "data",
|
from: "data",
|
||||||
to: "data",
|
to: "data",
|
||||||
filter: ["**/*"], // 修改为包含所有文件
|
filter: ["**/*"], // 确保包含data目录下的所有文件
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "portable.txt",
|
||||||
|
to: ".", // 确保portable.txt文件放在根目录
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user