Flutter Windows DLL 오류 완벽 해결 가이드 | VCRUNTIME140.dll, MSVCP140.dll 문제 해결

woogi·2025년 10월 5일

Flutter Tips

목록 보기
3/4
post-thumbnail

안녕하세요, 우기입니다! Flutter로 Windows 앱을 개발하다 보면 한 번쯤은 마주치는 골칫거리, 바로 DLL 오류에 대해 이야기해보려고 합니다. "앱이 내 컴퓨터에서는 잘 되는데 다른 PC에서는 안 돼요"라는 말, 한 번쯤 들어보셨죠?

들어가며 🤔

Flutter Windows 앱을 친구나 동료에게 공유했는데 다음과 같은 오류가 발생했다면, 이 글이 정확히 필요한 가이드입니다.

시스템에서 VCRUNTIME140.dll을 찾을 수 없어 코드 실행을 진행할 수 없습니다.
프로그램을 다시 설치하면 이 문제가 해결될 수 있습니다.

또는

MSVCP140.dll이(가) 없어 프로그램을 시작할 수 없습니다.

이런 오류는 개발 환경에서는 절대 발생하지 않지만, 사용자 PC에서만 나타나는 특징이 있습니다. 왜 그럴까요?


📋 목차

  1. DLL 오류가 발생하는 이유
  2. 자주 발생하는 DLL 오류 유형
  3. 해결 방법 1: Visual C++ 재배포 패키지 설치
  4. 해결 방법 2: DLL 파일 직접 포함
  5. 해결 방법 3: 정적 링크 빌드
  6. 완전 자동화 솔루션
  7. 예방 및 배포 전략

DLL 오류가 발생하는 이유 🔍

Flutter Windows 앱의 의존성 구조

Flutter Windows 앱은 다음과 같은 DLL 파일들에 의존합니다.

your_app.exe
├── flutter_windows.dll       (Flutter 엔진)
├── msvcp140.dll              (C++ 표준 라이브러리)
├── vcruntime140.dll          (Visual C++ 런타임)
├── vcruntime140_1.dll        (추가 런타임)
└── msvcp140_codecvt_ids.dll  (코드 변환)

개발 환경에서는 문제가 없는 이유:

  • Visual Studio 또는 Build Tools 설치 시 이 DLL들이 시스템에 자동 설치됨
  • Windows가 시스템 경로에서 자동으로 DLL을 찾음

사용자 환경에서 오류가 발생하는 이유:

  • 사용자 PC에는 Visual C++ 재배포 패키지가 설치되지 않음
  • 앱 폴더에 필요한 DLL이 포함되지 않음

오류 발생 흐름

사용자가 앱 실행
    ↓
Windows가 필요한 DLL 검색
    ↓
시스템 경로에서 DLL을 찾지 못함
    ↓
앱 실행 폴더에서도 DLL을 찾지 못함
    ↓
❌ "DLL을 찾을 수 없습니다" 오류 발생

자주 발생하는 DLL 오류 유형 📝

1. VCRUNTIME140.dll 오류

오류 메시지:

VCRUNTIME140.dll이(가) 없어 프로그램을 시작할 수 없습니다.

원인: Visual C++ 2015-2022 재배포 패키지가 설치되지 않음

영향도: ⭐⭐⭐⭐⭐ (가장 흔함)

2. MSVCP140.dll 오류

오류 메시지:

MSVCP140.dll을(를) 찾을 수 없습니다.

원인: C++ 표준 라이브러리 DLL 누락

영향도: ⭐⭐⭐⭐⭐ (가장 흔함)

3. VCRUNTIME140_1.dll 오류

오류 메시지:

VCRUNTIME140_1.dll이(가) 컴퓨터에 없습니다.

원인: 64비트 애플리케이션용 추가 런타임 DLL 누락

영향도: ⭐⭐⭐⭐ (64비트 앱에서 발생)

4. api-ms-win-crt-runtime-l1-1-0.dll 오류

오류 메시지:

api-ms-win-crt-runtime-l1-1-0.dll이(가) 없습니다.

원인: Universal C Runtime이 설치되지 않음 (주로 Windows 7/8)

영향도: ⭐⭐⭐ (구형 Windows에서 발생)


해결 방법 1: Visual C++ 재배포 패키지 설치 💊

