본문으로 건너뛰기

필수 프로그램 설치하기

이 문서에서는 HandStack을 빌드하고 실행하는 데 필요한 프로그램을 처음부터 설치합니다. 사용 중인 운영체제 탭 하나만 선택하고 위에서 아래로 따라 하세요.

설치가 끝나면 다음 명령을 사용할 수 있습니다.

프로그램용도확인 명령
.NET SDK 10 GAHandStack 서버 빌드 및 실행dotnet --list-sdks
Node.js LTS와 npm화면 리소스와 Node.js 패키지 관리node --version, npm --version
GitHandStack 소스 코드 내려받기git --version
curl설치 파일과 HTTP 리소스 내려받기curl --version
gulp-cli화면 리소스 번들링gulp --version
LibMan CLI클라이언트 라이브러리 복원libman --version
PowerShell 7HandStack 자동화 스크립트 실행pwsh --version
설치 전에 확인하세요
  • 설치 파일을 내려받으려면 인터넷 연결이 필요합니다.
  • 이미 설치되어 정상 실행되는 프로그램은 해당 설치 명령을 건너뛰어도 됩니다.
  • 이 문서의 대상 환경은 Windows 11 x64, macOS 14·15·26, Ubuntu 26.04 LTS amd64입니다.
  • .NET SDK 확인 결과에는 10.0.x-preview10.0.x-rc가 아닌 정식 10.0.x 버전이 있어야 합니다.

한 번에 설치하기

설치 과정을 자동으로 진행하려면 사용 중인 운영체제 탭에서 스크립트를 파일로 저장한 뒤 실행하세요. 스크립트는 이미 사용할 수 있는 도구를 건너뛰므로 같은 사용자 계정에서 다시 실행할 수 있습니다.

경고

스크립트를 실행하기 전에 내용을 확인하세요. macOS와 Ubuntu에서는 스크립트 전체에 sudo를 붙이지 말고 일반 사용자 계정으로 실행합니다.

Windows 11

다음 내용을 windows-bootstrapper.ps1로 인코딩을 UTF-8 with BOM 으로 저장 합니다.

#requires -Version 5.1

[CmdletBinding()]
param()

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'

function Test-Command {
param([Parameter(Mandatory)][string]$Name)

return $null -ne (Get-Command $Name -ErrorAction SilentlyContinue)
}

function Update-ProcessPath {
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$env:Path = (@($machinePath, $userPath) | Where-Object { $_ }) -join ';'
}

