electron / forge

:electron: A complete tool for building and publishing Electron applications
https://electronforge.io
MIT License
6.42k stars 507 forks source link

Unable to makes squirrel distributable for win32/arm64 on macos #3142

Open ahmadbenos opened 1 year ago

ahmadbenos commented 1 year ago

Pre-flight checklist

Electron Forge version

6.0.4

Electron version

22.0.1

Operating system

macOS 13.1 (M1)

Last known working Electron Forge version

No response

Expected behavior

a successful squirrel out folder

Actual behavior

here is what is happening when i run: electron-forge make --platform win32

✔ Checking your system
✔ Loading configuration
✔ Loading configuration
✔ Resolving make targets
  › Making for the following targets: squirrel
✔ Running package command
  ✔ Preparing to package application
  ✔ Running packaging hooks
    ✔ Running generateAssets hook
    ✔ Running prePackage hook
      ✔ [plugin-webpack] Preparing native dependencies: 2 / 2
      ✔ [plugin-webpack] Building webpack bundles
  ✔ Packaging application
    ✔ Packaging for arm64 on win32 [2m15s]
  ✔ Running postPackage hook
✔ Running preMake hook
❯ Making distributables
  ✖ Making a squirrel distributable for win32/arm64
    › Failed with exit code: 255
      Output:
      System.AggregateException: One or more errors occurred. () ---> System.…
      at Squirrel.Utility.CreateZipFromDirectory (System.String zipFilePath, …
      --- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <b27839cc2dba4804baacf2f5cce6de32>:0 
  at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in <b27839cc2dba4804baacf2f5cce6de32>:0 
  at System.Threading.Tasks.Task.Wait () [0x00000] in <b27839cc2dba4804baacf2f5cce6de32>:0 
  at Squirrel.ReleasePackage.CreateReleasePackage (System.String outputFile, System.String packagesRootDir, System.Func`2[T,TResult] releaseNotesProcessor, System.Action`1[T] contentsPostProcessHook) [0x001f7] in <1ffb1a5dca5b4f2f93386cec56fd9ec2>:0 
  at Squirrel.Update.Program.Releasify (System.String package, System.String targetDir, System.String packagesDir, System.String bootstrapperExe, System.String backgroundGif, System.String signingOpts, System.String baseUrl, System.String setupIcon, System.Boolean generateMsi, System.Boolean packageAs64Bit, System.String frameworkVersion, System.Boolean generateDeltas) [0x00214] in <1ffb1a5dca5b4f2f93386cec56fd9ec2>:0 
  at Squirrel.Update.Program.executeCommandLine (System.String[] args) [0x00116] in <1ffb1a5dca5b4f2f93386cec56fd9ec2>:0 
  at Squirrel.Update.Program.main (System.String[] args) [0x00113] in <1ffb1a5dca5b4f2f93386cec56fd9ec2>:0 
  at Squirrel.Update.Program.Main (System.String[] args) [0x00006] in <1ffb1a5dca5b4f2f93386cec56fd9ec2>:0 
---> (Inner Exception #0) System.Exception
  at Squirrel.Utility.CreateZipFromDirectory (System.String zipFilePath, System.String inFolder) [0x00119] in <1ffb1a5dca5b4f2f93386cec56fd9ec2>:0 <---
at ChildProcess.<anonymous> (/Users/myusername/Desktop/work/project/project/node_modules/electron-winstaller/lib/spawn-promise.js:49:24)
    at ChildProcess.emit (node:events:513:28)
    at ChildProcess.emit (node:domain:489:12)
    at maybeClose (node:internal/child_process:1098:16)
    at ChildProcess._handle.onexit (node:internal/child_process:304:5)

Steps to reproduce

1- install wine with homebrew using this command: brew install --cask wine-stable

2- install mono from their website https://www.mono-project.com/docs/getting-started/install/mac/

3- add mono path to .zprofile export PATH=$PATH:/Library/Frameworks/Mono.framework/Versions/Current/bin/mono

4- in forge.config.js

{
      name: '@electron-forge/maker-squirrel',
      config: {
        certificateFile: './cert.pfx',
        certificatePassword: process.env.CERTIFICATE_PASSWORD,
        authors: 'test',
        description: 'Desktop app'
      },
      platforms: ["win32"]
    }

5- run the make command: electron-forge make --platform win32

Additional information

No response

iwangx commented 1 year ago

I have the same problem

morehardy commented 1 year ago

same problem

gaoxianglyx commented 1 year ago

macos donot support squirrel. we make win package in win-server finally

zzzJH commented 1 year ago

same problem

mbagatini commented 1 year ago

Same issue

zzzmj commented 1 year ago

same problem

hubingliang commented 1 year ago

same problem

MarshallOfSound commented 1 year ago

Commenting "same problem" is not helpful and only serves to spam notifications. GitHub has upvote reactions to indicate support for the issue, no need to comment all the time.

@gaoxianglyx Is correct, Squirrel.Windows does not run on macOS it is recommended to build for windows on a windows machine / CI server.

Groganj89 commented 1 year ago

Commenting "same problem" is not helpful and only serves to spam notifications. GitHub has upvote reactions to indicate support for the issue, no need to comment all the time.

@gaoxianglyx Is correct, Squirrel.Windows does not run on macOS it is recommended to build for windows on a windows machine / CI server.

I am running into the exact same issue as the OP, however, I have seen on the docs the following: "on a macOS or Linux machine with mono and wine installed." so there must be a way.

@ahmadbenos, did you get any further?

max24192 commented 1 year ago

~~I got it working using the workaround mentioned here: https://github.com/Squirrel/Squirrel.Windows/issues/1605#issuecomment-973906514~~ Edit: if you proxy requests to a local homebrew'ed 7zip installation, then it all appears to work great until you install the package in Windows, which will throw errors: error: IEnableLogger: Failed to create uninstaller registry entry: System.NotSupportedException: ZIP archive contains unsupported data structures. The solution to the problem is here: https://github.com/electron/forge/issues/2683#issuecomment-1020178730 you have to delete the 7z-arm64.exe|dll and rename the 7z-x64.exe|dll to 7z.exe|dll in your node-modules folder.

I replaced Wine with

brew uninstall --cask wine-stable
brew tap gcenx/wine
brew install --cask --no-quarantine wine-crossover

...and I believe running winetricks -q mfc42 also fixed an error. Of course in order for that to work you need to brew winetricks as well.

...but then you get stuck signing that thing. Because that 🤬 signtool.exe (that comes with electron-winstaller and is located in your node_modules) throws just a bunch of errors like

SignTool Error: A required function is not present. This error likely means that you are running SignTool on an OS that does not support the options you've specified.

By now I do feel a bit embarrassed to even try to get this to work, but the more people chime in to either get this fixed or get the documentation changed, the less time other people have to throw at it.

So, my last attempt to get signing to work is to brew install osslcodesign, and osslsigncode sign -pkcs12 yourcertificate.pfx -pass yoursecret -n "Your Appname" -i http://www.yourwebsite.com/ -in file.exe -out file-signed.exe actually works 🥳

On to replacing node_modules/electron-winstaller/vendor/signtool.exe that's called from within wine. This gets really messy, because all attempts to integrate osslsigncode stalled. The first person who came up with a solution was Dustin Blackman, but his releases don't work anymore, likely because the sources are pointing to a timestamp server that does not exist anymore. So Victor Hugo forked the project and fixed that, and instead of delivering a release file (security!) you get a docker script to build the file yourself. Which you rename to signtool.exe and place into the node_modules folder that contains the one that is not working.

EDIT: the problem with a self-compiled signtool.exe that diverts the calls to a native homebrew'ed binary is that it does not work. So I ported the mentioned repo from Victor Hugo to node, and am using the proxy technique mentioned in the first link of this post to divert the calls instead. Here's the gist: https://gist.github.com/max24192/3e3b5f4333a5167c4ce8072afb87aa02 You have to save this file as wine, chmod+x it and then add the location of it to your PATH (for example, by changing the package.json script to

"makeWinOnArm64": "export PATH=$HOME/wine_proxy:$PATH && electron-forge make --arch=x64 --platform=win32",

Just a reminder that you cannot have native dependencies. And even if this all works, I'm already facing the next issues in Windows running the exe - it shows me a log from a previous github cli installation from several years ago when I start my application 🤡 I guess squirrel uses the same temp directory. And then on to hundreds of issues related to Squirrel.Windows and electron-winstaller... Seriously, although I was facing some issues with electron-builder's NSIS, it seems like a much better solution in general.

A guess on why we are so masochistic to attempt to do all this today: 1) first, it all kind of worked using electron-builder. Builder has a custom sign solution which seems to work. But electron-builder is huge, and electronjs recommends using forge. So we are switching from builder to forge. Not so sure if I would go that step again, but it seems highly recommended by the electron folks. 2) Apple Silicon does not virtualize x64 Windows. We have fast Apple Silicon machines and this way above appears to be less work than using a dedicated CI system on external (Intel) hardware, which also needs a lot of care, esp. for cross-platform builds. For smaller applications with not so frequent releases, this alternative seems to be useful.

Finally, there is also the docker image from electron-builder that has mono and wine on board. But it did not work in my tests either.

Bug-Reaper commented 1 month ago

@max24192 's suggestion doesn't seem to work anymore M1 Mac Ventura 13 Despite all the steps never got past

System.AggregateException: One or more errors occurred. (Unknown header: 454473068) ---> System.NotSupportedException: Unknown header: 454473068
  at SharpCompress.Common.Zip.ZipHeaderFactory.ReadHeader (System.UInt32 headerBytes, System.IO.BinaryReader reader, System.Boolean zip64)

Also tried using a more recent version of 7zip in the vendor folder.