Search code examples
squirrel.windows

Why does Setup.exe run my application, crash, then run it again (successfully)?


EDIT: Apologies I put this in "Squirrel.Windows" when this is more of a Clowd.Squirrel question. I don't have enough rep to make the Clowd.Squirrel tag.

I previously used Squirrel.Windows to "realisify" my app (which was first turned into a NuGet package). I have since upgraded the project to .Net 6, and so I've turned to Clowd.Squirrel.

I still package my app the same way. I then use squirrel.exe releasify -p C:\project\project.nupkg -r c:\project\Releases\ -i C:\project\my_icon.ico --msi=x64. It successfully produces a ProjectSetup.exe and ProjectSetup_DeploymentTool.msi. The msi file works as expected, but the setup file... does not.

When running ProjectSetup.exe, it first copies files over to %localappdata%\project (including app-1.0.0, packages\, Project.exe, and Update.exe). Then it opens my app. After about 10 seconds, it crashes. It then re-opens my app, and it works normally from there. Why? I can't find any windows event logs to explain it, which makes me think it isn't actually a crash, but rather an end that I wasn't expected (but Squirrel is).

Additionally, ProjectSetup.exe also does not set up my app in the Start Menu. When I used Squirrel.Windows, it would create a directory C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Project which contained a shortcut to Project.exe (or perhaps it wasn't a shortcut; I can't totally recall). Am I missing some flag/switch or config option?

I'd be happy to provide more information if requested.


Solution

  • A couple hours of toiling later, and I found my problem. Please still correct me if I'm wrong, but here are my findings.

    And before we get started, I need to reiterate: This is a problem I had with Clowd.Squirrel. I again apologize that I have this on the Squirrel.Windows tag, but the Clowd.Squirrel tag does not exist at the time of writing, and I don't have enough rep to open it.

    Now, let me explain what I learned.

    What is "Squirrel Aware"?

    For your app to be "Squirrel Aware", it needs to make use of the hooks Squirrel provides. These are the OnInstall, OnEveryRun, etc. (actual naming might be slightly different). Now, I slightly fib: You can say your app is squirrel aware without actually using these hooks. This was my problem.

    Squirrel Aware on Squirrel.Windows

    When using Squirrel.Windows, it does not care if you are squirrel aware. And if you aren't, it doesn't complain. For my project, I am only using the UpdateManager class, so I don't need squirrel aware-ness.

    Squirrel Aware on Clowd.Squirrel

    When changing over to Clowd.Squirrel, it suddenly complained to me that we weren't being squirrel aware! So, I created the app.manifest file, and I included the requisite <SquirrelAwareVersion xmlns="urn:schema-squirrel-com:asm.v1">1</SquirrelAwareVersion>. Now Squirrel doesn't complain. But, when I run ProjectSetup.exe (or run the deployment tool), it opens, waits about 10 seconds, then closes. Looking back over the Clowd.Squirrel quick start guide, I realized it might make sense to actually follow it. So I added the hooks as it describes. Now, it doesn't open-close-open. Instead, it installs shortcuts in the correct places (desktop and start menu) and opens up afterwards. All is hunky-dory.

    You may then ask: "What if I don't have any plans for those hooks?" Well, if you replace the hook functions with a simple (a, b) => { } (or (a, b, c) => { } for onEveryRun), I found that my app would open, close, then reopen as before. But! Now the first open is very short: just enough time to open a white window, then it immediately closes.

    Now wait a second, why can't I just have what I had with Squirrel.Windows -- without all the awareness and whatnot?

    Good news! You don't need squirrel awareness (still)!

    Actual Solution

    • Remove the app.manifest file (which made my app squirrel aware)
      • Strictly speaking, you probably need to remove only the <SquirrelAwareVerson> tag in app.manifest.
    • When running squirrel, simply add the --allowUnaware flag.
      • This flag was hinted at when I attempted to use squirrel on my app without my app being squirrel aware. But since I had already made it squirrel aware, the warning was nowhere to be found, and I had to find this flag by digging through the source code myself :( (kinda fun tho)

    So I end up with:

    squirrel.exe releasify -p C:\project\project.nupkg -r c:\project\Releases\ -i C:\project\my_icon.ico --allowUnaware --msi=x64