A Windows command-line tool that copies photos and videos from an iPhone to a local folder, designed for bulk transfers of large libraries. Behaves like robocopy — incremental, resumable, and fault-tolerant.
- Incremental — skips files already at the destination; only copies what's new
- Resumable — if interrupted, picks up exactly where it left off on the next run
- Fault-tolerant — per-file retry with backoff; one bad file never stops the run
- Atomic writes — copies to a
.tmpfile first, renames only on success; no corrupt partials - Streaming — transfers in 4 MB chunks; never loads an entire video into memory
- Progress display — live single-line output with files done, MB transferred, elapsed time, and ETA
- Detailed log — every file outcome written to a tab-separated log in real time
- Single executable — no installer, no .NET runtime required on the target machine
On your PC:
- Windows 10 or 11 (64-bit)
- iTunes or the Apple Devices app from the Microsoft Store — either one installs the Apple USB drivers that Windows needs to talk to the iPhone
On your iPhone:
- Connect via USB cable, unlock the phone, and tap Trust when prompted
Download iPhoneCopy.exe from the Releases page and place it anywhere — no installation needed.
iPhoneCopy <destination> [options]
iPhoneCopy D:\Photos
Just run the same command again. The state file tracks completed files and skips them automatically.
iPhoneCopy D:\Photos
iPhoneCopy D:\Photos --since 2025-01-01
iPhoneCopy D:\Photos --dry-run
iPhoneCopy D:\Photos --overwrite --no-resume
Options:
--device <name> Select device by name (if multiple iPhones connected)
--overwrite Re-copy files already at destination
--dry-run Preview only; no writes
--since <YYYY-MM-DD> Only copy files modified on or after this date
--flat Copy all files into destination root (no subfolders)
--log <file> Override the default log file path
--no-resume Ignore the state file; treat as a fresh run
--retries <n> Per-file retry count (default: 3)
--help Show help
--version Show version
iPhoneCopy is designed to run unattended across libraries of 20,000+ files. Before starting a long run:
- Disable Auto-Lock on the iPhone — Settings → Display & Brightness → Auto-Lock → Never. Re-enable it when the copy finishes.
- Keep the USB cable undisturbed
- If the run is interrupted for any reason, just run the same command again — it will resume from where it stopped
Files are copied into subfolders matching the iPhone's organization (typically by month):
D:\Photos\
202105_a\
IMG_1042.HEIC
IMG_1043.MOV
202506_a\
IMG_4983.HEIC
...
iPhoneCopy_20260322_220000.log
.iPhoneCopy_state.json
Use --flat to copy everything into the destination root with no subfolders.
A tab-separated log is written in real time alongside your photos:
2026-03-22T22:00:05Z COPIED Internal Storage/202105_a/IMG_1042.HEIC 202105_a\IMG_1042.HEIC 3145728 bytes
2026-03-22T22:00:06Z SKIPPED Internal Storage/202105_a/IMG_1041.HEIC (already exists, same size)
2026-03-22T23:45:12Z SUMMARY Copied: 18432 Skipped: 4521 Failed: 12 Bytes: 187,432,904,192 Elapsed: 1h45m12s
| Code | Meaning |
|---|---|
| 0 | All files copied or skipped successfully |
| 1 | Completed with one or more file errors |
| 2 | Fatal error (device disconnected, destination not writable, etc.) |
Requires the .NET 8 SDK and Windows 10/11.
# Build
dotnet build src/iPhoneCopy/iPhoneCopy.csproj
# Run
dotnet run --project src/iPhoneCopy/iPhoneCopy.csproj -- D:\Photos
# Publish as single-file exe
dotnet publish src/iPhoneCopy/iPhoneCopy.csproj -c Release -r win-x64 --self-contained -o ./publishThe interop assemblies in src/iPhoneCopy/Interop/ were pre-generated from the Windows Portable Devices type libraries using tlbimp.exe and are checked in — no additional SDK tools are needed to build.
iPhoneCopy uses the Windows Portable Devices (WPD) COM API, which Windows exposes when Apple's USB drivers are installed. The iPhone appears as a WPD device, and iPhoneCopy streams files directly from it over USB — no iCloud, no iTunes sync, no intermediary.
Files are transferred in 4 MB chunks and written atomically (.tmp → rename). A JSON state file records every successfully copied file, enabling instant resume after any interruption.
MIT