{"id":48521642,"url":"https://github.com/dady8889/onova.publisher","last_synced_at":"2026-04-07T21:02:50.387Z","repository":{"id":62916235,"uuid":"387056283","full_name":"dady8889/Onova.Publisher","owner":"dady8889","description":"Provides publishing support for applications using Onova.","archived":false,"fork":false,"pushed_at":"2024-07-21T22:28:49.000Z","size":240,"stargazers_count":23,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-09T13:32:07.318Z","etag":null,"topics":["cpp","csharp","installer","onova","publish","publisher","squirrel","update","updater","webinstaller"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dady8889.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-17T23:48:18.000Z","updated_at":"2025-05-08T05:25:09.000Z","dependencies_parsed_at":"2022-11-09T04:01:03.301Z","dependency_job_id":null,"html_url":"https://github.com/dady8889/Onova.Publisher","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/dady8889/Onova.Publisher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dady8889%2FOnova.Publisher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dady8889%2FOnova.Publisher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dady8889%2FOnova.Publisher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dady8889%2FOnova.Publisher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dady8889","download_url":"https://codeload.github.com/dady8889/Onova.Publisher/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dady8889%2FOnova.Publisher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31528752,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","csharp","installer","onova","publish","publisher","squirrel","update","updater","webinstaller"],"created_at":"2026-04-07T21:02:26.933Z","updated_at":"2026-04-07T21:02:50.376Z","avatar_url":"https://github.com/dady8889.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Onova.Publisher - Like Squirrel but Simpler™\n[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine)\n[![Version](https://img.shields.io/nuget/v/Onova.Publisher.svg)](https://nuget.org/packages/Onova.Publisher)\n\n\nIt has been years since Squirrel.Windows had been deprecated, without a modern replacement.\nThis project aims to provide the basic functionality of Squirrel.Windows.\nWe build upon the [Onova update library](https://github.com/Tyrrrz/Onova), which provides seamless update process for your application.\nOne of Onova's upsides is the unawareness of how the application has been installed.\nHowever, to make the process of installing and updating as intuitive as possible, it is useful to make them depend on each other.\n\n## Introduction\n\n**Onova.Publisher is a tool that allows you to create new packages directly from Visual Studio Package Manager Console.**  \nThe package will be targeted for usage by [WebPackageResolver](https://github.com/Tyrrrz/Onova#webpackageresolver).  \nPublisher also takes care of creating the manifest file, which is consumed by the updater.  \n\nThe most important part is the installer - in comparison to Squirrel, which packed the latest version of your application into the installer itself, Onova.Publisher packs only the information necessary to download the latest version from your deployment server.   This type of installer is also known as a web installer. The major upsides are that the installer is small and you don't need to update it with your app.  \n\n**Like Squirrel, Onova.Publisher builds an installer which will install your application to the local appdata folder, without needing admin privileges.**  \n\n## Usage\nThe only **requirement** for Onova.Publisher to work is that your project **targets .NET 5+**.\n\nLet us assume you have built and dotnet published your app into the *\\publish* folder of your solution.\nSelect your startup project as the default project in the Package Manager Console.\n\n```\nPM\u003e Onova.Publisher -h\nOnova.Publisher\n  Publishes your application for Onova.\n\nUsage:\n  Onova.Publisher [options]\n\nOptions:\n  -n, --name \u003cname\u003e             Your application's name (name of executable without extension). Maximum 31 characters.\n  -v, --version \u003cversion\u003e       Version in format major.minor[.build[.revision]].\n  -u, --url \u003curl\u003e               URL to web where the manifest resides. Maximum 1023 characters.\n  -i, --in, --target \u003ctarget\u003e   Folder which will get packed into a zip.\n  -o, --out, --output \u003coutput\u003e  Folder which will contain the updated manifest file, zip and installer. [default: .\\OnovaPublish]\n  --no-releasenotes, --no-rn    Disables generation of an empty release note (.rn) file.\n  -s, --sign \u003csign\u003e             Sign AppName.exe/.dll files and the installer. This field accepts SignTool parameters.\n  -?, -h, --help                Show help and usage information\n```\n\nAfter reading the tool's help, let's try publishing our DummyApp version 1.2.3 to our web server at https://dummy.com/files/.\n\n```\nPM\u003e Onova.Publisher --name DummyApp --version 1.2.3 --url https://dummy.com/files/ --target publish\\\n```\n\nThis should produce the following output:\n```\nSuccessfully published DummyApp version 1.2.3 into DummyApp-1.2.3.zip.\n```\nIf we check our solution folder, we can see a new folder called *OnovaPublish*.\nThe contents of the folder are following:\n```\n    MANIFEST\n    DummyApp-1.2.3.zip\n    DummyApp-1.2.3.rn\n    websetup.exe\n```\nThe MANIFEST file will contain one line, *1.2.3 DummyApp-1.2.3.zip*. This file is precisely formatted for [WebPackageResolver](https://github.com/Tyrrrz/Onova#webpackageresolver).\n\nThe .rn file is an empty text file, in which you can add release notes for your release. For more information, check out [Onova.ReleaseNotes](https://github.com/dady8889/Onova.ReleaseNotes).\n\nYou can now upload the files to the desired location.  \n\nContinuing, we will assume you have implemented the updating in your application as:\n```csharp\nusing (var mgr = new UpdateManager(new WebPackageResolver(\"https://dummy.com/files/MANIFEST\"), new ZipPackageExtractor()))\n{\n  var result = await mgr.CheckForUpdatesAsync();\n  ...\n}\n```\n\nYou can try creating another version, by running a similar command:\n```\nPM\u003e Onova.Publisher --name DummyApp --version 1.3.0 --url https://dummy.com/files/ --target publish\\\n```\nNow, you should just need to upload the new zip file and update the latest MANIFEST entry. *(unless a new version of the publisher had come out in the meantime, in which case an update for the installer may be required)*\n\nAfter uploading the files, let's try downloading and running the *webinstaller.exe* of our application.\nThe installer is written in C++ and statically linked for x86, compiled with MSVC, which means it should run on any reasonable Windows installation.\nRunning the installer will greet us with a console window with the following contents:\n```\nWelcome to DummyApp web install\nDownloading the latest version...\nInstalling version 1.3.0...\nThe app was sucessfully installed.\nPress any key to continue . . .\n```\n\nThe installer did the following:\n* Checked the manifest in the URL specified during publishing\n* Parsed the manifest and selected the latest entry\n* Downloaded the latest zip to temp directory\n* Unpacked the zip to %localappdata%\\DummyApp\\oapp\\\n* Created link to the start menu\n* Registered the app in the Windows Registry\n* Copied an uninstaller to %localappdata%\\DummyApp\\uninstall.exe\n\nOf course, if anything during the process went wrong, the installer would output an error message in the console.\nCurrently, the installed app **will not** be started after the installation.\n\nIf you want to uninstall the application, you can use the standard Windows uninstall procedure using Settings, or you can directly execute the uninstall.exe in the application base directory. *Also, in comparison with Squirrel, your application will have an icon visible in the installed programs menu, and the uninstaller leaves no installed files behind.*\n\n## Code signing\n\nIf you don't want to sign your app by yourself, you can use Onova.Publisher with the --sign option.\nThis option requires parameters that get passed to the bundled SignTool.\nOnova.Publisher will sign **only** valid executable files (exe, dll) with your application's name, and the generated installer. Example:\n```\nPM\u003e Onova.Publisher --name DummyApp --version 1.3.0 --url https://dummy.com/files/ --target publish\\ --sign \"/f cert.pfx /p passwd123 /tr http://timestamp.digicert.com\"\n```\n\n## Missing (planned) features\n- [x] Changelog support\n- [x] SignTool support\n- [ ] Start menu link in publisher name folder\n- [ ] Run app after installation\n- [ ] Silent install\n\n## Missing (not planned) features\n* Bigger customization eg. icons, custom UI\n* Dedicated non-web installer\n* Other OS support or backporting to older .NET versions\n* Bootstrapping\n\n## Known issues\n- [ ] No wiki\n- [ ] No tests\n- [x] App name allows only ANSI encoding\n- [x] MANIFEST rebuilding sorts alphabetically, not semantically\n\n## Contributions\nI am open to suggestions, PRs, bug reports.\nAny contribution is welcome.\n\n## Licensing\nThe project uses following licensed works:\n\n* zip_file.hpp - [miniz_cpp](https://github.com/tfussell/miniz-cpp)\n* WinReg.hpp - Giovanni Dicanio, [WinReg](https://github.com/GiovanniDicanio/WinReg)\n* [cpr](https://github.com/libcpr/cpr)\n\nMy provided code is licensed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdady8889%2Fonova.publisher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdady8889%2Fonova.publisher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdady8889%2Fonova.publisher/lists"}