How to Use IronPrint with Cursor

Curtis Chau
Curtis Chau
Updated: October 19, 2026

When an AI agent ports a C# printing service from System.Drawing.Printing to IronPrint, a setting copied across unchanged still compiles and changes its meaning. A margin of 50 in the old code means half an inch, while the same 50 in IronPrint means 50 millimeters. The printer names come across unchanged too. In our tests, IronPrint sent a job for a printer name that was not installed to the default printer without raising an error.

Cursor, which is based on the VS Code codebase, adds an agent to the editor. Whether a migration keeps these details depends on two Cursor features, the documentation links given to the agent and the committed project rules in .cursor/rules. The examples apply both to a despatch office service that prints packing slips, shelf labels and returns notes. The service builds each job from a configuration file in hundredths of an inch, and the prompts move it to IronPrint.

For details on the settings involved, see the paper margins guide and the printer names guide.

Quickstart
NuGetInstall with NuGet

PM > Install-Package IronPrint

Install IronPrint by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.

Open the despatch repository, start a new Agent chat and send this prompt.

@src/DespatchDesk/ @config/despatch.json

Start by fetching https://ironsoftware.com/print/csharp/llms.txt.
Also read the pages it links on printer names and print settings.

Then add a printers command to Program.cs:
`dotnet run --project src/DespatchDesk -- printers`

Have it show what IronPrint reports on this machine:
- Every name from Printer.GetPrinterNames, in square brackets so spaces show.
- The trays GetPrinterTrays returns for each printer, or "none".
- Whether each printer named in config/despatch.json is in that list.

Have the program read IRONPRINT_LICENSE_KEY from the environment.
Set License.LicenseKey from it before anything else runs.
Don't echo the key or dump the environment.
IronPrint stays on version 2026.10.1.
Send no print jobs, and leave DespatchJobs.cs on System.Drawing.Printing for now.

Run the printers command and show me what it prints.
Text

Never paste the license key into the chat. Cursor's agent can edit files and run shell commands, so it can copy a pasted key into a commit message, a source file or a build log. The prompt has the program assign IRONPRINT_LICENSE_KEY to License.LicenseKey because setting the variable alone left IronPrint 2026.10.1 unlicensed in testing. In a probe without a key, IronPrint listed printers and trays, and Printer.Print threw an AggregateException around a LicensingException before any job was sent. The license key guide names the places IronPrint does read a key from, such as appsettings.json.



Which Cursor model should you use for IronPrint work?

Composer is Cursor's own agentic model. The model picker also offers SpaceXAI's Grok models, which Cursor co-developed, and models from OpenAI, Anthropic, Google and other labs. The test run below used Grok 4.7.

How do you give Cursor the IronPrint documentation?

Put IronPrint's documentation link in each request, or once in a project rule for the whole team. IronPrint's llms.txt lists each guide, example and troubleshooting page with a summary, and llms-full.txt holds abstracts of 33 documentation pages. As of October 2026, Cursor lists folders, files, past chats, the browser, terminals and Git diffs in its @ menu, so the agent gets IronPrint's documentation as a link.

The documentation states that a null printer name selects the default printer, and IronPrint's guide on specifying a printer name says that a mismatched name fails silently or throws an error. Neither outcome occurred in testing, so the project rule records the measured behavior instead.

@src/DespatchDesk/Printing/ReprintService.cs

Answer five questions about IronPrint without editing any files:
1. What unit does the Margins class use?
2. Which sides does each value of new Margins(10, 20) set?
3. What does Printer.Print do when PrintSettings.PrinterName is null?
4. What do the docs say about a name GetPrinterNames doesn't return, and does the rule agree?
5. Does NumberOfCopies always produce that many copies?

Base each answer on https://ironsoftware.com/print/csharp/llms.txt or a page linked from it.
Check them against the printers output from the last turn where that helps.
Cite the page behind each answer.
If no page covers a question, say so plainly rather than guess.
Text

How do you write project rules that encode your IronPrint conventions?

Project rules are .mdc files kept in .cursor/rules and committed to the repository, so every clone loads the same rules. Cursor's rules system ignores a plain .md file there, since it carries no frontmatter.

