Building Windows software from a Mac: a borrowed computer, a virtual machine and a photo of an error
Schools run Windows. We work on a Mac and Ubuntu. This is how Tziyun B'Rega learned to build and test for Windows, and the photo that taught us the most.
6 min read

We sent a build to a tester, and the tester sent back a photo of the screen. The program refused to open, because a support file was missing. Windows calls such files DLLs.
That photo changed how we build and check. Tziyun B’Rega runs on Windows computers, and we build it on a Mac and an Ubuntu desktop. The gap sounds small, and it became one of the hardest parts of the project. Here is the rest of the story in the order it happened.
Key points
- A tester sent back a photo: the program refused to open on Windows because a support file, a DLL, was missing. On our machines everything worked.
- A Windows program has to be built on a real Windows: first on a family member’s computer, then in a virtual machine.
- The fix: the program now carries what it needs inside itself and stays a single file.
- Our in-house system builds, checks and asks a person to approve each build, and end-to-end tests run on a separate computer, our builder machine.
This program has to be built on a real Windows
Parts of the program rely on libraries written in C, a lower-level language, and those need the full Windows toolchain (the set of tools that turns code into a program) to compile. Our own decision record (a short note we wrote when we chose between options) from 17 July 2026 says it plainly: the Windows program cannot be cross-compiled from Linux or macOS. It has to be built on Windows.
What does “build” mean?
Developers write a program as text. To build it, a tool called a compiler turns that text into a finished program the computer can run, like turning a recipe into a baked cake. Compiling is the main step of building.
So the first question was whether it even compiles and runs on Windows, before any talk of automation. The first Windows build was done by hand on a family member’s ordinary Windows computer, just to see it compile and work. The first entry in the project history that sets up the Windows-native toolchain is dated 14 July 2026.
What is a project’s history?
A repository is the folder where a project’s files are kept together with a record of every change. Each time someone saves a set of changes with a short note, that is called a commit, so the history reads like a diary with dates. We use it to see what we did and when.
Then a virtual machine, with proof first
A computer you borrow is not a build system. The next idea was a virtual machine, a pretend Windows computer running inside another computer, so builds could be repeated and started from clean. We were afraid it would be slow or strange, and we did not want to invest in it before we knew a build could compile and run at all. That fear came before the facts. We never measured it.
Once the borrowed computer had shown it worked, we built the VM route. By 17 July, three days after that, a Windows 11 virtual machine with no screen could build the program from Linux or macOS. The decision record explains one costly lesson: our first way of copying the code into the machine silently garbled Hebrew file names (fonts and exam files). Nothing failed. The names were just wrong. After that we copied code only through git, the tool that keeps the project’s history.
Back to the photo
The program worked on our machines because the builder machine had those support files installed. A school computer does not, and it should not need them. No school should be asked to install extra software because we used it.
We reproduced the error exactly on 14 August by taking the extra drive off the builder machine. Then we fixed it the way an offline product should be fixed: the program now carries what it needs inside itself and stays a single file.
The lesson was bigger than the fix. Everything that was true on our machines had to be checked on a clean one.
Our in-house system
That is the thinking behind our in-house system for building the project’s software and testing it, which began on 12 August 2026. We drive it from the Mac, and it does three things:
- Build. It builds the Windows program inside the virtual machine and stores the result.
- Check. It runs tests and must-pass checks: that the interface is really embedded in the program, that nothing is missing which Windows does not provide (the check that would have caught the photo), that the program starts, and that updating works.
- Approve. A person signs off one specific build. It always asks a human, and no option skips the question.
One rule came from experience: “the program is running” is not proof that it works. For its checks, the system takes a picture of the virtual machine’s screen and reads the words on it.
The builder machine
The virtual machines run on a separate computer with Ubuntu installed, our builder machine. Its notes record a limit we learned the hard way: its memory fits one virtual machine at a time. Two at once froze that machine. On 14 August, while one virtual machine held 8 GB, unrelated tests failed in ways that looked like code bugs, until someone looked at the memory. The system now enforces one at a time.

Testing the real program
Wails (opens in a new tab) shows the screen using the web view built into Windows. On 26 August 2026 we proved that this web view can be opened for remote control with the Chrome DevTools Protocol (opens in a new tab), the channel developers use to inspect web pages. It is off unless switched on for a test, and the program is the same file either way. From the builder machine we connected to the running program and read values out of its real screen.
That made automated end-to-end tests (tests that go through the whole program from start to finish) possible. We call them playbooks. Each one starts from a fresh machine, goes through first-run setup like a new user, does a real task, and ends with a pass or fail table. We do not fill the database to skip steps, because that would test something other than the real program. The runs are meant to be watched like a video, slowly enough for a person to follow.
Pretending to be a weak school computer
One scenario makes the test machine behave like a poor school PC: two processor cores, 4 GB of memory, and heavy load running at the same time. In that run, on 23 October 2026, the scanner list gave up after one search and reported that it found no scanners although the scanner was there. We fixed it so the list keeps searching. We found the problem because we had made the test hard.
What we learned
None of this was planned in advance. Each tool exists because something went wrong once. We built this lean and carefully, without cutting corners, and the machine does the remembering: the checks, the approvals and the tests.
Nothing in this story matches your search.
Read next
A mouse pointer that looked wrong on WindowsThe same program can look different on every operating system. One day the mouse pointer changed on Windows, so we chose our own pointer and learned to test the small things.
Watching a school computer from far away: what the logs taught us about small computersTziyun B'Rega sends its logs home so we can see it work where we cannot visit. A small computer in a remote town showed us that a computer's size, and in the end its processor, decides how well the program runs.