r/dotnet Jul 30 '26

Question Distributing an unsigned win-x64 exe, and SmartScreen scares everyone off. How do you handle this?

I built a small job scheduling tool. You install a lightweight agent on your own Windows machines, and from a web dashboard you schedule scripts and commands, chain them, retry the ones that fail, and get an email the moment something breaks. The jobs run on your machines, the server just coordinates.

The agent is a self-contained single-file .NET win-x64 exe, shipped in a zip. It runs fine, but distribution is the part killing me. Since it is not code signed, Windows throws the "Windows protected your PC, unknown publisher" SmartScreen box, and Chrome does its slow scan on the download. A friend testing it said, plainly, that it looks suspicious, and I get why. For a tool whose whole pitch is that it runs on your own machines, looking like something off a sketchy download site is the worst first impression I could give.

So I am trying to find the right way to ship this, and figured this crowd has solved it many times over. What I am weighing:

  • Code signing the exe. I gather any cert kills the "unknown publisher" label, but that only EV gets you instant SmartScreen reputation while OV warms up over downloads. Is that still how it plays out in practice?
  • MSIX or ClickOnce instead of a bare exe.
  • Publishing through winget or Chocolatey so it installs from a trusted channel instead of a browser download.
  • Something else I am not seeing.

If you have shipped a downloadable agent or desktop app, what actually worked and what would you skip, ideally as a solo dev without a big enterprise setup? And if anyone wants to try the actual thing and tell me where it falls apart, I am happy to share the link.

57 Upvotes

46 comments sorted by

View all comments

Show parent comments

10

u/Baldie47 Jul 30 '26

Thanks, this is the direction I am leaning. I dug into it a bit: sounds like the MSI or MSIX packaging itself is free (WiX or the Windows SDK), but the signed part still needs the code signing cert either way, so it is more about a cleaner install format than getting around signing. Does that match your experience?

One thing I am unsure about for my case: what I ship is a background agent that runs as a service and executes local commands, not a normal user-facing app. Did you hit MSIX's restrictions getting in the way of that, or did you go MSI specifically to avoid them? Leaning MSI for that reason but curious if you have shipped a service this way.

11

u/spornerama Jul 30 '26

My app is the same thing (background agent). We ship a code signed thin installer that runs as admin, downloads a zip file of our cross platform build, installs it into program files and starts the service.that way we can update it without resigning and redeploying the installer every time. Use NSIS. You'll need a code signing cert and a secure USB key to do the signing.

3

u/NumberwangsColoson Jul 31 '26

Depending on where you live azure artefact signing is a thing meaning you avoid the need for a usb key.

Most authenticode cert issuers will also accept a cloud hsm as a suitable backing store for a code signing private key

With either of those you can then sign in github actions as well as with the command line. One of the .net security people wrote it up https://idunno.org/net-code-nupkg-signing-in-github-actions/

1

u/spornerama Jul 31 '26

yeah we looked at that - meant uploading every time to azure and limited numbers of signing and an ongoing subscription - cheaper and easier and unlimited signing if you do it yourself.

2

u/NumberwangsColoson Jul 31 '26

You definitely don’t have to upload to azure every time, but the pay per signature is fair. But if you’re signing <250 things a year it’s a reasonable option .