Save the rule below as .cursor/rules/ironprint-despatch.mdc. With globs set and alwaysApply false, Cursor attaches it when a C# file under src/DespatchDesk or tests is in the request's context, and leaves it out of other requests.

---
description: IronPrint conventions for the despatch printing code
globs: src/DespatchDesk/**/*.cs, tests/**/*.cs
alwaysApply: false
---

Despatch printing code uses IronPrint and follows these rules:
- Print with IronPrint only.
- Reference IronPrint 2026.10.1 from NuGet and use its IronPrint namespace.
- Do not add another printing package.
- Move existing code to IronPrint only when a request asks for it.
- The IronPrint docs index is https://ironsoftware.com/print/csharp/llms.txt.
- Read the license key from the IRONPRINT_LICENSE_KEY variable.
- Keep the license key out of output and files.
- IronPrint Margins uses whole millimeters, as left, top, right, bottom.
- System.Drawing.Printing.Margins uses hundredths of an inch, as left, right, top, bottom.
- new Margins(a, b) sets left and right to a, and top and bottom to b.
- Printer.Print sends the job to the default printer if PrinterName is not an exact installed name.
- Check the name against Printer.GetPrinterNames before every job.
- Run the print and reprint commands only when I ask for them.
- Check settings with the jobs and reprint-jobs reports instead.
- If an IronPrint member is not in the docs, say that and cite the page you searched.
- Never make up an IronPrint member.
Markdown
Please note: Cursor reads AGENTS.md files too, in the project root and in subdirectories. AGENTS.md is plain markdown without frontmatter, so it cannot hold the globs this rule depends on.

According to Cursor's rules page, Agent uses rules but Tab does not, and user rules are left out of inline edit. Check suggestions from Tab and inline edit against the rule by hand.

How do you map System.Drawing.Printing settings to IronPrint?

A request to use IronPrint does not say which IronPrint setting replaces each PrintDocument setting. The table below gives that mapping.

System.Drawing.PrintingIronPrint
PrinterSettings.PrinterNamePrintSettings.PrinterName
PageSettings.PaperSize, sized in hundredths of an inchThe PaperSize enum, such as PaperSize.A4
PageSettings.LandscapePaperOrientation.Landscape or PaperOrientation.Portrait
PageSettings.Margins, hundredths of an inch, left, right, top, bottomPaperMargins with a Margins value, whole millimeters, left, top, right, bottom
PrinterSettings.CopiesNumberOfCopies
PageSettings.Color set to falseGrayscale set to true
PrintDocument.Print with a PrintPage handlerPrinter.Print with a file path and the settings

A configured margin of 50 is 12.7 millimeters, which rounds to 13 because the constructor takes whole numbers. IronPrint's paper size guide lists the four-value order as top, right, bottom, left, while the shipped XML documentation and a probe of the library both give left, top, right, bottom.

How do you plan and run a migration to IronPrint?

Shift+Tab cycles the chat's modes. Stop at Plan Mode and send the request below. Cursor saves the plan to a markdown file, which can be edited before approval.

@src/DespatchDesk/Printing/ @TestData/expected-jobs.tsv

Plan the move of DespatchJobs from System.Drawing.Printing to IronPrint.
Write no code until I approve.
ReprintService already uses IronPrint, so keep it out of this plan.

The plan needs to cover these points:
- Each PrintDocument setting DespatchJobs uses, with its PrintSettings replacement or none.
- How margins in hundredths of an inch become IronPrint margins, including the order of the sides.
- How the jobs command keeps its columns and its values.

Keep config/despatch.json, JobSummary and the public Describe and Print signatures unchanged.
Where something is unclear, write down the assumption you made.
Text

Edit the plan where it is wrong. To approve it, click Build, or return to Agent mode and send this request.

@ironprint-despatch

Go ahead with the approved plan.
TestData/expected-jobs.tsv holds the jobs report the despatch office signed off.
A row matches when all eight columns agree with it.

Then follow these four steps:
1. Run `dotnet run --project src/DespatchDesk -- jobs` and count the matching rows.
2. Move DespatchJobs to IronPrint.
3. Remove System.Drawing.Common from the project file.
4. Build the solution and run the jobs command a second time.

Tell me the match count before and after the move, then show me the diff.
Text