사용자에게 권장하는 방법

가장 간단하지만 사용자가 직접 설치해야 하는 방법입니다.

단계별 설치 가이드

1단계: 다운로드

사용자에게 다음 링크를 공유하세요:

2단계: 설치

  1. 다운로드한 vc_redist.x64.exe 파일 실행
  2. 라이선스 동의 체크
  3. "설치" 버튼 클릭
  4. 설치 완료 후 재부팅 (선택사항)

3단계: 확인

앱을 다시 실행하여 정상 작동하는지 확인합니다.

장단점 분석

항목내용
장점• 시스템 전체에서 DLL 공유
• 한 번 설치하면 모든 앱에서 사용
• Microsoft 공식 지원
⚠️ 단점• 사용자가 직접 설치 필요
• 추가 다운로드 및 설치 과정
• 관리자 권한 필요

자동 설치 안내 문서

사용자에게 다음과 같은 안내를 제공하세요:

## 앱 실행 오류 해결 방법

앱 실행 시 DLL 관련 오류가 발생한다면 다음 단계를 따라주세요:

### 필수 구성 요소 설치

1. [이 링크](https://aka.ms/vs/17/release/vc_redist.x64.exe)를 클릭하여 파일 다운로드
2. 다운로드한 파일을 실행하여 설치
3. 설치 완료 후 앱을 다시 실행

### 여전히 문제가 발생한다면

support@yourcompany.com으로 문의해주세요.

해결 방법 2: DLL 파일 직접 포함 📦

앱과 함께 DLL 배포하기

사용자가 별도 설치 없이 바로 실행할 수 있도록 DLL을 앱에 포함시키는 방법입니다.

단계 1: 필요한 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

단계 2: Flutter 빌드 구조에 DLL 복사

Flutter 프로젝트의 windows 폴더에 배포 스크립트를 생성합니다.

프로젝트 구조:

your_flutter_project/
├── lib/
├── windows/
│   ├── runner/
│   └── copy_dlls.ps1  ← 새로 생성
└── pubspec.yaml

단계 3: DLL 복사 스크립트 작성

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

단계 4: 빌드 후 자동 실행

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..."
)

단계 5: 빌드 및 확인

# 앱 빌드
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 중복 (여러 앱 설치 시)

해결 방법 3: 정적 링크 빌드 🔗

C++ 런타임 정적 링크

DLL 의존성을 완전히 제거하는 가장 근본적인 해결 방법입니다.

단계 1: CMake 설정 수정

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()

단계 2: 빌드 캐시 삭제 및 재빌드

# 기존 빌드 삭제
flutter clean

# Windows 빌드 캐시 삭제
Remove-Item -Recurse -Force build\windows\

# 새로 빌드
flutter build windows --release

단계 3: 의존성 확인

빌드된 실행 파일의 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 템플릿

배포 패키지에 포함할 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

고급 팁 및 트러블슈팅 🔧

DLL 의존성 분석 도구

1. Dependencies (GUI 도구)

Dependencies - 무료 오픈소스 도구

사용법:
1. Dependencies.exe 다운로드
2. 빌드한 앱 파일(.exe) 드래그 앤 드롭
3. 누락된 DLL을 시각적으로 확인

2. dumpbin (명령줄 도구)

Visual Studio와 함께 설치되는 공식 도구

# 의존성 확인
dumpbin /dependents your_app.exe

# 더 자세한 정보
dumpbin /imports your_app.exe

플러그인별 DLL 요구사항

일부 Flutter 플러그인은 추가 DLL이 필요할 수 있습니다:

플러그인필요한 추가 DLL해결 방법
sqlite3sqlite3.dll플러그인 문서 참조
webview_windowsWebView2Loader.dllEdge WebView2 Runtime 설치
media_kitmpv-2.dll, libmpv-2.dll플러그인 assets 포함

CI/CD 파이프라인에 통합

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 문제를 미리 해결하여 사용자가 클릭 한 번으로 앱을 사용할 수 있게 만드세요.

궁금한 점이나 추가로 다뤄줬으면 하는 내용이 있다면 언제든 댓글로 남겨주세요! 🚀


profile
안녕하세요! 👋 저는 6년차 Flutter 개발자 우기입니다.

0개의 댓글