# Simple Scanner for Windows

A small, free Windows app for scanning paper to **PDF, JPG or PNG**, with a remembered default
save location, remembered scan settings, and one-click **email**.

Freeware — no charge, no licence key, no account, no telemetry.

Built with .NET 8 / WinForms and Windows Image Acquisition (WIA), so it works with any scanner that
has a normal Windows driver — flatbed or document feeder.

## What it does

- **Scan** from any WIA scanner: flatbed, feeder (ADF) or double-sided feeder.
- **Multi-page**: keeps feeding until the ADF is empty; pages appear as thumbnails you can reorder,
  rotate or delete before saving.
- **Save as PDF** (all pages in one file), **JPG** or **PNG** (one file per page).
- **Default save folder** and **default settings** (format, colour, resolution, page size, source,
  file-name pattern, JPEG quality) are remembered between runs.
- **Email the scan**: either through your desktop mail client (Outlook gets the attachment added
  automatically) or straight through an SMTP server you configure.
- **Driver dialog fallback** for scanners with unusual options, and **Add image file...** so you can
  turn existing images into a PDF.

## Privacy

Simple Scanner has no analytics, no accounts and no background network activity. Your scans stay on
your PC unless you choose to email them, in which case they go to your mail client or your own SMTP
server. Full policy: <https://insta.host/privacy>.

## Requirements

- Windows 10 or 11
- A scanner with a WIA driver (virtually all consumer/office scanners and MFPs)
- Nothing else for the standalone build; the small build needs the
  [.NET 8 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/8.0)

## Build

From this folder, with the .NET 8 SDK installed:

```powershell
# standalone .exe - no runtime needed on the target PC (~70 MB)
.\build.ps1

# smaller .exe - requires the .NET 8 Desktop Runtime (~9 MB)
.\build.ps1 -Standalone:$false
```

Or directly:

```powershell
dotnet publish src\SimpleScanner\SimpleScanner.csproj -c Release -r win-x64 `
  --self-contained true -p:PublishSingleFile=true `
  -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true `
  -o publish\standalone
```

The result is a single `SimpleScanner.exe` you can copy anywhere — no installer required.

## Using it

1. Pick your **scanner** (press *Refresh* if it was switched on after the app started).
2. Choose **source**, **colour**, **quality** (dpi), **page size** and **Save as** format.
3. Press **Scan**. Each page shows up in the Pages list; click one to preview it.
4. Tidy up if needed — right-click a page to rotate, reorder or delete it.
5. Press **Save**, or **Save & email...** to save and then send it.

### Defaults and settings

*Settings...* stores everything in `%APPDATA%\SimpleScanner\settings.json`:

| Setting | Notes |
| --- | --- |
| Save folder | Defaults to `Documents\Scans`, created on demand |
| File name pattern | Braces contain a date format, e.g. `Scan_{yyyy-MM-dd_HHmmss}` or `Invoice_{yyyyMMdd}` |
| Format / colour / dpi / page size / source | Pre-selected each time the app starts |
| JPEG quality | 10–100, used for JPG output only |
| Open the file after saving | Opens the finished PDF/JPG/PNG in your default viewer |
| Clear the page list after saving | Leaves the app ready for the next document |

Existing files are never overwritten — a second `Scan.pdf` is saved as `Scan (2).pdf`.

### Email

Two ways to send, chosen in *Settings* or in the email dialog:

- **Desktop mail client** (default) — if Outlook is installed, a draft opens with the scan already
  attached, so you can review it before sending. Otherwise your default mail app opens with the
  subject and body pre-filled and Explorer highlights the file to drag in.
- **SMTP server** — sends directly. Fill in server, port, TLS, username, password, from name and
  from address, then use *Send test email* to check it. Port 465 uses implicit TLS; every other port
  uses STARTTLS when TLS is ticked. The password is encrypted with Windows DPAPI for your user
  account and is never written in clear text.

## How it works

| Area | Detail |
| --- | --- |
| Scanning | WIA automation via late binding, so no COM interop assembly is needed. Resolution, bit depth, intent and the scan extents are pushed to the driver; unsupported properties fall back to the driver default rather than failing. |
| Feeder | Repeats the transfer while the driver reports "feed ready", and stops cleanly on `WIA_ERROR_PAPER_EMPTY`. |
| Page cache | Pages are held as lossless PNGs in `%TEMP%\SimpleScanner\<session>` and only thumbnails stay in memory, so a 50-page 600 dpi scan will not exhaust RAM. The folder is deleted when the app closes. |
| PDF | PdfSharp, one image per page, page size derived from the pixel size and the scan dpi so an A4 scan produces an A4 page. 1-bit black & white pages are expanded to 24-bit first because PDF image embedding cannot handle sub-byte bit depths. |
| Threading | Scans run on a dedicated STA thread, keeping the UI responsive and the COM apartment correct. |

## Project layout

```
src/SimpleScanner/
  Program.cs             entry point + global error handling
  AppSettings.cs         persisted settings (JSON in %APPDATA%)
  DataProtection.cs      DPAPI wrapper for the SMTP password
  StaTask.cs             runs scans on an STA thread
  Scanning/              WIA device enumeration, properties and transfers
  Output/                page cache, PDF/JPG/PNG writers, file naming
  Mail/                  SMTP (MailKit) and Outlook/mailto handoff
  UI/                    main window, settings dialog, email dialog
```

## Troubleshooting

| Symptom | Fix |
| --- | --- |
| "No scanner found" | Switch the scanner on, plug it in, then press *Refresh*. Network scanners must be added under *Settings → Bluetooth & devices → Printers & scanners* first. |
| "Windows Image Acquisition is unavailable" | Start the *Windows Image Acquisition (WIA)* service (`services.msc`). |
| Scan is cropped or has a black border | Choose the page size that matches the paper, or use *Scan using driver dialog...* |
| Feeder scans only one page | Choose *Feeder (ADF)* rather than *Flatbed* as the source. |
| PDFs are large | Use greyscale or black & white, or drop to 200/300 dpi — output is lossless, so dpi drives the size. |

---

Freeware by [Patrick Hamid](https://linkedin.com/in/phamid) ·
[More free tools](https://insta.host/tools) ·
[☕ Buy me a coffee](https://coffee.insta.host)