The @ironprint-despatch mention adds the rule to the request by name. The jobs report prints each document's settings without sending a job, so the comparison works on a machine with no printer attached.

Which Cursor feature fits each change?

Pick the feature by the size of the change. Tab offers the rest of an edit already in progress. Inline edit (Ctrl+K) changes selected code from a one-sentence instruction. Agent suits a change that spans several files or needs a build. Plan Mode is worth the extra step when undoing a wrong change takes longer than writing a plan, and a Cloud Agent handles unattended work.

Select the Print method of DespatchJobs and add it to the chat as context with Ctrl+Shift+L, or Cmd+Shift+L on macOS. Then send this request from Agent mode.

Make DespatchJobs.Print refuse a printer that isn't installed:
- Check the name against Printer.GetPrinterNames before anything is sent.
- Use an ordinal, case-sensitive comparison so spaces and case must match too.
- If it's missing, throw an error whose message includes every installed printer name.
- Have the print command show that message and exit with code 2.

Then run these two commands and show me what each one prints:
`dotnet run --project src/DespatchDesk -- print packing-slip`
`dotnet run --project src/DespatchDesk -- print packing-slip --printer "adobe pdf"`
Text

The second command differs from an installed printer name only in case.

What happens when IronPrint cannot find the printer name?

The old service stopped with an error. System.Drawing.Printing threw an InvalidPrinterException with the message "Settings to access printer 'Despatch-A4-01' are not valid." IronPrint 2026.10.1 addressed the captured job for that name, and for three other names, to the default printer. These were the sample printer name from IronPrint's margins guide, an installed printer typed in lower case, and the same printer with a trailing space.

Microsoft Print to PDF, which was the test machine's default printer, asks for a file name, so an unattended service would have stopped at a Save As dialog. The printer names guide states that each returned name matches the name in the Windows printer settings exactly, which makes an ordinal comparison with Printer.GetPrinterNames the check to run before every job.

How do you debug two print paths that disagree?

The reprint kiosk code already used IronPrint, and its settings report disagrees with the signed-off report on every row.

@src/DespatchDesk/Printing/ReprintService.cs @TestData/expected-jobs.tsv

Find out why the reprint report disagrees with expected-jobs.tsv on every row.
The jobs report matches it, and both read config/despatch.json.

Work through these steps before changing any code:
1. Run the reprint-jobs command and the jobs command, and compare them.
2. List each column where reprint-jobs differs, per document type.
3. Explain what ReprintService does to cause each difference.

Then fix ReprintService and keep it on IronPrint.
Give its Print method the same printer check.
Keep the check out of BuildSettings and Describe, since reprint-jobs reads those.
Run reprint-jobs again and tell me how many rows match, before and after the fix.
Text

The disagreement has two causes. The kiosk code passes the hundredths directly to the two-value constructor, so a packing slip reports margins of 50 millimeters, and the returns note repeats its top value at the bottom, where the configuration sets 80 hundredths. It also sets landscape orientation for every document because it was written for shelf labels.

Output

In a capture from the run before the fix, the portrait packing slip sent with landscape orientation was laid out on a 297 by 210 millimeter sheet. Its page was scaled to 148.4 by 209.9 millimeters, and the other 148.5 millimeters of the sheet stayed blank.

Packing slip with the settings of the unfixed ReprintService, as IronPrint built the job, captured to a file in place of a printer.

What does IronPrint send to the printer?

None of the four printers on the test machine completes a job unattended, so nothing was printed on paper. For these measurements, the margins guide's samples and the migrated service ran unchanged, and only the final call into Windows printing was replaced. At that call, a patch saved each job's pages and print ticket as an XPS file, and the print queue received nothing. The measurements below come from those files and describe what a printer would receive.

  • Margins: margins of 0, 10, 15, 20, 30 and 50 millimeters produced identical pages, with the page image filling the sheet. The System.Drawing.Printing version of the packing slip drew its image inside 12.7 millimeter margins.
  • Grayscale: for a PNG page, the setting changed only the print ticket and the image stayed in color. For a PDF page, the image itself was gray.
  • Resolution: a PDF was rendered at the Dpi setting, 2479 by 3508 pixels for A4 at 300. A PNG was sent at its own pixel size.

Until IronPrint applies PaperMargins to the page on Windows, a layout that needs white space at the edges must carry it in the document itself.

