| @@ -128,8 +128,3 @@ FORMS += \ | |||
| src/ui/free_monitor_widget.ui \ | |||
| src/ui/runtime_monitor_window.ui \ | |||
| src/ui/runtime_monitor_widget.ui | |||
| # 专用用户运行版打包时由脚本传入生成的工程资源;普通编程器构建不包含工程 | |||
| !isEmpty(RUNTIME_PROJECT_RESOURCE) { | |||
| RESOURCES += $$RUNTIME_PROJECT_RESOURCE | |||
| } | |||
| @@ -46,29 +46,10 @@ int main(int argc, char *argv[]) | |||
| // 设置组织名称,用来区分这个程序保存的 Qt 配置 | |||
| application.setOrganizationName(QStringLiteral("QtProXinJe")); | |||
| QString runtime_project_path; | |||
| const QStringList arguments = application.arguments(); | |||
| const int project_option = arguments.indexOf(QStringLiteral("--runtime-project")); | |||
| if (project_option >= 0 && project_option + 1 < arguments.size()) | |||
| { | |||
| runtime_project_path = arguments.at(project_option + 1); | |||
| } | |||
| const QFileInfo executable_info(application.applicationFilePath()); | |||
| const RuntimeProjectBundleLoadResult bundled_project_result = | |||
| RuntimeProjectBundleService::load(executable_info.absoluteFilePath()); | |||
| const QString bundled_project = executable_info.absolutePath() | |||
| + QStringLiteral("/runtime-project.json"); | |||
| if (runtime_project_path.isEmpty() | |||
| && executable_info.completeBaseName() != QStringLiteral("integrated_platform") | |||
| && QFileInfo::exists(bundled_project)) | |||
| { | |||
| runtime_project_path = bundled_project; | |||
| } | |||
| const bool embedded_runtime_project = QFile::exists( | |||
| QStringLiteral(":/runtime-project.json")); | |||
| if (bundled_project_result.status == RuntimeProjectBundleStatus::Invalid | |||
| && runtime_project_path.isEmpty() | |||
| && !embedded_runtime_project) | |||
| if (bundled_project_result.status == RuntimeProjectBundleStatus::Invalid) | |||
| { | |||
| QMessageBox::critical( | |||
| nullptr, | |||
| @@ -78,9 +59,7 @@ int main(int argc, char *argv[]) | |||
| } | |||
| const bool bundled_runtime_project = bundled_project_result.status | |||
| == RuntimeProjectBundleStatus::Loaded; | |||
| const bool user_runtime_mode = !runtime_project_path.isEmpty() | |||
| || embedded_runtime_project | |||
| || bundled_runtime_project; | |||
| const bool user_runtime_mode = bundled_runtime_project; | |||
| const ApplicationSettingsLoadResult application_settings = | |||
| ApplicationSettingsLoader::load( | |||
| @@ -93,55 +72,25 @@ int main(int argc, char *argv[]) | |||
| project_storage, application_settings.settings.projectLimits); | |||
| if (user_runtime_mode) | |||
| { | |||
| ProjectOperationResult result; | |||
| if (embedded_runtime_project && runtime_project_path.isEmpty()) | |||
| { | |||
| const QByteArray bytes = [] | |||
| { | |||
| QFile resource(QStringLiteral(":/runtime-project.json")); | |||
| return resource.open(QIODevice::ReadOnly) | |||
| ? resource.readAll() : QByteArray{}; | |||
| }(); | |||
| const QString temporary_path = QDir::tempPath() | |||
| + QStringLiteral("/qtproxinje-runtime-project.json"); | |||
| QFile temporary_file(temporary_path); | |||
| if (bytes.isEmpty() || !temporary_file.open(QIODevice::WriteOnly) | |||
| || temporary_file.write(bytes) != bytes.size()) | |||
| { | |||
| QMessageBox::critical( | |||
| nullptr, | |||
| QObject::tr("运行程序启动失败"), | |||
| QObject::tr("无法读取内嵌项目资源")); | |||
| return 2; | |||
| } | |||
| temporary_file.close(); | |||
| result = project_service.load(temporary_path.toUtf8().toStdString()); | |||
| QFile::remove(temporary_path); | |||
| } | |||
| else if (bundled_runtime_project && runtime_project_path.isEmpty()) | |||
| const QString temporary_path = QDir::tempPath() | |||
| + QStringLiteral("/qtproxinje-runtime-bundle-") | |||
| + QString::number(application.applicationPid()) | |||
| + QStringLiteral(".json"); | |||
| QFile temporary_file(temporary_path); | |||
| const QByteArray &bytes = bundled_project_result.project_data; | |||
| if (bytes.isEmpty() || !temporary_file.open(QIODevice::WriteOnly) | |||
| || temporary_file.write(bytes) != bytes.size()) | |||
| { | |||
| const QString temporary_path = QDir::tempPath() | |||
| + QStringLiteral("/qtproxinje-runtime-bundle-project.json"); | |||
| QFile temporary_file(temporary_path); | |||
| const QByteArray &bytes = bundled_project_result.project_data; | |||
| if (bytes.isEmpty() || !temporary_file.open(QIODevice::WriteOnly) | |||
| || temporary_file.write(bytes) != bytes.size()) | |||
| { | |||
| QMessageBox::critical( | |||
| nullptr, | |||
| QObject::tr("运行程序启动失败"), | |||
| QObject::tr("无法读取封装的工程资源")); | |||
| return 2; | |||
| } | |||
| temporary_file.close(); | |||
| result = project_service.load(temporary_path.toUtf8().toStdString()); | |||
| QFile::remove(temporary_path); | |||
| } | |||
| else | |||
| { | |||
| result = project_service.load( | |||
| runtime_project_path.toUtf8().toStdString()); | |||
| QMessageBox::critical( | |||
| nullptr, | |||
| QObject::tr("运行程序启动失败"), | |||
| QObject::tr("无法读取封装的工程资源")); | |||
| return 2; | |||
| } | |||
| temporary_file.close(); | |||
| const ProjectOperationResult result = project_service.load( | |||
| temporary_path.toUtf8().toStdString()); | |||
| QFile::remove(temporary_path); | |||
| if (!result.succeeded) | |||
| { | |||
| QMessageBox::critical( | |||
| @@ -1,7 +1,6 @@ | |||
| [CmdletBinding()] | |||
| param( | |||
| [string]$OutputName = 'integrated_platform-win64', | |||
| [string]$ProjectFile = '' | |||
| [string]$OutputName = 'integrated_platform-win64' | |||
| ) | |||
| Set-StrictMode -Version Latest | |||
| @@ -34,13 +33,6 @@ if ([string]::IsNullOrWhiteSpace($OutputName) -or | |||
| throw "输出名称不是有效的 Windows 文件名:$OutputName" | |||
| } | |||
| if (-not [string]::IsNullOrWhiteSpace($ProjectFile)) { | |||
| $resolvedProjectFile = [System.IO.Path]::GetFullPath($ProjectFile) | |||
| if (-not (Test-Path -LiteralPath $resolvedProjectFile -PathType Leaf)) { | |||
| throw "未找到运行版工程文件:$resolvedProjectFile" | |||
| } | |||
| } | |||
| $packageDirectory = Join-Path $packageRoot $OutputName | |||
| $archivePath = Join-Path $packageRoot "$OutputName.zip" | |||
| $resolvedProjectRoot = [System.IO.Path]::GetFullPath($projectRoot).TrimEnd('\') | |||
| @@ -54,22 +46,6 @@ if (-not $resolvedPackageRoot.StartsWith("$resolvedProjectRoot\build\", [System. | |||
| New-Item -ItemType Directory -Path $buildDirectory -Force | Out-Null | |||
| New-Item -ItemType Directory -Path $packageRoot -Force | Out-Null | |||
| $runtimeResourceFile = $null | |||
| if (-not [string]::IsNullOrWhiteSpace($ProjectFile)) { | |||
| $runtimeResourceFile = Join-Path $buildDirectory 'runtime_project.qrc' | |||
| $escapedProjectPath = [System.Security.SecurityElement]::Escape($resolvedProjectFile) | |||
| @( | |||
| '<?xml version="1.0" encoding="UTF-8"?>' | |||
| '<RCC><qresource prefix="/">' | |||
| "<file alias=`"runtime-project.json`">$escapedProjectPath</file>" | |||
| '</qresource></RCC>' | |||
| ) | Set-Content -LiteralPath $runtimeResourceFile -Encoding UTF8 | |||
| $resourceText = Get-Content -LiteralPath $runtimeResourceFile -Raw -Encoding UTF8 | |||
| if (-not $resourceText.Contains($escapedProjectPath)) { | |||
| throw "运行版资源未正确指向工程文件:$resolvedProjectFile" | |||
| } | |||
| } | |||
| $originalPath = $env:Path | |||
| $env:Path = "$qtRoot\bin;$mingwBin;$env:Path" | |||
| @@ -77,11 +53,7 @@ try { | |||
| Push-Location $buildDirectory | |||
| try { | |||
| Write-Host 'RUNTIME_EXPORT_STAGE: qmake' | |||
| $qmakeArguments = @($qtProjectFile, 'CONFIG+=release', 'CONFIG-=debug') | |||
| if ($null -ne $runtimeResourceFile) { | |||
| $qmakeArguments += "RUNTIME_PROJECT_RESOURCE=$($runtimeResourceFile.Replace('\', '/'))" | |||
| } | |||
| & $qmakePath @qmakeArguments | |||
| & $qmakePath $qtProjectFile 'CONFIG+=release' 'CONFIG-=debug' | |||
| if ($LASTEXITCODE -ne 0) { | |||
| throw "qmake 执行失败,退出码:$LASTEXITCODE" | |||
| } | |||
| @@ -100,17 +72,6 @@ try { | |||
| throw "未生成可执行文件:$executablePath" | |||
| } | |||
| if ($null -ne $runtimeResourceFile) { | |||
| $generatedResourceSource = Join-Path $buildDirectory 'release\qrc_runtime_project.cpp' | |||
| if (-not (Test-Path -LiteralPath $generatedResourceSource)) { | |||
| throw "未生成运行版工程资源:$generatedResourceSource" | |||
| } | |||
| $generatedResourceText = Get-Content -LiteralPath $generatedResourceSource -Raw -Encoding UTF8 | |||
| if ($generatedResourceText -notlike '*runtime-project.json*') { | |||
| throw '编译结果中缺少 runtime-project.json 资源' | |||
| } | |||
| } | |||
| if (Test-Path -LiteralPath $packageDirectory) { | |||
| Remove-Item -LiteralPath $packageDirectory -Recurse -Force | |||
| } | |||
| @@ -120,12 +81,7 @@ try { | |||
| Write-Host 'RUNTIME_EXPORT_STAGE: package' | |||
| New-Item -ItemType Directory -Path $packageDirectory | Out-Null | |||
| $packagedExecutableName = if ([string]::IsNullOrWhiteSpace($ProjectFile)) { | |||
| 'integrated_platform.exe' | |||
| } else { | |||
| "$OutputName.exe" | |||
| } | |||
| $packagedExecutable = Join-Path $packageDirectory $packagedExecutableName | |||
| $packagedExecutable = Join-Path $packageDirectory 'integrated_platform.exe' | |||
| Copy-Item -LiteralPath $executablePath -Destination $packagedExecutable | |||
| $runtimeFiles = @( | |||
| 'Qt5Core.dll', 'Qt5Gui.dll', 'Qt5Network.dll', | |||
| @@ -159,15 +115,11 @@ try { | |||
| } | |||
| } | |||
| if ([string]::IsNullOrWhiteSpace($ProjectFile)) { | |||
| Compress-Archive -LiteralPath $packageDirectory -DestinationPath $archivePath -CompressionLevel Optimal | |||
| } | |||
| Compress-Archive -LiteralPath $packageDirectory -DestinationPath $archivePath -CompressionLevel Optimal | |||
| Write-Host "打包完成" | |||
| Write-Host "运行目录:$packageDirectory" | |||
| if ([string]::IsNullOrWhiteSpace($ProjectFile)) { | |||
| Write-Host "压缩包:$archivePath" | |||
| } | |||
| Write-Host "压缩包:$archivePath" | |||
| } | |||
| finally { | |||
| $env:Path = $originalPath | |||