function Add-UserPath {
param([Parameter(Mandatory)][string]$Directory)

$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$userPathEntries = @($userPath -split ';' | Where-Object { $_ })
if ($userPathEntries -notcontains $Directory) {
$newUserPath = (@($userPathEntries) + $Directory) -join ';'
[Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User')
}

Update-ProcessPath
}

function Install-WinGetPackage {
param([Parameter(Mandatory)][string]$Id)

& winget.exe install `
--id $Id `
--exact `
--source winget `
--accept-package-agreements `
--accept-source-agreements `
--disable-interactivity `
--silent

if ($LASTEXITCODE -ne 0) {
throw "WinGet 패키지 설치 실패: $Id (종료 코드 $LASTEXITCODE)"
}

Update-ProcessPath
}

function Get-NpmCommand {
# Node.js MSI가 PATH를 갱신한 직후에도 현재 프로세스에서 바로 보이지 않을 수 있다.
# 먼저 레지스트리 PATH를 다시 읽고, 그래도 찾지 못하면 기본 설치 위치를 직접 사용한다.
Update-ProcessPath

$command = Get-Command 'npm.cmd' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($null -ne $command) {
return $command.Source
}

$defaultNpmCommand = Join-Path $env:ProgramFiles 'nodejs\npm.cmd'
if (Test-Path -LiteralPath $defaultNpmCommand -PathType Leaf) {
$nodeDirectory = Split-Path -Parent $defaultNpmCommand
if (($env:Path -split ';') -notcontains $nodeDirectory) {
$env:Path = "$nodeDirectory;$env:Path"
}
return $defaultNpmCommand
}

return $null
}

function Initialize-NpmGlobalDirectory {
$npmCommand = Get-NpmCommand
if (-not $npmCommand) {
throw 'Node.js 설치 후 npm.cmd를 찾을 수 없습니다.'
}

# npm 11/Node.js 24의 Windows 기본 prefix가 Program Files로 잡히면 일반 사용자
# 전역 설치가 실패할 수 있다. npm 조회 명령에 의존하지 않고 사용자 전용 위치를 쓴다.
$npmGlobalDirectory = Join-Path ([Environment]::GetFolderPath('ApplicationData')) 'npm'
if (-not (Test-Path -LiteralPath $npmGlobalDirectory -PathType Container)) {
New-Item -ItemType Directory -Path $npmGlobalDirectory -Force | Out-Null
}

[Environment]::SetEnvironmentVariable('NPM_CONFIG_PREFIX', $npmGlobalDirectory, 'User')
$env:NPM_CONFIG_PREFIX = $npmGlobalDirectory
Add-UserPath $npmGlobalDirectory

return $npmCommand
}

function Test-DotNet10Ga {
if (-not (Test-Command 'dotnet.exe')) {
return $false
}

$sdks = & dotnet.exe --list-sdks 2>$null
return $null -ne ($sdks | Where-Object { $_ -match '^10[.]0[.][0-9]+\s' } | Select-Object -First 1)
}

try {
Write-Host '=== HandStack 개발 환경 설치: Windows 11 x64 ==='
Write-Host '[1/8] 사전 조건 확인'

if ($env:OS -ne 'Windows_NT') {
throw 'Windows 전용 스크립트입니다.'
}

if ([Environment]::OSVersion.Version.Build -lt 22000) {
throw "Windows 11 전용 스크립트입니다. 현재 빌드: $([Environment]::OSVersion.Version.Build)"
}

$architecture = if ($env:PROCESSOR_ARCHITEW6432) {
$env:PROCESSOR_ARCHITEW6432
} else {
$env:PROCESSOR_ARCHITECTURE
}

if ($architecture -ne 'AMD64') {
throw "Windows x64 전용 스크립트입니다. 현재 아키텍처: $architecture"
}

if (-not (Test-Command 'winget.exe')) {
throw 'winget.exe를 찾을 수 없습니다. Microsoft Store의 앱 설치 관리자(App Installer)를 설치하거나 업데이트하세요.'
}

& winget.exe source update --disable-interactivity
if ($LASTEXITCODE -ne 0) {
throw "WinGet 원본 업데이트 실패 (종료 코드 $LASTEXITCODE)"
}

Write-Host '[2/8] .NET SDK 10 GA 확인 및 설치'
if (Test-DotNet10Ga) {
Write-Host ' .NET SDK 10 GA가 이미 설치되어 있어 건너뜁니다.'
} else {
Install-WinGetPackage 'Microsoft.DotNet.SDK.10'
}

$dotnetToolsDirectory = Join-Path $HOME '.dotnet\tools'
Add-UserPath $dotnetToolsDirectory

Write-Host '[3/8] Node.js LTS 확인 및 설치'
if ((Test-Command 'node.exe') -and (Test-Command 'npm.cmd')) {
Write-Host ' Node.js가 이미 설치되어 있어 건너뜁니다.'
} else {
Install-WinGetPackage 'OpenJS.NodeJS.LTS'
}

$npmCommand = Initialize-NpmGlobalDirectory

Write-Host '[4/8] Git 확인 및 설치'
if (Test-Command 'git.exe') {
Write-Host ' Git이 이미 설치되어 있어 건너뜁니다.'
} else {
Install-WinGetPackage 'Git.Git'
}

Write-Host '[5/8] curl 확인 및 설치'
if (Test-Command 'curl.exe') {
Write-Host ' curl이 이미 설치되어 있어 건너뜁니다.'
} else {
Install-WinGetPackage 'cURL.cURL'
}

Write-Host '[6/8] gulp-cli 확인 및 설치'
if (Test-Command 'gulp.cmd') {
Write-Host ' gulp-cli가 이미 설치되어 있어 건너뜁니다.'
} else {
& $npmCommand install --global gulp-cli
if ($LASTEXITCODE -ne 0) {
throw "gulp-cli 설치 실패 (종료 코드 $LASTEXITCODE)"
}
}

Write-Host '[7/8] Microsoft.Web.LibraryManager.Cli 확인 및 설치'
if (Test-Command 'libman.exe') {
Write-Host ' libman이 이미 설치되어 있어 건너뜁니다.'
} else {
& dotnet.exe tool install --global Microsoft.Web.LibraryManager.Cli
if ($LASTEXITCODE -ne 0) {
throw "LibMan CLI 설치 실패 (종료 코드 $LASTEXITCODE)"
}
}

Write-Host '[8/8] PowerShell 확인 및 설치'
if (Test-Command 'pwsh.exe') {
Write-Host ' PowerShell이 이미 설치되어 있어 건너뜁니다.'
} else {
& dotnet.exe tool install --global PowerShell
if ($LASTEXITCODE -ne 0) {
throw "PowerShell 설치 실패 (종료 코드 $LASTEXITCODE)"
}
}

Write-Host
Write-Host '=== 설치 결과 ==='
Write-Host "Windows: $([Environment]::OSVersion.VersionString)"
Write-Host '.NET SDK:'
& dotnet.exe --list-sdks
Write-Host "Node.js: $(& node.exe --version)"
Write-Host "npm: $(& npm.cmd --version)"
Write-Host "PowerShell: $(& pwsh.exe --version)"
Write-Host "Git: $(& git.exe --version)"
Write-Host "curl: $((& curl.exe --version | Select-Object -First 1))"
Write-Host 'gulp-cli:'
& gulp.cmd --version
Write-Host "libman: $(& libman.exe --version)"
Write-Host
Write-Host '모든 구성 요소가 설치되었습니다. 새 터미널에서도 사용자 PATH 설정이 적용됩니다.'
} catch {
Write-Error "설치 실패: $($_.Exception.Message)"
exit 1
}

관리자 권한으로 PowerShell에서 실행한다. 일반 사용자 권한으로 실행 하면, 시스템 범위 패키지 설치 시 WinGet이 UAC 승인을 요청할 수 있습니다.

powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\windows-bootstrapper.ps1

설치 과정을 자동으로 진행하지 않고 사용 중인 운영체제 환경에 따라 필요한 프로그램을 직접 설치하려면 다음 내용을 참고하세요.

Windows 11에서 설치하기

Windows에서는 Windows PowerShell 5.1과 WinGet을 사용합니다. 프로그램 설치 중 사용자 계정 컨트롤(UAC) 창이 표시되면 내용을 확인한 뒤 승인하세요.

1. Windows PowerShell 열기

  1. 시작 메뉴에서 Windows PowerShell을 검색합니다.
  2. 관리자 권한으로 실행을 선택합니다.
  3. 다음 명령을 실행해 Windows 버전, CPU 아키텍처, WinGet을 확인합니다.
[Environment]::OSVersion.Version
$env:PROCESSOR_ARCHITECTURE
winget.exe --version

Windows 빌드는 22000 이상, 아키텍처는 AMD64여야 합니다. winget.exe를 찾을 수 없다면 Microsoft Store에서 앱 설치 관리자를 설치하거나 업데이트한 뒤 Windows에 다시 로그인하세요.

WinGet 패키지 정보를 갱신합니다.

winget.exe source update --disable-interactivity

2. .NET SDK 10 설치

winget.exe install --id Microsoft.DotNet.SDK.10 --exact --source winget `
--accept-package-agreements --accept-source-agreements

설치가 끝나면 정식 버전이 표시되는지 확인합니다.

dotnet.exe --list-sdks

결과에 10.0.으로 시작하고 -preview-rc가 붙지 않은 버전이 하나 이상 있으면 정상입니다.

3. Node.js LTS와 Git 설치

winget.exe install --id OpenJS.NodeJS.LTS --exact --source winget `
--accept-package-agreements --accept-source-agreements

winget.exe install --id Git.Git --exact --source winget `
--accept-package-agreements --accept-source-agreements

Windows 11에는 일반적으로 curl.exe가 포함되어 있습니다. 다음 명령에서 오류가 날 때만 WinGet으로 설치하세요.

curl.exe --version
winget.exe install --id cURL.cURL --exact --source winget `
--accept-package-agreements --accept-source-agreements

여기까지 설치했으면 PowerShell 창을 닫고 새 PowerShell 창을 일반 사용자 권한으로 여세요. 새로 추가된 dotnet, node, npm, git 경로가 이때 적용됩니다.

4. 사용자 전역 도구 경로 설정

npm 도구와 .NET 전역 도구를 현재 사용자 계정에 설치하도록 경로를 설정합니다. 새 PowerShell 창에서 다음 블록 전체를 한 번 실행하세요.

$npmDirectory = Join-Path $env:APPDATA 'npm'
$dotnetToolsDirectory = Join-Path $HOME '.dotnet\tools'
New-Item -ItemType Directory -Path $npmDirectory -Force | Out-Null

[Environment]::SetEnvironmentVariable('NPM_CONFIG_PREFIX', $npmDirectory, 'User')
$env:NPM_CONFIG_PREFIX = $npmDirectory

$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$pathEntries = @($userPath -split ';' | Where-Object { $_ })
foreach ($directory in @($npmDirectory, $dotnetToolsDirectory)) {
if ($pathEntries -notcontains $directory) {
$pathEntries += $directory
}
}
[Environment]::SetEnvironmentVariable('Path', ($pathEntries -join ';'), 'User')
$env:Path = "$npmDirectory;$dotnetToolsDirectory;$env:Path"

5. gulp-cli, LibMan, PowerShell 7 설치

다음 세 명령은 관리자 PowerShell이 아닌 현재 사용자 PowerShell에서 실행합니다.

npm.cmd install --global gulp-cli
dotnet.exe tool install --global Microsoft.Web.LibraryManager.Cli
dotnet.exe tool install --global PowerShell

Tool ... is already installed 메시지가 나오면 이미 설치된 것입니다. 최신 버전으로 갱신하려면 install 대신 update를 사용합니다.

dotnet.exe tool update --global Microsoft.Web.LibraryManager.Cli
dotnet.exe tool update --global PowerShell

6. 설치 결과 확인

PowerShell 창을 다시 닫고 새 창을 연 뒤 다음 명령을 한 줄씩 실행합니다.

dotnet.exe --list-sdks
node.exe --version
npm.cmd --version
git.exe --version
curl.exe --version
gulp.cmd --version
libman.exe --version
pwsh.exe --version

모든 명령이 버전 정보를 출력하면 Windows 설치가 끝났습니다.

Windows 문제 해결

  • npm.cmd를 찾을 수 없음: PowerShell을 새로 열고 where.exe node, where.exe npm을 실행합니다. 기본 설치 경로인 C:\Program Files\nodejs가 PATH에 있는지도 확인합니다.
  • gulp.cmd를 찾을 수 없음: npm.cmd config get prefix%APPDATA%\npm을 가리키는지 확인하고 4단계를 다시 실행합니다.
  • libman.exe 또는 pwsh.exe를 찾을 수 없음: dotnet.exe tool list --global로 설치 여부를 확인하고 %USERPROFILE%\.dotnet\tools가 사용자 PATH에 있는지 확인합니다.
  • curlInvoke-WebRequest로 실행됨: curl 대신 실행 파일 이름인 curl.exe를 사용합니다.
  • .NET SDK 10이 보이지 않음: where.exe dotnetdotnet.exe --info로 실제 실행 경로와 아키텍처를 확인합니다.

설치 완료 기준

사용 중인 운영체제의 마지막 확인 명령이 모두 성공하고 다음 조건을 만족하면 준비가 끝난 것입니다.

  • dotnet --list-sdks에 정식 .NET SDK 10.0.x가 표시됩니다.
  • node, npm, git, curl, gulp, libman, pwsh가 각각 버전 정보를 출력합니다.
  • 새 터미널을 열어도 같은 명령을 사용할 수 있습니다.

이제 개발 환경 설정하기로 이동해 HandStack 소스 코드를 내려받고 빌드하세요.

도구 업데이트하기

설치 후에는 운영체제의 패키지 관리자와 각 도구의 업데이트 명령을 사용합니다.

winget.exe upgrade --all
npm.cmd update --global gulp-cli
dotnet.exe tool update --global Microsoft.Web.LibraryManager.Cli
dotnet.exe tool update --global PowerShell

참고 자료