Your build agent compiles the vision application in minutes; the target PC then fails on first run with a missing DLL. The gap between those two events is the SDK boundary: managed wrapper assemblies travel with your executable, and the native runtime under them does not. This guide splits the job the way that boundary demands, so a machine without the SDK installed can still build your code while every target gets its runtime in one administrator setup. You will find the component inventory, a deployment sequence you can script, the startup checks that catch a bad target, and a worked example with twelve controllers on a camera line.
What compiles without the SDK and what runs without it
A .NET compiler asks one thing of an SDK: the managed wrapper assemblies your code references. Copy those wrapper DLLs into a lib folder in your repository, or publish them to an internal NuGet feed, and a build agent with no SDK installed produces your executable. The compiler only checks the wrapper's public types, so the full product never has to be on the build machine.
Execution asks for the rest, and that part never travels with your output. Every wrapper is a thin translation layer over native libraries, and those libraries are version-locked to an installed runtime. Vendors ship the wrappers inside their own setup — many install them to the global assembly cache — so that wrapper and native versions stay matched on a working machine. A wrapper-only package that promises a runnable application delivers the opposite: the first camera open or processing call fails, because the wrapper requires an installed runtime of at least the version it was built against.
The rule that drives everything else: your build output travels, the vendor's installed base does not. Design the deployment around that split and both sides stay simple.
The native stack an administrator setup installs
Three kinds of components sit under your application, and copying files cannot deploy any of them:
- Transport drivers. A GigE Vision setup installs a filter driver that binds to the camera network interface and hands packet streams to the SDK. Windows registers a driver only from an elevated installer.
- Device services. Background services enumerate cameras, hold acquisition state and manage the stream path. The service control manager accepts them the same way: from an elevated setup.
- Licensing services. A license manager validates dongles or software licenses and answers your process at runtime. It runs as a service for the same reason, and it must be up before the first acquisition.
The administrator requirement is not paperwork; the operating system genuinely refuses driver and service registration without it. Run the vendor setup once per machine during imaging, reboot when the driver asks, and the installed base is settled for the life of the station. When the filter driver is missing after an install, the usual cause is a skipped elevation — the GigE configurator admin-rights error and its fix walks that exact case. When licensing behaves oddly, the SDK watermark and licensing-service diagnosis is the companion read.
Build on a clean agent without installing the SDK
Treat the wrapper assemblies as versioned artifacts of your own build, not as parts of an installed product:
- Commit the wrapper DLLs to a lib folder in the repository, or push them to your internal NuGet feed with an explicit version per release.
- Reference them with copy-local enabled, so every build drops the wrappers beside the executable.
- Remove any reference that resolves into an SDK install directory; a build that leans on a Program Files path breaks the next time the agent image changes.
- When you raise the runtime version on the targets, rebuild against the matching wrappers in the same change. The wrapper version is the contract between your code and the installed base.
The agent then compiles the whole application and still cannot run it, which is the correct state: continuous integration proves the code builds, and the target proves it runs. The same isolation discipline shows up on containerized build agents from the header side — the SDK header fix for containerized builds covers that variant.
Deployment sequence for a target that never had the SDK
You need the vendor runtime installer, administrator rights on the target, your application package, and the pre-flight constants described in the next section.
- Run the vendor runtime setup once, as administrator, on the imaged target. Reboot when the driver asks for it.
- Confirm the three component groups: the transport driver is bound to the camera interface, the device services show Running, and the license service responds.
- Deploy your application by the normal script or MSI: executable plus wrapper DLLs, and nothing from the SDK's install folder.
- Match bitness: build the executable for the platform the native runtime was installed as, x64 on a 64-bit Windows target.
- Run the pre-flight checks before the first production piece.
- Record the installed runtime version on the station's build sheet; that number becomes the minimum your next build requires.
- Ship every later application update as a plain file copy — the installed base does not change, so no elevation and no reboot are needed.
The same file-copy-versus-elevated-setup split holds on edge controllers. If your deployment spans one, this native Python package build-and-deploy guide walks the same boundary from the device side.
Pre-flight checks that fail fast
Five checks at startup, before the first camera open, turn a grey failure into a named one:
- Native load test. Try loading the vendor's core native library inside a try/catch. A caught exception names the file and the missing dependency directly.
- Version gate. Read the file version of that library and of the wrapper, and compare both against the minimum compiled into your application.
- Bitness gate. Compare the process platform against the native runtime before any load, because a 32-bit process on 64-bit libraries otherwise fails at the first call.
- Service check. Query the device and licensing services; a stopped service gets named in the error instead of surfacing as a timeout.
- License request. Ask for the acquisition license context and surface the vendor's return code if it is refused.
When one of these fires on the floor, the missing-DLL startup diagnosis is the follow-up routine that turns the named error into the fixed component.
Resist the temptation to fix a failed check by copying native DLLs into system folders or onto PATH. The Windows loader resolves dependencies by its documented Dynamic-Link Library Search Order, and folder or environment overrides that work on your bench break silently when the next runtime update moves a file. Keep the runtime where the setup put it.
Worked example: four cameras, twelve controllers, one build agent
Inputs. Example fleet numbers: twelve stations, four GigE cameras opened per station, eleven wrapper DLLs in the build output, and a runtime the application was built against at version 4.2. The per-target component inventory comes from the native-stack section: one filter driver, two device services and one licensing service — four admin-installed components per target. The target hardware in this example is a compact vision controller from the shop range, the MV-VC2140-128G40-1T.
Rule. A station is ready when all four admin-installed components are present at or above version 4.2, and the application package contains only managed files.
Arithmetic. Copying the application folder to all twelve stations places 11 of 11 managed files per station and 0 of 4 runtime components: the pre-flight reports 4 failed checks per station, and 12 × 4 = 48 failures across the line. Running the vendor setup once per station costs 12 elevated setup runs and at most 12 reboots; after that every station reports 4 of 4 components at version 4.2 or newer. Every later application update is then 11 files × 12 stations = 132 file copies, with no elevation and no reboot.
Decision. The threshold is zero: any missing or outdated component means that station needs the setup run again, not more file copies. Once the four components are green, deployment stays copy-only for the life of the fleet.
The target in this example:
- LAN ports
- 3-4 LAN ports
- USB 3 ports
- 2 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
Choosing target hardware with the licensing already settled
Runtime licensing is the one deployment input that ordering can settle for you. Some vision controllers ship with the vision software license already included; others ship without a license key, which puts the licensing step on your rollout plan. Decide before the fleet is imaged, because a target without its license cannot pass the pre-flight license request no matter how clean the install is.
Two ends of that decision:
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
- LAN ports
- 3-4 LAN ports
- USB 3 ports
- 2 USB 3 ports
- PoE
- PoE camera ports
- Light outputs
- 6 built-in channels
The same comparison across the three controllers named above:
| Specification | MV-VC3301H-128G66 | MV-VC4712-256G10-2TH | MV-VC2140-128G40-1T |
|---|---|---|---|
| CPU | Intel® Core i3-8100 | Intel® Core Ultra 7 processor 255H | Intel® Processor N97 |
| Memory | 8 GB | 2 × DDR5 6400 MHz non-ECC SO-DIMM memory slots; Up to 48 GB per slot, Up to 96 GB with two slots | 8 GB |
| Storage | 128G SSD | 1 × 7-pin SATA3.0, 1 × M.2 SATA 2280, 1 × M.2 NVMe 2280; 1 × 2.5"/3.5" drive bay | 128 GB SSD + 1 TB HDD |
| GPU | Intel® HD Graphics 630 | Intel® Arc 140T GPU | Intel® UHD Graphics |
| Operating system | Windows 10 64-bit, Not activated | Windows 11 64-bit (not activated) | Unactivated 64-bit Windows 10 LTSC 21H2 |
| Encryption method | VM6200Pro license key | MV-VC47**-**6-**: VM6200pro encryption supported; MV-VC47**-**0-**: encryption not supported | Not support |
| Video output | HDMI interface × 1, VGA interface × 1; Supports independent display output at the same time; Max. resolution 1920 × 1080 @ 60 Hz | Independent dual display supported; 1× HDMI port, Up to 1920 × 1080 @ 60 Hz; 1× VGA port, Up to 1920 × 1080 @ 60 Hz | HDMI interface × 1, VGA interface × 1; Supports independent display outputs at the same time; Max. resolution 1920 × 1080 @ 60 Hz |
| Digital I/O | 8 digital isolated inputs supported; 16 opto-isolated outputs supported (NPN/PNP switchable) | 18 digital isolated inputs supported; 18 isolated digital outputs | Opto-isolated input × 8; Opto-isolated output × 8 |
| Network interface | 6× Gigabit Ethernet ports | 4× Gigabit Ethernet ports; PoE power supported, 15 W per port, 25 W total across 4 ports | GigE interface × 4 |
| USB Interface | USB 2.0 × 4; USB 3.0 × 4; Built-in USB 2.0 × 1 | 4× USB 2.0 ports; 2× USB 3.0 ports; 1 × internal USB2.0 port | USB 2.0 × 2; USB 3.0 × 2 |
| Serial Port | 2× full-function RS-232, RS-485/RS-422 switchable | 2 × configurable RS-232/RS-422/RS-485 | RS-232 × 1, supports switching to RS-485 or RS-422 |
| Light interface | 4-channel 24 V constant-voltage light drive, Max. power per channel: 72 W, Max. power (4 channels): 150 W | SMR-03V-BC female; 6-channel 24 V constant-voltage light drive, Max. power per channel: 72 W, Max. total power: 110 W | Light interface with 24 VDC constant voltage × 4; (Brightness is adjustable. Max. current 3 A for single light interface, and total max. power consumption 80 W. Supports light mode switching between strobe and solid via external control) |
| Price | $2,419.00 | $6,049.00 · quoted | $1,679.00 |
All 3 share: Power supply 24 VDC; Certification CE, KC. Values as printed in each product's data sheet; open a part for its drawing and full specifications.
Vision computers and fanless industrial PCs
190 models · from $1,119.00The cameras feeding the application are the other half of the inventory; the area scan cameras range covers the GigE, USB3 and CoaXPress models these targets serve. When you shortlist targets from scratch, you can filter the vision controllers category by LAN port count, USB 3 ports and built-in light channels.
Shortcuts that cost a weekend
- Copying wrappers out of the global assembly cache of a working machine: they match yesterday's runtime, not your next build. The internal feed stays the single source of truth.
- PATH and System32 edits: the loader's search order makes them work on the bench and fail on the line. The app-local folder plus the setup's installed locations is the whole mechanism you need.
- Assembly.LoadFrom and lazy loading to dodge the version gate: they move the failure from startup to first use, which is the worst place for it on a running line. The same applies to install-path environment variables, which an installer update can repoint silently.
- x86 builds against x64-only native runtimes: match bitness at build time. The failure pattern has a named shape — the wrapper bitness fix shows the error and the exit.
- Installing the full SDK on production targets to make an error disappear: it puts developer tools on the line PC and hides which component was actually missing.
Linux targets split the same way: your files copy, the vendor stack installs with root rights, and device access follows the distribution's rules. When a Linux target still cannot find the camera after a clean install, the Linux access-error isolation routine is the next stop.
The decision and the ship checklist
The decisions, per machine:
- A machine that only builds: wrappers by feed or lib folder, no SDK, no elevation, and it never opens a camera.
- A machine that runs the line: one elevated runtime setup during imaging, then copy-only application updates, and a green pre-flight before the first piece.
- A station that fails pre-flight: run the setup again. File copies cannot supply a driver or a service, so more copying never fixes it.
Ship checklist:
Build side:
- Wrapper versions pinned in the feed or lib folder and matched to the minimum runtime version — the wrapper is the contract.
- Copy-local on and no references into SDK install paths — the agent must build with the product absent.
- Minimum-version and service-name constants compiled into the app — startup has to name the problem, not guess.
Target side:
- Runtime setup run once as administrator and the requested reboot done — drivers and services cannot register without elevation.
- License service responding to a test request — an unlicensed target fails at first acquisition however clean the rest is.
- Installed runtime version recorded on the station sheet — the next build needs its minimum.
First run:
- Pre-flight green, then one known-good part inspected end to end — green checks plus one good image is a deployment actually proven.
For the wider bring-up that surrounds this, the target discovery checklist for embedded vision projects covers the discovery half, and the systems topic page gathers the rest. If you want a second pair of eyes on a rollout plan, the contact page is the direct line to us.
Questions
Can I wrap the vendor's .NET wrapper DLLs in my own NuGet package?
Yes, for compilation. Keep the package private and put only the managed wrapper assemblies in it. That lets a build agent without the SDK produce your executable. It does not make the application runnable: the wrapper still binds to an installed vendor runtime of at least the version you compiled against, and the driver, services and licensing on each target come only from the vendor setup run as administrator. Check the redistribution terms in the vendor license before sharing the package.
Why does my application throw BadImageFormatException on only one PC?
That error means a bitness mismatch: a 32-bit process tried to load a 64-bit native DLL, or the reverse. The wrapper loads; the native library behind it does not. Match the platform target of your executable to the native runtime installed on that machine; on 64-bit Windows that usually means building AnyCPU or x64 and installing 64-bit native libraries. Run the bitness check at startup so the application reports the mismatch by name instead of failing on the first camera open.
Do production PCs need the full SDK installed?
No. The IDE, samples and documentation in an SDK are developer content. A production target needs the runtime side: the camera driver, the device services and the licensing service, plus the wrapper assemblies your executable carries. Many vendors ship a runtime-only installer for exactly this; if yours does not, run the full setup once during imaging and leave the development tools unused. The application itself stays a plain file copy after that.
How do I check the installed runtime version at startup?
Read the file version of the vendor's core native library with a version-info call, and compare it against a minimum-version constant compiled into your application. Do the same for the managed wrapper. If either is below the minimum, stop with a message that names both numbers. Query the licensing and device services through the service controller as well, because a correct version with a stopped service still fails on the first acquisition.
Does the same split apply to Linux targets?
Yes. Managed wrapper assemblies copy with your application just as on Windows, while the native stack installs from vendor packages with root rights, and services register under the system service manager. Camera access rights, udev rules and network driver setup are the usual runtime-side tasks. If the application then still cannot find the device, work through a Linux access-error isolation routine before touching your own code.


