
안녕하세요, 우기입니다! Flutter로 Windows 앱을 개발하다 보면 한 번쯤은 마주치는 골칫거리, 바로 DLL 오류에 대해 이야기해보려고 합니다. "앱이 내 컴퓨터에서는 잘 되는데 다른 PC에서는 안 돼요"라는 말, 한 번쯤 들어보셨죠?
Flutter Windows 앱을 친구나 동료에게 공유했는데 다음과 같은 오류가 발생했다면, 이 글이 정확히 필요한 가이드입니다.
시스템에서 VCRUNTIME140.dll을 찾을 수 없어 코드 실행을 진행할 수 없습니다.
프로그램을 다시 설치하면 이 문제가 해결될 수 있습니다.
또는
MSVCP140.dll이(가) 없어 프로그램을 시작할 수 없습니다.
이런 오류는 개발 환경에서는 절대 발생하지 않지만, 사용자 PC에서만 나타나는 특징이 있습니다. 왜 그럴까요?
Flutter Windows 앱은 다음과 같은 DLL 파일들에 의존합니다.
your_app.exe
├── flutter_windows.dll (Flutter 엔진)
├── msvcp140.dll (C++ 표준 라이브러리)
├── vcruntime140.dll (Visual C++ 런타임)
├── vcruntime140_1.dll (추가 런타임)
└── msvcp140_codecvt_ids.dll (코드 변환)
개발 환경에서는 문제가 없는 이유:
사용자 환경에서 오류가 발생하는 이유:
사용자가 앱 실행
↓
Windows가 필요한 DLL 검색
↓
시스템 경로에서 DLL을 찾지 못함
↓
앱 실행 폴더에서도 DLL을 찾지 못함
↓
❌ "DLL을 찾을 수 없습니다" 오류 발생
오류 메시지:
VCRUNTIME140.dll이(가) 없어 프로그램을 시작할 수 없습니다.
원인: Visual C++ 2015-2022 재배포 패키지가 설치되지 않음
영향도: ⭐⭐⭐⭐⭐ (가장 흔함)
오류 메시지:
MSVCP140.dll을(를) 찾을 수 없습니다.
원인: C++ 표준 라이브러리 DLL 누락
영향도: ⭐⭐⭐⭐⭐ (가장 흔함)
오류 메시지:
VCRUNTIME140_1.dll이(가) 컴퓨터에 없습니다.
원인: 64비트 애플리케이션용 추가 런타임 DLL 누락
영향도: ⭐⭐⭐⭐ (64비트 앱에서 발생)
오류 메시지:
api-ms-win-crt-runtime-l1-1-0.dll이(가) 없습니다.
원인: Universal C Runtime이 설치되지 않음 (주로 Windows 7/8)
영향도: ⭐⭐⭐ (구형 Windows에서 발생)
가장 간단하지만 사용자가 직접 설치해야 하는 방법입니다.
1단계: 다운로드
사용자에게 다음 링크를 공유하세요:
2단계: 설치
vc_redist.x64.exe 파일 실행3단계: 확인
앱을 다시 실행하여 정상 작동하는지 확인합니다.
| 항목 | 내용 |
|---|---|
| ✅ 장점 | • 시스템 전체에서 DLL 공유 • 한 번 설치하면 모든 앱에서 사용 • Microsoft 공식 지원 |
| ⚠️ 단점 | • 사용자가 직접 설치 필요 • 추가 다운로드 및 설치 과정 • 관리자 권한 필요 |
사용자에게 다음과 같은 안내를 제공하세요:
## 앱 실행 오류 해결 방법
앱 실행 시 DLL 관련 오류가 발생한다면 다음 단계를 따라주세요:
### 필수 구성 요소 설치
1. [이 링크](https://aka.ms/vs/17/release/vc_redist.x64.exe)를 클릭하여 파일 다운로드
2. 다운로드한 파일을 실행하여 설치
3. 설치 완료 후 앱을 다시 실행
### 여전히 문제가 발생한다면
support@yourcompany.com으로 문의해주세요.
사용자가 별도 설치 없이 바로 실행할 수 있도록 DLL을 앱에 포함시키는 방법입니다.
필요한 DLL 파일들은 일반적으로 다음 경로에 있습니다:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\{version}\x64\Microsoft.VC143.CRT\
필요한 파일 목록:
msvcp140.dll
vcruntime140.dll
vcruntime140_1.dll
Flutter 프로젝트의 windows 폴더에 배포 스크립트를 생성합니다.
프로젝트 구조:
your_flutter_project/
├── lib/
├── windows/
│ ├── runner/
│ └── copy_dlls.ps1 ← 새로 생성
└── pubspec.yaml
windows/copy_dlls.ps1 파일을 생성하세요:
# DLL 복사 스크립트
param(
[string]$BuildMode = "Release"
)
$VC_REDIST_PATH = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC"
$BUILD_OUTPUT = "..\build\windows\x64\runner\$BuildMode"
Write-Host "🔍 Visual C++ DLL 검색 중..." -ForegroundColor Cyan
# 최신 버전 폴더 찾기
$latestVersion = Get-ChildItem -Path $VC_REDIST_PATH -Directory |
Sort-Object Name -Descending |
Select-Object -First 1
$DLL_SOURCE = "$($latestVersion.FullName)\x64\Microsoft.VC143.CRT"
if (-not (Test-Path $DLL_SOURCE)) {
Write-Host "❌ DLL 소스 경로를 찾을 수 없습니다: $DLL_SOURCE" -ForegroundColor Red
exit 1
}
Write-Host "✅ DLL 발견: $DLL_SOURCE" -ForegroundColor Green
# 필요한 DLL 목록
$dlls = @(
"msvcp140.dll",
"vcruntime140.dll",
"vcruntime140_1.dll"
)
Write-Host "📦 DLL 복사 중..." -ForegroundColor Cyan
foreach ($dll in $dlls) {
$source = Join-Path $DLL_SOURCE $dll
$destination = Join-Path $BUILD_OUTPUT $dll
if (Test-Path $source) {
Copy-Item -Path $source -Destination $destination -Force
Write-Host " ✓ $dll 복사 완료" -ForegroundColor Green
} else {
Write-Host " ⚠ $dll 을(를) 찾을 수 없습니다" -ForegroundColor Yellow
}
}
Write-Host "🎉 모든 DLL 복사 완료!" -ForegroundColor Green
Write-Host "📍 위치: $BUILD_OUTPUT" -ForegroundColor Cyan
windows/runner/CMakeLists.txt 파일 끝에 다음 내용을 추가하세요:
# DLL 자동 복사
add_custom_command(TARGET ${BINARY_NAME} POST_BUILD
COMMAND powershell -ExecutionPolicy Bypass -File "${CMAKE_CURRENT_SOURCE_DIR}/../copy_dlls.ps1" -BuildMode $<CONFIG>
COMMENT "Copying required DLLs..."
)
# 앱 빌드
flutter build windows --release
# DLL이 포함되었는지 확인
dir build\windows\x64\runner\Release\
다음과 같은 파일들이 있어야 합니다:
your_app.exe
flutter_windows.dll
msvcp140.dll ← 추가됨
vcruntime140.dll ← 추가됨
vcruntime140_1.dll ← 추가됨
| 항목 | 내용 |
|---|---|
| ✅ 장점 | • 사용자가 별도 설치 불필요 • 즉시 실행 가능 • 버전 충돌 없음 |
| ⚠️ 단점 | • 앱 크기 증가 (약 1-2MB) • DLL 중복 (여러 앱 설치 시) |
DLL 의존성을 완전히 제거하는 가장 근본적인 해결 방법입니다.
windows/runner/CMakeLists.txt 파일을 수정합니다:
# 기존 설정 찾기
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
# 동적 링크를 정적 링크로 변경
if(MSVC)
# /MD를 /MT로 변경 (Release)
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
# 추가 최적화
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2")
endif()
# 기존 빌드 삭제
flutter clean
# Windows 빌드 캐시 삭제
Remove-Item -Recurse -Force build\windows\
# 새로 빌드
flutter build windows --release
빌드된 실행 파일의 DLL 의존성을 확인합니다:
# Dependency Walker 또는 dumpbin 사용
dumpbin /dependents build\windows\x64\runner\Release\your_app.exe
예상 결과 (VCRUNTIME140.dll 등이 목록에서 제거됨):
KERNEL32.dll
flutter_windows.dll
| 항목 | 내용 |
|---|---|
| ✅ 장점 | • DLL 의존성 완전 제거 • 배포 단순화 • 버전 관리 용이 |
| ⚠️ 단점 | • 실행 파일 크기 증가 (약 500KB-1MB) • 빌드 시간 증가 • 일부 플러그인과 호환성 문제 가능 |
앞서 소개한 모든 방법을 하나로 통합한 완전 자동화 스크립트입니다.
프로젝트 루트에 build_and_package.ps1 파일을 생성하세요:
#!/usr/bin/env pwsh
# Flutter Windows 앱 완전 자동 빌드 및 패키징 스크립트
param(
[string]$AppName = "MyApp",
[switch]$IncludeDLLs = $true,
[switch]$CreateInstaller = $false,
[string]$OutputDir = ".\Release"
)
# 색상 정의
$Green = [System.ConsoleColor]::Green
$Blue = [System.ConsoleColor]::Cyan
$Yellow = [System.ConsoleColor]::Yellow
$Red = [System.ConsoleColor]::Red
function Write-ColorOutput {
param([string]$Message, [System.ConsoleColor]$Color = [System.ConsoleColor]::White)
$prev = $host.UI.RawUI.ForegroundColor
$host.UI.RawUI.ForegroundColor = $Color
Write-Output $Message
$host.UI.RawUI.ForegroundColor = $prev
}
Write-ColorOutput "=====================================" $Blue
Write-ColorOutput "Flutter Windows 앱 자동 빌드 시작" $Blue
Write-ColorOutput "=====================================" $Blue
Write-Output ""
# 1단계: 빌드 환경 정리
Write-ColorOutput "🧹 1/5 빌드 환경 정리 중..." $Yellow
flutter clean | Out-Null
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue build\windows\
Write-ColorOutput "✅ 정리 완료" $Green
# 2단계: 의존성 가져오기
Write-ColorOutput "📦 2/5 의존성 가져오기..." $Yellow
flutter pub get | Out-Null
Write-ColorOutput "✅ 의존성 준비 완료" $Green
# 3단계: Release 빌드
Write-ColorOutput "🔨 3/5 Release 빌드 중..." $Yellow
flutter build windows --release
if ($LASTEXITCODE -ne 0) {
Write-ColorOutput "❌ 빌드 실패" $Red
exit 1
}
Write-ColorOutput "✅ 빌드 완료" $Green
$BuildPath = "build\windows\x64\runner\Release"
# 4단계: DLL 복사 (옵션)
if ($IncludeDLLs) {
Write-ColorOutput "📋 4/5 필수 DLL 복사 중..." $Yellow
$VCRedistPath = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC"
if (Test-Path $VCRedistPath) {
$latestVersion = Get-ChildItem -Path $VCRedistPath -Directory |
Sort-Object Name -Descending |
Select-Object -First 1
$DLLSource = "$($latestVersion.FullName)\x64\Microsoft.VC143.CRT"
$requiredDLLs = @(
"msvcp140.dll",
"vcruntime140.dll",
"vcruntime140_1.dll"
)
foreach ($dll in $requiredDLLs) {
$source = Join-Path $DLLSource $dll
$destination = Join-Path $BuildPath $dll
if (Test-Path $source) {
Copy-Item -Path $source -Destination $destination -Force
Write-ColorOutput " ✓ $dll" $Green
} else {
Write-ColorOutput " ⚠ $dll 을(를) 찾을 수 없습니다" $Yellow
}
}
} else {
Write-ColorOutput "⚠️ Visual Studio를 찾을 수 없어 DLL 복사를 건너뜁니다" $Yellow
}
Write-ColorOutput "✅ DLL 복사 완료" $Green
} else {
Write-ColorOutput "⏭️ 4/5 DLL 복사 건너뛰기" $Yellow
}
# 5단계: Release 폴더 생성
Write-ColorOutput "📦 5/5 Release 패키지 생성 중..." $Yellow
if (Test-Path $OutputDir) {
Remove-Item -Recurse -Force $OutputDir
}
New-Item -ItemType Directory -Path $OutputDir | Out-Null
Copy-Item -Path "$BuildPath\*" -Destination $OutputDir -Recurse -Force
Write-ColorOutput "✅ 패키지 생성 완료" $Green
# 결과 출력
Write-Output ""
Write-ColorOutput "=====================================" $Blue
Write-ColorOutput "🎉 빌드 완료!" $Green
Write-ColorOutput "=====================================" $Blue
Write-Output ""
Write-Output "📍 실행 파일 위치: $OutputDir\$AppName.exe"
Write-Output "📊 패키지 크기: $((Get-ChildItem -Path $OutputDir -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB | ForEach-Object { '{0:N2}' -f $_ }) MB"
Write-Output ""
if ($IncludeDLLs) {
Write-ColorOutput "✅ Visual C++ DLL이 포함되어 있어 별도 설치 없이 실행 가능합니다" $Green
} else {
Write-ColorOutput "⚠️ 사용자 PC에 Visual C++ 재배포 패키지가 필요합니다" $Yellow
Write-Output " 다운로드: https://aka.ms/vs/17/release/vc_redist.x64.exe"
}
Write-Output ""
Write-ColorOutput "배포 준비 완료! 🚀" $Blue
# 기본 빌드 (DLL 포함)
.\build_and_package.ps1
# DLL 없이 빌드
.\build_and_package.ps1 -IncludeDLLs:$false
# 앱 이름 지정
.\build_and_package.ps1 -AppName "MyAwesomeApp"
# 출력 디렉토리 변경
.\build_and_package.ps1 -OutputDir ".\Dist"
배포하기 전에 다음 항목들을 확인하세요:
깨끗한 Windows 환경에서 테스트
개발 환경이 아닌 일반 사용자 PC에서 실행 테스트
필요한 DLL이 모두 포함되었는지 확인
dumpbin /dependents your_app.exe 명령으로 확인
앱 크기 확인
불필요한 파일이 포함되지 않았는지 점검
바이러스 백신 스캔
주요 백신 프로그램에서 false positive 발생 여부 확인
MyApp-1.0.0-Windows/
├── MyApp.exe
├── flutter_windows.dll
├── msvcp140.dll
├── vcruntime140.dll
├── vcruntime140_1.dll
├── data/
│ └── (앱 데이터 파일들)
├── README.txt ← 설치 및 실행 안내
└── vc_redist.x64.exe ← Visual C++ 재배포 패키지 (선택)
배포 패키지에 포함할 README.txt 예시:
# MyApp 설치 및 실행 가이드
## 시스템 요구사항
- Windows 10 이상 (64비트)
- 최소 100MB의 여유 공간
## 설치 방법
### 방법 1: 간편 설치 (권장)
1. 압축 해제된 폴더 전체를 원하는 위치로 이동
2. MyApp.exe 더블클릭하여 실행
### 방법 2: DLL 오류 발생 시
앱 실행 시 "DLL을 찾을 수 없습니다" 오류가 발생하면:
1. 포함된 `vc_redist.x64.exe` 파일 실행
2. 설치 완료 후 MyApp.exe 다시 실행
또는 아래 링크에서 직접 다운로드:
https://aka.ms/vs/17/release/vc_redist.x64.exe
## 문제 해결
### Q: "신뢰할 수 없는 앱"이라는 경고가 표시됩니다
A: Windows Defender SmartScreen 경고입니다.
"추가 정보" → "실행" 클릭하면 실행됩니다.
### Q: 실행 시 즉시 종료됩니다
A: 관리자 권한으로 실행해보세요.
파일 우클릭 → "관리자 권한으로 실행"
## 지원
이메일: support@yourcompany.com
웹사이트: https://yourcompany.com
더 전문적인 배포를 원한다면 Inno Setup으로 인스톨러를 만드세요:
[Setup]
AppName=MyApp
AppVersion=1.0.0
DefaultDirName={autopf}\MyApp
OutputDir=Output
OutputBaseFilename=MyApp-Setup
[Files]
Source: "Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
[Icons]
Name: "{autoprograms}\MyApp"; Filename: "{app}\MyApp.exe"
Name: "{autodesktop}\MyApp"; Filename: "{app}\MyApp.exe"
[Run]
; Visual C++ 재배포 패키지 자동 설치
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/quiet /norestart"; \
StatusMsg: "Installing Visual C++ Runtime..."; Flags: waituntilterminated
Filename: "{app}\MyApp.exe"; Description: "Launch MyApp"; \
Flags: nowait postinstall skipifsilent
Dependencies - 무료 오픈소스 도구
사용법:
1. Dependencies.exe 다운로드
2. 빌드한 앱 파일(.exe) 드래그 앤 드롭
3. 누락된 DLL을 시각적으로 확인
Visual Studio와 함께 설치되는 공식 도구
# 의존성 확인
dumpbin /dependents your_app.exe
# 더 자세한 정보
dumpbin /imports your_app.exe
일부 Flutter 플러그인은 추가 DLL이 필요할 수 있습니다:
| 플러그인 | 필요한 추가 DLL | 해결 방법 |
|---|---|---|
| sqlite3 | sqlite3.dll | 플러그인 문서 참조 |
| webview_windows | WebView2Loader.dll | Edge WebView2 Runtime 설치 |
| media_kit | mpv-2.dll, libmpv-2.dll | 플러그인 assets 포함 |
GitHub Actions 예시:
name: Build Windows
on:
push:
branches: [ main ]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.16.5'
- name: Build and Package
run: |
.\build_and_package.ps1 -AppName "MyApp" -IncludeDLLs
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: windows-release
path: Release/
| 상황 | 권장 방법 | 이유 |
|---|---|---|
| 개인 프로젝트 | DLL 직접 포함 | 간단하고 빠름 |
| 회사/상용 앱 | 인스톨러 + 자동 설치 | 전문적이고 사용자 친화적 |
| 포터블 앱 | 정적 링크 | 의존성 완전 제거 |
| 오픈소스 프로젝트 | README에 안내 | 사용자 선택권 제공 |
✅ 개발 단계에서 해야 할 일:
1. CMake 설정 최적화 (정적/동적 링크 선택)
2. 빌드 후 자동 DLL 복사 스크립트 설정
3. 깨끗한 환경에서 테스트
✅ 배포 단계에서 해야 할 일:
1. 필요한 DLL 모두 포함
2. 사용자 가이드 작성
3. Visual C++ 재배포 패키지 링크 제공
✅ 사용자에게 안내할 내용:
1. 시스템 요구사항 명시
2. DLL 오류 발생 시 해결 방법
3. 지원 연락처
Flutter Windows 앱의 DLL 문제는 한 번만 제대로 설정하면 더 이상 걱정할 필요가 없습니다. 이 가이드에서 소개한 방법 중 프로젝트 상황에 맞는 것을 선택하여 적용하세요.
가장 중요한 것은 사용자 경험입니다. 아무리 좋은 앱이라도 설치와 실행이 복잡하면 사용자는 떠나게 됩니다. DLL 문제를 미리 해결하여 사용자가 클릭 한 번으로 앱을 사용할 수 있게 만드세요.
궁금한 점이나 추가로 다뤄줬으면 하는 내용이 있다면 언제든 댓글로 남겨주세요! 🚀