Building & Packaging
Release artifacts
Every release ships four zip packages:
release_<version>_<Variant>_win-<arch>.zip
2.9.0 Dokan|WinFsp x64|arm64
| Package | Contents |
|---|---|
…_Dokan_win-x64.zip | SimpleZipDrive.exe, 7z.dll, 7z_arm64.dll, ReadMe.md, LICENSE.txt, WhatsNew.md |
…_Dokan_win-arm64.zip | same layout |
…_WinFsp_win-x64.zip | SimpleZipDrive_WinFsp.exe, winfsp-msil.dll, 7z.dll, 7z_arm64.dll, docs |
…_WinFsp_win-arm64.zip | same layout |
All are framework-dependent single-file executables (~4–5 MB): the .NET Desktop Runtime and the filesystem driver are the only prerequisites.
Publish commands
Important: the
.csprojfiles contain<SelfContained>true</SelfContained>, but releases are built framework-dependent — the publish command must override it with--self-contained false. Publishing without the override produces huge self-contained bundles that also break the packaging assumptions documented below.
# Dokan variant
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r win-x64 --self-contained false -o out\Dokan_x64
dotnet publish SimpleZipDrive\SimpleZipDrive.csproj -c Release -r win-arm64 --self-contained false -o out\Dokan_arm64
# WinFsp variant
dotnet publish SimpleZipDrive_WinFsp\SimpleZipDrive_WinFsp.csproj -c Release -r win-x64 --self-contained false -o out\WinFsp_x64
dotnet publish SimpleZipDrive_WinFsp\SimpleZipDrive_WinFsp.csproj -c Release -r win-arm64 --self-contained false -o out\WinFsp_arm64
Then zip each output folder together with ReadMe.md, LICENSE.txt, WhatsNew.md using the naming convention above.
Packaging internals
Three constraints make the file layout non-negotiable:
-
winfsp-msil.dllmust stay a real file beside the exe (WinFsp variant). Its static initializer (Fsp.Interop.Api.CheckVersion) callsFileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);Assembly.Locationis an empty string inside a single-file bundle, soPath.GetFullPath("")throws and every mount dies with “The path is empty (Parameter ‘path’)” before the driver is ever contacted. The csproj contains a target that runs before the bundler computes its file list:<Target Name="KeepWinFspInteropOutOfBundle" BeforeTargets="_ComputeFilesToBundle"> <ItemGroup> <ResolvedFileToPublish Update="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.Filename)%(ResolvedFileToPublish.Extension)' == 'winfsp-msil.dll'" ExcludeFromSingleFile="true" /> </ItemGroup> </Target>Timing matters:
AfterTargets="ComputeFilesToPublish"/BeforeTargets="BundleFiles"do not work — the SDK splits bundled/non-bundled files in_ComputeFilesToBundle. -
7z.dll/7z_arm64.dllmust stay real files beside the exe (both variants).SevenZipFallbackprobesAppContext.BaseDirectoryfor the library matching the process architecture (SharpSevenZipBase.SetLibraryPath); bundling them into the exe makes the fallback silently unavailable. Both ship in every package so one zip works on x64 and ARM64. -
winfsp.net stays at 2.1.x (
2.1.25156). Interop 2.2.x rejects the stable native 2.1 driver (“incorrect dll version (need 2.2, have 2.1)”); interop 2.1 accepts both the 2.1 stable driver and 2.2+ betas. Version gates live inMountService(RequiredWinFspVersion = 2.1).
Release process checklist
- Bump
<Version>/<AssemblyVersion>/<FileVersion>to the new version in all five.csprojfiles. - Update
WhatsNew.md(user-facing Fixed/Changed/Internal sections). dotnet test SimpleZipDrive.Tests -c Release— green.- Publish the four artifacts (commands above).
- Smoke-test each variant: mount a stored ZIP and a compressed archive through the packaged exe (both a drive letter and a folder; elevated and non-elevated for WinFsp).
- Create the four zips with the exact naming convention.
- Tag
release_<version>and push the tag. gh release create release_<version> --title "<version>" --notes-file … *.zip(GitHub CLI, full release — not draft/prerelease).- Inform issue reporters whose bugs the release fixes.
There is no CI/CD — releases are produced locally with the exact commands above.