OP on Windows: one plugin for window binding, capture, input and OCR
Windows消息模拟,gdi,dx,opengl截图,找图,找字(OCR)
At a glance
- What is it?
- OP (Operator & Open) is a C++ automation plugin for Windows that puts window binding, seven screen capture backends, input simulation, colour and image search, dot matrix OCR and an HTTP path to YOLO behind a single interface, exposed as COM, a C API, Python and Go bindings. Its main cost is that the heavier recognition work runs in services you have to run yourself.
- Who is it for?
- Adopt OP if you are writing Windows desktop automation in Python, C++ or a COM host language and you want capture, input simulation and image matching from one vendor with no separate screenshot library. Do not adopt it if you need cross platform support, an offline single binary recognition stack, or a project that forbids process memory access, because the plugin carries DLL injection and memory read write features and ships no OCR or YOLO engine of its own.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 42 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem OP addresses is a Windows desktop with no scripting layer
OP is short for Operator and Open, and it is a Windows automation plugin written in C++. The problem it solves is narrow and practical: a script that drives a Windows desktop has to reach for a separate library for every single job. One library finds a window and binds to it in the background, another grabs a screenshot from a DirectX surface, a third injects a keystroke, and a fourth does template matching. The project description lists window enumeration, process queries, window state control, background binding, screenshots, mouse and keyboard simulation, colour and image search, OCR, OpenCV, YOLO HTTP detection and process memory read write as features of one package, and the library directory layout backs that claim, with separate subdirectories for window handling, capture, hook, input, image, ocr, opencv, memory, ipc, network, algorithm and yolo.
The audience is script authors and desktop automation programs on Windows. The wiki is described as holding installation, interface notes, OpenCV, OCR, registration free usage and multi-language examples, and a separate OPTestTool repository is linked as a test harness. The licence is MIT, and the published package is a DLL rather than an application, so nothing here is a product in its own right. It is a dependency you call from something you write.
Seven capture backends sit behind one interface, and binding splits the display handle from the input handle
The capture directory holds GDI, DXGI, WGC and hook based backends, and the documented list of screenshot methods runs to ordinary windows, GDI, DXGI, WGC, DirectX hook, OpenGL and OpenGL ES. That is the shape of the problem rather than feature padding. A game window, a remote desktop session and a WebGL canvas do not answer to the same capture call, so the plugin keeps a separate backend for each and exposes them through the same API.
The second detail worth knowing is how binding is split. The feature list distinguishes ordinary binding, background binding, and a mode where the display handle and the input handle are separated. A display handle is what you would read pixels from, and an input handle is what you would send input to. Keeping them apart lets a script read the screen of one surface while directing input at another, which is the situation that comes up when a protected surface sits above the window the script is actually driving. The hook directory is where the more invasive parts live, listed as remote injection, display hook, input hook and shared frame writing, and the ipc directory wraps shared memory, mutexes and pipes for the process to process communication that this kind of hooking needs.
OCR runs two separate routes, one of which needs a service you must host
There are two OCR paths and they have nothing in common. The first is a dot matrix font library route for fixed font screens, and it is compatible both with OP's own binary font libraries and with the DaMo text dot matrix font format. The second is a general OCR route that calls an independent HTTP service, op_ocr_engine, with backends such as Tesseract and PaddleOCR doing the recognition.
The practical consequence is that the dot matrix path is self contained and the general path is not. Font libraries can be loaded from a local file or from memory, so a program can bundle its templates instead of shipping data files next to the executable, and the ocr directory is where font library management and recognition sit. But if your screen uses proportional fonts, anti-aliasing or a language the dot matrix libraries do not cover, you are in the HTTP case, and that means standing up op_ocr_engine yourself. The project documents this in doc/ocr.md and does not bundle an engine, so the recognition quality you get is the quality of the backend you chose to host.
YOLO detection is a request wrapper, not an inference runtime
The object detection path follows the same split as the general OCR path. OP handles taking the screenshot, reading the image and wrapping the request, and the model inference itself is done by a separate service. The interface is described in doc/yolo.md, and the repository ships a minimal service example at tools/op_yolo_engine.py, which is the clearest sign of where the boundary sits.
This is a reasonable design rather than a gap. Running inference in a separate process keeps a heavy dependency out of the plugin DLL, which matters when the plugin is loaded into a host process that has its own idea of what memory it wants to spend, and it also means you can swap PaddleOCR style pipelines or a different detector behind a stable HTTP contract. The cost is operational. A detection call now depends on a service being up, reachable and fast enough for your loop, and the plugin will not help you if that service is missing. If your target is a handful of fixed images rather than a varied stream, the bundled OpenCV template matching and feature matching paths are the more direct answer, and those run inside the plugin.
pip install op-plugins is the short path, and the architecture suffix is the trap
The quickest way to use the project is the op-plugins wheel, which targets users who work with the pyop package directly. It supports Python 3.9 through 3.12 and ships two builds, one for win32 and one for win_amd64. The installation is a single command, and the check afterwards is a one-liner:
pip install op-pluginsfrom pyop import Op
op = Op()
print("op version:", op.Ver())python -c "from pyop import Op; print(Op().Ver())"The wheel already contains the OP runtime files for its architecture, so there is no need to copy DLLs out of a zip by hand. To install a specific wheel from a release, point pip at the release asset and substitute the real tag and file name:
pip install https://github.com/WallBreaker2/op/releases/download/<tag>/<wheel>.whlTwo things catch people here. A 64 bit Python needs the win_amd64 wheel and a 32 bit Python needs the win32 wheel, and mixing them up fails at import time rather than at build time. And there are two separate Python surfaces in the tree. The pyop package is generated through SWIG, while the directory bindings/python is a ctypes based wrapper over the C API, and the project describes them as independent from each other, suited to callers that want to reach op_c_api_x86.dll or op_c_api_x64.dll directly. Pick one and do not assume the two behave identically.
COM registration needs regsvr32, and the registry free route lives only in the wiki
If you host the plugin through COM, the DLL has to be registered first, and which DLL you register depends on the bitness of the host program. The commands are plain regsvr32 calls against the two shipped binaries:
regsvr32 .\op_x86.dllregsvr32 .\op_x64.dllOnce registered, a Python script reaches the component by dispatching the ProgID, and the version call is the usual first check:
from win32com.client import Dispatch
op = Dispatch("op.opsoft")
print("op version:", op.Ver())Registering into the machine registry is often not an option on locked down or shared machines, and the project has a registration free path for that reason. That path is documented in the wiki rather than in the repository tree, at the install page and at a Python registration free example, and the same wiki index carries examples for C#, Lua, Golang, Rust, Node.js and Java. The tools directory is where the registration free loader and the YOLO service example live, so the capability exists in code, but the step by step usage is external to the repository.
Building from source needs Visual Studio, CMake and Python, and produces DLLs plus a wheel
The stated build requirements are Windows 10 or newer, Visual Studio 2022 or newer, CMake 3.24 or newer and Python 3.12 for the build script, the SWIG bindings and the test tools. The recommended entry point is build.py at the root, and the flags mirror what the CI runs:
python build.py -g vs2026 -t Release -a x64The Release output is installed into bin/x86 or bin/x64, and a published package is expected to carry the plugin DLLs for both architectures, the matching C API DLLs and import libraries, the tools DLL, the compiled pyop extension and the pyop Python module. To produce a wheel locally, the project lists scikit-build-core and setuptools-scm as the build requirements and points at a PowerShell script:
pip install scikit-build-core setuptools-scm.\scripts\build_wheel.ps1If you drive it by hand, run build.py once so the dependency bootstrap happens, then let pip do the wheel build:
python build.py -g vs2026 -t Release -a x64pip wheel . --no-deps -w wheelhouseThe packaging metadata confirms the shape of the project. The pyproject file names the distribution op-plugins, requires Python from 3.9 up to but not including 3.13, sets the build backend to scikit-build-core, turns on SWIG generation and the Python wheel target, and disables the C++ test build, with a fallback version of 0.4.8.3. The published releases follow that line, with 0.4.8.1 on 2026-07-03, 0.4.8.2 on 2026-07-05 and 0.4.8.3 on 2026-07-07. The last push was on 2026-09-11 and the repository is not archived, so the tree is still moving, although the release tags and the last push are separated by about two months.
The feature list includes memory writes and DLL injection, and that narrows who may use it
The capability list ends with process memory read and write, assembly calls and assorted algorithm utilities, and the repository tree backs it, with a memory directory for target process memory access and a window directory that includes DLL injection. For a scripting plugin this is normal territory, since a lot of Windows automation exists to drive applications that expose no scriptable interface. It is also the reason to read the terms of the software you point this at, because an application that checks for injected modules or writes to its own memory will not welcome it.
Two more limits are worth stating plainly. The project is Windows only, the classifiers list Microsoft Windows as the supported operating system and every wheel is built for win32 or win_amd64, so none of this carries to Linux or macOS. And the general recognition paths are services, which means the plugin alone is not a complete recognition stack. The README lists TSPLUG and Kiero as reference projects without describing either of them, so for an alternative there is nothing documented to compare against here. In practice the real choice is between using OP's bundled template matching for fixed images and running a separate OCR or detection service for everything else.
Editorial conclusion
Adopt OP if you are writing Windows desktop automation in Python, C++ or a COM host language and you want capture, input simulation and image matching from one vendor with no separate screenshot library. Do not adopt it if you need cross platform support, an offline single binary recognition stack, or a project that forbids process memory access, because the plugin carries DLL injection and memory read write features and ships no OCR or YOLO engine of its own. Before committing, verify the wiki install page for the registration free path, confirm the wheel architecture matches your Python bitness, and check that the separate OCR and YOLO services are acceptable in your environment.
Frequently asked questions
How do I install OP on Windows for use from Python?
Install the op-plugins wheel with pip, then import the pyop package and call Op().Ver() to confirm the plugin loads. The wheel supports Python 3.9 to 3.12 and carries the runtime files for its own architecture.
Which op-plugins wheel should I use with 64-bit Python?
Use the win_amd64 build for 64-bit Python and the win32 build for 32-bit Python. The wheel already includes the matching OP runtime files, so no manual DLL copy is needed.
Does OP include an OCR engine or a YOLO detector?
No. Fixed font OCR uses dot matrix font libraries loaded from a file or from memory, while general OCR and YOLO detection are performed by separate HTTP services, with a minimal YOLO service example in tools/op_yolo_engine.py.
What does it take to build OP from source?
You need Windows 10 or newer, Visual Studio 2022 or newer, CMake 3.24 or newer and Python 3.12, then run build.py with the generator, configuration and architecture flags. Release output is installed into bin/x86 or bin/x64.
Can OP be used without registering the COM component?
Yes, the project documents a registration free way to load the plugin, with a loader in the tools directory and a Python registration free example in the wiki. The step by step instructions live in the wiki rather than in the repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wallbreaker2-op)Was this useful?