Case Studies

Rebuilding a Legacy System in Modern Code While Preserving Operational Fidelity

The Client

Salem Automation was brought in by a partner firm that had identified a legacy software modernization need within their own customer base but lacked the specialized scope and resources to address it. The customer relied on a software system that ran on outdated, custom hardware. That hardware was no longer available for purchase, and today’s engineers didn’t have the skills to maintain it. The system needed to be brought up to date so operations could continue to run and be supported going forward.

The Problem

The old system had two main layers: a VB6 front end that operators used to interact with the system, and a C++ back end that handled data collection and talked to the hardware. Over the years, different teams had maintained each layer separately.

At the heart of the C++ layer was a driver that communicated with a physical card plugged into an ISA expansion slot — a type of hardware connection that the industry stopped using years ago. Because the system needed that ISA slot to function, it couldn’t run on any modern machine.

On top of the hardware problem, the software itself had become fragile. The two layers weren’t formally connected, but they depended on each other in hidden ways — shared assumptions about the order things ran in, how data was formatted, and what the hardware would do. Changing one part could cause unexpected breakdowns in seemingly unrelated parts of the system.

Over time, small additions that each made sense on their own had built up into a web of undocumented rules baked into the code. Salem Automation’s engineers found cases where calling what looked like a simple function would actually set off a chain reaction across multiple parts of the system, all the way down to the hardware driver. None of this was written down. The only way to uncover it was to watch the system run, trace its behavior, and piece together the logic buried in the code.

The Solution

Discovery

Before changing anything, Salem Automation’s team studied how the entire system actually behaved. They treated the old codebase not as a list of parts to swap out one by one, but as a living system that had to be understood as a whole first. This focus on how the parts interacted — not just what each part did on its own — shaped the project’s timeline and approach from start to finish.

Choosing the New Technology

The team chose C# as the main programming language because it’s modern, well-supported, and has a large community of developers — making the system much easier to maintain long-term. They used WPF for the user interface, which cleanly separates what the screen looks like from what the application does behind the scenes, something the old system never had. And they used the Prism framework to give the new system a clear, organized structure with built-in tools for managing how different parts of the application connect and communicate.

Isolating the Hardware Dependency

The old system’s connection to the ISA hardware was scattered throughout the code with no clear boundaries. In the new system, Salem Automation wrapped that hardware connection behind a single, clearly defined interface. This did two things: it made the hardware dependency visible for the first time, and it created a clean boundary so the hardware can eventually be replaced without having to rework the rest of the system.

The system still needs an ISA-equipped machine to run until the hardware is physically replaced. But now that dependency is clearly identified and contained in one place, rather than hidden throughout the code.

Building in the Right Order

Because so many parts of the system depended on each other, the team couldn’t just rebuild pieces at random. They worked from the bottom up — starting with the foundational components that other parts relied on, then moving to the layers above them. At every step, they checked that the new version behaved exactly the same way the old one did. The old system’s behavior was the spec.

The Results

Legacy systems are not simply old code. They are records of decisions made under real constraints, by real engineers, in response to real operational needs. Respecting that history — understanding it before attempting to change it — is the foundation of modernization done well.

  • The project delivered a fully modernized system built on C#, WPF, and Prism.
  • The new system behaves exactly like the original, but now sits on an architecture that’s easier to maintain, understand, and extend.

The ISA hardware dependency is now clearly visible in the system’s design, giving the client a straightforward path to replace the hardware whenever they’re ready.

Maintain Thriving Legacy Systems with Salem Automation

We use cookies and other tracking technologies to improve your browsing experience on our website, to show you personalized content and targeted ads, to analyze our website traffic, and to understand where our visitors are coming from.