Input

The service prints three PNG files from TestData/jobs, slip-1001.png, labels-aisle-07.png and return-2207.png. Each one is a 150 DPI image with a red border at its edges.

Packing slip 1001 input image, A4 portrait with a red border Shelf labels for aisle 07 input image, A4 landscape with a red border Returns note 2207 input image, A5 portrait with a red border

Output

The PDFs below show one job each from the code Cursor wrote. Each page image is unaltered and keeps the size of the captured page.

Packing slip as IronPrint built the job, captured to a file in place of a printer. The job holds one A4 portrait page, and its print ticket requests two copies in monochrome.

Shelf labels as IronPrint built the job, captured to a file in place of a printer. This A4 landscape page measures 297 by 210 millimeters, and the print ticket specifies color output.

Returns note as IronPrint built the job, captured to a file in place of a printer. Its single A5 portrait page measures 148 by 210 millimeters, and monochrome output is set in the print ticket.

How do you write regression tests for printing code?

Cursor's Cloud Agents run on Ubuntu machines, and the sample targets net9.0-windows, so send this request in a local Agent chat.

@tests/DespatchDesk.Tests/ @TestData/

Write xUnit tests for DespatchJobs and ReprintService. None of them may send a print job.

Cover these cases with tests:
- Describe returns every row of TestData/expected-jobs.tsv, for both classes.
- The returns note reports a 20 mm bottom margin.
- Print throws when the printer is missing from GetPrinterNames.
- That error message names each printer GetPrinterNames returns when the test runs.
- An installed printer name with its case changed is refused as well.
- Hundredths of an inch convert to the millimeters in expected-jobs.tsv.

Link config and TestData from the repo root into the test output, keeping their relative paths.
Leave expected-jobs.tsv as it is, then run dotnet test.
Tell me how many tests passed and how many failed.
Text

The refusal tests use printer names that are not installed, so they stop at the printer check before Printer.Print is called.

The AI coding assistants guide takes one IronPrint task from an empty folder to a result checked against written pass criteria.

What did the prompts produce in a real run?

Cursor received the seven prompts in order against the despatch sample repository. After the run, fresh Release builds of every commit that changed code repeated each report and command below.

  • Before the move to IronPrint and after it, the jobs report matched all 3 rows of the signed-off report.
  • The reprint report matched 0 of 3 rows before the fix and 3 of 3 after it.
  • The printers command listed the four installed printers with their trays and marked both configured printers as not installed.
  • Each of Cursor's five documentation answers cited a page, and no file changed.
  • For a name that GetPrinterNames does not return, Cursor repeated the guide's statement and noted that the project rule describes a different outcome.
  • The plan found no PrintSettings replacement for the document name and recorded that as an assumption.
  • After the move, the app referenced only the IronPrint package, and no System.Drawing.Printing code remained.
  • DespatchJobs kept its public Describe and Print signatures.
  • The print command refused the configured printer for all three document types with exit code 2 and a list of the four installed printers.
  • The printer check also refused the installed Adobe PDF printer typed in lower case or with a trailing space.
  • Before its fix, the reprint command sent jobs for a missing configured printer and for "adobe pdf" to the default printer.
  • After the fix, the reprint command refused both names. It stopped with an unhandled exception, as prompt 06 asked for no exit code.
  • All 9 xUnit tests passed. They came from five test methods, and none sent a job.
  • The run left the configuration, the test data and the project rule unchanged.
  • Each Release build finished with 0 warnings and 0 errors, and no file was edited by hand.
  • Some steps ran differently from the page. Every prompt was sent by hand in one local desktop chat. Prompt 04 was first pasted without being sent, and was sent after the run's logging script reported it missing from the chat. The plan was approved by sending prompt 04 in Agent, and Build was never clicked. Cursor's migration already checked the printer name, as its plan proposed, so prompt 05 changed an existing check.

The GitHub Copilot guide also keeps path-specific instruction files in the repository, and the Google Antigravity guide tests the print page in a real browser. The run record lists the tool version, model, duration and test machine for each guide.


Troubleshooting


Questions?

If you have any questions, reach out to support@ironsoftware.com

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

Read More

Ready to Get Started?

Nuget Downloads 48,068Version:2026.10just released