배포 스크립트와 앱 Release 설정에 single-file, ReadyToRun, 압축 번들, 최적화 옵션을 추가해 릴리즈 배포 출력의 보호 수준을 한 단계 높였습니다. WebSearchHandler와 SettingsWindow는 single-file 환경에서 Assembly.Location 경고가 발생하지 않도록 AppContext.BaseDirectory 및 AssemblyInformationalVersionAttribute 기반으로 수정했습니다. README와 DEVELOPMENT 문서를 갱신했고, dotnet build 검증에서 경고 0 오류 0을 다시 확인했습니다.
This commit is contained in:
235
build.bat
235
build.bat
@@ -1,90 +1,199 @@
|
||||
@echo off
|
||||
setlocal EnableExtensions
|
||||
chcp 65001 >nul
|
||||
|
||||
set "ROOT=%~dp0"
|
||||
pushd "%ROOT%" >nul
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo AX Copilot - Build Script
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
set APP=src\AxCopilot\AxCopilot.csproj
|
||||
set ENCRYPTOR=src\AxKeyEncryptor\AxKeyEncryptor.csproj
|
||||
set OFFLINE=src\AxCopilot.Installer\AxCopilot.Installer.csproj
|
||||
set OUT=dist
|
||||
set "APP=%ROOT%src\AxCopilot\AxCopilot.csproj"
|
||||
set "ENCRYPTOR=%ROOT%src\AxKeyEncryptor\AxKeyEncryptor.csproj"
|
||||
set "INSTALLER=%ROOT%src\AxCopilot.Installer\AxCopilot.Installer.csproj"
|
||||
set "INSTALLER_DIR=%ROOT%src\AxCopilot.Installer"
|
||||
set "OUT=%ROOT%dist"
|
||||
set "APP_OUT=%OUT%\AxCopilot"
|
||||
set "ENCRYPTOR_OUT=%OUT%\AxKeyEncryptor"
|
||||
set "PAYLOAD_ZIP=%INSTALLER_DIR%\payload.zip"
|
||||
set "INSTALLER_EXE=%INSTALLER_DIR%\bin\Release\net48\AxCopilot_Setup.exe"
|
||||
set "RUNTIME=win-x64"
|
||||
set "OBFUSCATOR_EXE=%ROOT%tools\obfuscator\obfuscator.exe"
|
||||
set "OBFUSCATOR_CONFIG=%ROOT%tools\obfuscator\AxCopilot.obfuscation.xml"
|
||||
|
||||
:: Kill running app
|
||||
tasklist /FI "IMAGENAME eq AxCopilot.exe" 2>nul | find /i "AxCopilot.exe" >nul
|
||||
if %ERRORLEVEL%==0 (
|
||||
echo [0] Stopping AxCopilot...
|
||||
taskkill /IM AxCopilot.exe /F >nul 2>nul
|
||||
timeout /t 2 /nobreak >nul
|
||||
)
|
||||
:: Kill legacy process
|
||||
tasklist /FI "IMAGENAME eq AxCommander.exe" 2>nul | find /i "AxCommander.exe" >nul
|
||||
if %ERRORLEVEL%==0 (
|
||||
echo [0] Stopping legacy AxCommander...
|
||||
taskkill /IM AxCommander.exe /F >nul 2>nul
|
||||
timeout /t 2 /nobreak >nul
|
||||
)
|
||||
call :stop_process "AxCopilot" "AX Copilot"
|
||||
if errorlevel 1 goto :fail_running
|
||||
call :stop_process "AxCommander" "legacy AxCommander"
|
||||
if errorlevel 1 goto :fail_running
|
||||
|
||||
if exist "%OUT%" rd /s /q "%OUT%" 2>nul
|
||||
mkdir "%OUT%"
|
||||
mkdir "%OUT%\AxCopilot"
|
||||
mkdir "%OUT%" || goto :fail_dist
|
||||
mkdir "%APP_OUT%" || goto :fail_dist
|
||||
mkdir "%ENCRYPTOR_OUT%" || goto :fail_dist
|
||||
|
||||
:: ========================================
|
||||
:: 1. Main app (self-contained, folder)
|
||||
:: ========================================
|
||||
echo [1/4] Building main app (self-contained)...
|
||||
dotnet publish "%APP%" -c Release -o "%OUT%\AxCopilot" --self-contained true --nologo -v quiet
|
||||
if %ERRORLEVEL% NEQ 0 ( echo [FAILED] Main app build & pause & exit /b 1 )
|
||||
echo OK - dist\AxCopilot\
|
||||
if exist "%PAYLOAD_ZIP%" del /q "%PAYLOAD_ZIP%" 2>nul
|
||||
|
||||
echo [1/5] Building main app (self-contained %RUNTIME%)...
|
||||
dotnet publish "%APP%" ^
|
||||
-c Release ^
|
||||
-r %RUNTIME% ^
|
||||
--self-contained true ^
|
||||
-o "%APP_OUT%" ^
|
||||
--nologo ^
|
||||
-v minimal ^
|
||||
-p:DebugType=None ^
|
||||
-p:DebugSymbols=false ^
|
||||
-p:CopyOutputSymbolsToPublishDirectory=false ^
|
||||
-p:EnableSourceLink=false ^
|
||||
-p:PublishSingleFile=true ^
|
||||
-p:EnableCompressionInSingleFile=true ^
|
||||
-p:IncludeNativeLibrariesForSelfExtract=true ^
|
||||
-p:PublishReadyToRun=true
|
||||
if errorlevel 1 goto :fail_app
|
||||
echo OK - %APP_OUT%
|
||||
echo.
|
||||
|
||||
:: ========================================
|
||||
:: 2. AxKeyEncryptor (developer tool)
|
||||
:: ========================================
|
||||
echo [2/4] Building AxKeyEncryptor (WinForms)...
|
||||
mkdir "%OUT%\AxKeyEncryptor" 2>nul
|
||||
dotnet publish "%ENCRYPTOR%" -c Release -o "%OUT%\AxKeyEncryptor" --self-contained false --nologo -v quiet
|
||||
if %ERRORLEVEL% NEQ 0 ( echo [FAILED] AxKeyEncryptor build & pause & exit /b 1 )
|
||||
del /q "%OUT%\AxKeyEncryptor\*.pdb" 2>nul
|
||||
echo OK - dist\AxKeyEncryptor\
|
||||
echo [2/5] Checking obfuscation / anti-decompile status...
|
||||
if exist "%OBFUSCATOR_EXE%" (
|
||||
if exist "%OBFUSCATOR_CONFIG%" (
|
||||
echo Optional obfuscator found.
|
||||
echo Running: "%OBFUSCATOR_EXE%"
|
||||
"%OBFUSCATOR_EXE%" "%OBFUSCATOR_CONFIG%" "%APP_OUT%"
|
||||
if errorlevel 1 goto :fail_obfuscation
|
||||
echo OK - obfuscation step completed
|
||||
) else (
|
||||
echo WARNING - no external obfuscator configured.
|
||||
echo Current protection is limited to symbol/source metadata removal only.
|
||||
)
|
||||
) else (
|
||||
echo WARNING - no external obfuscator configured.
|
||||
echo Current protection is limited to symbol/source metadata removal only.
|
||||
)
|
||||
echo.
|
||||
|
||||
:: ========================================
|
||||
:: 3. Create payload ZIP for installer
|
||||
:: ========================================
|
||||
echo [3/4] Creating installer payload ZIP...
|
||||
powershell -NoProfile -Command "Compress-Archive -Path '%OUT%\AxCopilot\*' -DestinationPath 'src\AxCopilot.Installer\payload.zip' -Force"
|
||||
echo OK - payload.zip
|
||||
echo [3/5] Building AxKeyEncryptor...
|
||||
dotnet publish "%ENCRYPTOR%" ^
|
||||
-c Release ^
|
||||
-o "%ENCRYPTOR_OUT%" ^
|
||||
--self-contained false ^
|
||||
--nologo ^
|
||||
-v minimal ^
|
||||
-p:DebugType=None ^
|
||||
-p:DebugSymbols=false
|
||||
if errorlevel 1 goto :fail_encryptor
|
||||
echo OK - %ENCRYPTOR_OUT%
|
||||
echo.
|
||||
|
||||
:: ========================================
|
||||
:: 4. Build installer (.NET Framework 4.8)
|
||||
:: ========================================
|
||||
echo [4/4] Building installer (.NET Framework 4.8)...
|
||||
dotnet build "%OFFLINE%" -c Release --nologo -v quiet
|
||||
if %ERRORLEVEL% NEQ 0 ( echo [FAILED] Installer build & pause & exit /b 1 )
|
||||
copy /Y "src\AxCopilot.Installer\bin\Release\net48\AxCopilot_Setup.exe" "%OUT%\" >nul
|
||||
echo [4/5] Creating installer payload ZIP...
|
||||
powershell -NoProfile -Command "Compress-Archive -Path '%APP_OUT%\*' -DestinationPath '%PAYLOAD_ZIP%' -Force"
|
||||
if errorlevel 1 goto :fail_payload
|
||||
if not exist "%PAYLOAD_ZIP%" goto :fail_payload
|
||||
echo OK - %PAYLOAD_ZIP%
|
||||
echo.
|
||||
|
||||
echo [5/5] Building installer (.NET Framework 4.8)...
|
||||
dotnet build "%INSTALLER%" -c Release --nologo -v minimal
|
||||
if errorlevel 1 goto :fail_installer
|
||||
if not exist "%INSTALLER_EXE%" goto :fail_installer_copy
|
||||
copy /Y "%INSTALLER_EXE%" "%OUT%\" >nul
|
||||
if errorlevel 1 goto :fail_installer_copy
|
||||
for %%F in ("%OUT%\AxCopilot_Setup.exe") do echo OK - AxCopilot_Setup.exe (%%~zF bytes)
|
||||
echo.
|
||||
|
||||
:: ========================================
|
||||
:: Cleanup
|
||||
:: ========================================
|
||||
:: Remove debug symbols and metadata (anti-decompile)
|
||||
del /q "%OUT%\*.pdb" 2>nul
|
||||
del /q "%OUT%\AxCopilot\*.pdb" 2>nul
|
||||
del /q "%OUT%\AxCopilot\*.xml" 2>nul
|
||||
del /q "%OUT%\*.deps.json" 2>nul
|
||||
del /q "%OUT%\*.runtimeconfig.json" 2>nul
|
||||
del /q "src\AxCopilot.Installer\payload.zip" 2>nul
|
||||
echo [Cleanup] Removing debug and metadata files from dist...
|
||||
call :clean_publish_artifacts "%OUT%"
|
||||
call :clean_publish_artifacts "%APP_OUT%"
|
||||
call :clean_publish_artifacts "%ENCRYPTOR_OUT%"
|
||||
if exist "%PAYLOAD_ZIP%" del /q "%PAYLOAD_ZIP%" 2>nul
|
||||
echo OK - cleaned
|
||||
echo.
|
||||
|
||||
echo ========================================
|
||||
echo Build Complete!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo dist\AxCopilot\ Main app (EXE + DLL)
|
||||
echo dist\AxKeyEncryptor\ Settings Encryptor (dev tool)
|
||||
echo dist\AxCopilot_Setup.exe Installer (offline, .NET 4.8)
|
||||
echo %APP_OUT% Main app
|
||||
echo %ENCRYPTOR_OUT% Settings Encryptor
|
||||
echo %OUT%\AxCopilot_Setup.exe Installer
|
||||
echo.
|
||||
pause
|
||||
echo Note:
|
||||
echo - Release/self-contained single-file publish applied
|
||||
echo - ReadyToRun + compressed single-file bundle enabled
|
||||
echo - PDB/XML/debug metadata removed from dist output
|
||||
echo - External obfuscator is only applied when tools\obfuscator is configured
|
||||
echo.
|
||||
popd >nul
|
||||
exit /b 0
|
||||
|
||||
:stop_process
|
||||
set "PROC_NAME=%~1"
|
||||
set "DISPLAY_NAME=%~2"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"$name='%PROC_NAME%';" ^
|
||||
"$display='%DISPLAY_NAME%';" ^
|
||||
"$procs = Get-Process -Name $name -ErrorAction SilentlyContinue;" ^
|
||||
"if (-not $procs) { exit 0 }" ^
|
||||
"Write-Host ('[0] Stopping ' + $display + '...');" ^
|
||||
"$imageName = $name + '.exe';" ^
|
||||
"foreach ($proc in $procs) {" ^
|
||||
" try { if ($proc.MainWindowHandle -ne 0) { [void]$proc.CloseMainWindow() } } catch { }" ^
|
||||
"}" ^
|
||||
"Start-Sleep -Seconds 2;" ^
|
||||
"& taskkill /IM $imageName /T /F > $null 2> $null;" ^
|
||||
"Start-Sleep -Seconds 2;" ^
|
||||
"$stillRunning = Get-Process -Name $name -ErrorAction SilentlyContinue;" ^
|
||||
"if ($stillRunning) {" ^
|
||||
" Write-Host ('[FAILED] Could not stop ' + $display + '. Access may be denied or the app may be running with higher privileges.') -ForegroundColor Red;" ^
|
||||
" exit 1" ^
|
||||
"}" ^
|
||||
"exit 0"
|
||||
if errorlevel 1 exit /b 1
|
||||
exit /b 0
|
||||
|
||||
:clean_publish_artifacts
|
||||
if not exist "%~1" exit /b 0
|
||||
del /q "%~1\*.pdb" 2>nul
|
||||
del /q "%~1\*.xml" 2>nul
|
||||
del /q "%~1\*.deps.json" 2>nul
|
||||
del /q "%~1\*.runtimeconfig.json" 2>nul
|
||||
exit /b 0
|
||||
|
||||
:fail_dist
|
||||
echo [FAILED] dist ??????밴쉐 ??쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_app
|
||||
echo [FAILED] main app publish ??쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_obfuscation
|
||||
echo [FAILED] obfuscation ??m???쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_encryptor
|
||||
echo [FAILED] AxKeyEncryptor publish ??쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_payload
|
||||
echo [FAILED] payload.zip ??밴쉐 ??쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_installer
|
||||
echo [FAILED] installer build ??쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_installer_copy
|
||||
echo [FAILED] installer exe 癰귣벊沅???쎈솭
|
||||
goto :end_fail
|
||||
|
||||
:fail_running
|
||||
echo [FAILED] running AX Copilot process could not be stopped cleanly
|
||||
goto :end_fail
|
||||
|
||||
:end_fail
|
||||
if exist "%PAYLOAD_ZIP%" del /q "%PAYLOAD_ZIP%" 2>nul
|
||||
popd >nul
|
||||
exit /b 1
|
||||
|
||||
Reference in New Issue
Block a user