installer: 3-2 JDK 자동 설치(Temurin 21) 버튼 추가, 취소 가능

JDK 가 없을 때 사용자가 "자동 설치" 를 눌러 Adoptium Temurin 21 LTS
(Windows x64 zip) 를 받아 %APPDATA% 의 jdk/temurin-21 으로 풀어 사용하도록
한다. 다운로드는 streaming + AbortController 로 묶어, 설치 진행 중 같은
버튼이 "설치 취소" 로 바뀌며 누르면 다운로드를 즉시 중단하고 부분 파일을
정리한다. jdk:detect 후보에 자동 설치 경로도 추가해 다음 실행 시 자동 탐색됨.
This commit is contained in:
2026-05-13 01:57:24 +09:00
parent c621185abc
commit 99ed5076c1
3 changed files with 221 additions and 7 deletions

View File

@@ -211,15 +211,44 @@ function renderSubStep31(host, back, done) {
function renderSubStep32(host, back, done) {
host.innerHTML =
'<h3>3-2. JDK 확인</h3>' +
'<p class="formMessage">JAVA_HOME 또는 C:\\Program Files\\Java 에서 자동 탐색합니다. 직접 폴더를 선택해도 됩니다.</p>' +
'<p class="formMessage">JAVA_HOME 또는 C:\\Program Files\\Java 에서 자동 탐색합니다. 없으면 "자동 설치" 로 Temurin 21 을 받아 설치할 수 있습니다.</p>' +
'<div class="fieldset"><label><input id="jdkPath" type="text" placeholder="C:\\Program Files\\Java\\jdk-17" value="' + (state.serverInstall.jdk || '') + '" /></label>' +
'<button class="secondaryBtn" id="pickJdk">폴더 선택</button>' +
'<button class="secondaryBtn" id="auto">자동 탐색</button></div>' +
'<button class="secondaryBtn" id="auto">자동 탐색</button>' +
'<button class="secondaryBtn" id="install">자동 설치</button></div>' +
'<div class="formMessage" id="msg"></div>' +
'<div class="actionRow"><button class="secondaryBtn" id="back">이전</button><button class="primaryBtn" id="next">다음</button></div>'
var input = host.querySelector('#jdkPath')
var msg = host.querySelector('#msg')
host.querySelector('#auto').addEventListener('click', async function () {
var installBtn = host.querySelector('#install')
var autoBtn = host.querySelector('#auto')
var pickBtn = host.querySelector('#pickJdk')
var nextBtn = host.querySelector('#next')
var installing = false
function setInstallingUi(on) {
installing = on
if (on) {
installBtn.textContent = '설치 취소'
installBtn.classList.remove('secondaryBtn')
installBtn.classList.add('dangerBtn')
autoBtn.disabled = true
pickBtn.disabled = true
nextBtn.disabled = true
input.disabled = true
} else {
installBtn.textContent = '자동 설치'
installBtn.classList.remove('dangerBtn')
installBtn.classList.add('secondaryBtn')
autoBtn.disabled = false
pickBtn.disabled = false
nextBtn.disabled = false
input.disabled = false
}
}
autoBtn.addEventListener('click', async function () {
if (installing) return
var detect = await installerApi.detectJdk()
if (detect.found) {
input.value = detect.path
@@ -227,16 +256,51 @@ function renderSubStep32(host, back, done) {
msg.classList.remove('error')
msg.classList.add('success')
} else {
msg.textContent = 'JDK를 자동으로 찾지 못했습니다. 직접 선택해 주세요.'
msg.textContent = 'JDK를 자동으로 찾지 못했습니다. "자동 설치" 를 눌러 Temurin 21 을 설치하거나 직접 선택해 주세요.'
msg.classList.remove('success')
msg.classList.add('error')
}
})
host.querySelector('#pickJdk').addEventListener('click', async function () {
pickBtn.addEventListener('click', async function () {
if (installing) return
var picked = await installerApi.pickFolder()
if (picked) input.value = picked
})
host.querySelector('#back').addEventListener('click', back)
host.querySelector('#next').addEventListener('click', function () {
installBtn.addEventListener('click', async function () {
if (installing) {
// 진행 중이면 취소.
msg.textContent = 'JDK 설치 취소 요청 중...'
msg.classList.remove('success', 'error')
await installerApi.cancelJdkInstall()
return
}
setInstallingUi(true)
msg.classList.remove('success', 'error')
msg.textContent = 'Temurin 21 다운로드 중... (네트워크 상태에 따라 1~5분)'
try {
var result = await installerApi.installJdk()
if (result.ok && result.path) {
input.value = result.path
state.serverInstall.jdk = result.path
msg.textContent = 'JDK 자동 설치 완료: ' + result.path
msg.classList.add('success')
} else {
msg.textContent = 'JDK 설치 ' + (result.message === '취소됨' ? '취소됨' : '실패: ' + (result.message || '알 수 없는 오류'))
msg.classList.add('error')
}
} catch (err) {
msg.textContent = 'JDK 설치 오류: ' + (err && err.message ? err.message : err)
msg.classList.add('error')
} finally {
setInstallingUi(false)
}
})
host.querySelector('#back').addEventListener('click', function () {
if (installing) return
back()
})
nextBtn.addEventListener('click', function () {
if (installing) return
if (!input.value.trim()) {
msg.textContent = 'JDK 경로를 입력해 주세요.'
msg.classList.add('error')
@@ -251,6 +315,8 @@ function renderSubStep32(host, back, done) {
input.value = detect.path
msg.textContent = 'JDK 자동 탐색됨: ' + detect.path
msg.classList.add('success')
} else if (!detect.found) {
msg.textContent = 'JDK를 자동으로 찾지 못했습니다. "자동 설치" 를 누르면 Temurin 21 LTS 를 받아 설치합니다.'
}
})()
}