diff --git a/.github/workflows/windows-installer.yml b/.github/workflows/windows-installer.yml index 1adc71bc4736..00496c436f35 100644 --- a/.github/workflows/windows-installer.yml +++ b/.github/workflows/windows-installer.yml @@ -19,43 +19,19 @@ jobs: python-version: "3.7" - name: curl miniupnpc and setproctitle - working-directory: ${{ github.workspace }}\electron-wix\blockchain + working-directory: ${{ github.workspace }}\build_scripts run: | - curl -OL --show-error --fail https://download.chia.net/simple/miniupnpc/miniupnpc-2.1-cp37-cp37m-win_amd64.whl - curl -OL --show-error --fail https://download.chia.net/simple/setproctitle/setproctitle-1.1.10-cp37-cp37m-win_amd64.whl + git config --global core.longpaths true + ./build_windows.ps1 - - name: Collect and Create wheels for chia-blockchain - run: | - python -m pip install --upgrade pip - pip install pep517 wheel - pip wheel --use-pep517 --only-binary cbor2 --extra-index-url https://download.chia.net/simple/ -f ${{ github.workspace }} --wheel-dir=${{ github.workspace }}\electron-wix\blockchain ${{ github.workspace }}\. - - - name: Install electron-packager - run: | - npm install electron-packager -g - - - name: npm install - working-directory: ${{ github.workspace }}\electron-react - run: | - npm install --runtime=electron --target=1.7.6 - - - name: curl Visual C++ 2019 redistributable # Windows has curl natively - working-directory: ${{ github.workspace }}\electron-wix\prerequisites\ - run: curl -OL --show-error --fail https://aka.ms/vs/16/release/vc_redist.x64.exe - - - name: curl Python 3.7.7 Installer - working-directory: ${{ github.workspace }}\electron-wix\prerequisites\ - run: curl -OL --show-error --fail https://www.python.org/ftp/python/3.7.7/python-3.7.7-amd64.exe - - - name: Build Windows installer with Wix - env: - version: 0.1.13 # TODO Need to create this from setuptools_scm for Windows - working-directory: ${{ github.workspace }}\electron-wix - run: | - .\rebuild-all.ps1 + - name: Upload artifacts EXE + uses: actions/upload-artifact@v1 + with: + name: Windows-Exe + path: ${{ github.workspace }}\electron-react\Chia-win32-x64 - name: Upload artifacts uses: actions/upload-artifact@v1 with: name: Windows-Installers - path: ${{ github.workspace }}\electron-wix\final + path: ${{ github.workspace }}\electron-react\release-builds\ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 175736f78380..990fbbda5287 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -69,8 +69,19 @@ steps: py.test tests -s -v displayName: "pytest" + - script: | + cd build_scripts + sh build_mac.sh + displayName: "Build DMG" + - task: PublishPipelineArtifact@1 inputs: targetPath: $(System.DefaultWorkingDirectory)/wheels artifactName: MacOS-wheels displayName: "Upload MacOS wheels" + + - task: PublishPipelineArtifact@1 + inputs: + targetPath: $(System.DefaultWorkingDirectory)/build_scripts/Chia.dmg + artifactName: MacOS-DMG + displayName: "Upload MacOS DMG" diff --git a/build_scripts/build_mac.sh b/build_scripts/build_mac.sh index 32961f85cd26..2d0000e55798 100644 --- a/build_scripts/build_mac.sh +++ b/build_scripts/build_mac.sh @@ -6,8 +6,9 @@ sudo pyinstaller daemon.spec cp -r dist/daemon ../electron-react cd .. cd electron-react +npm install npm run build -electron-packager . chia --overwrite -mv chia-darwin-x64 ../build_scripts/dist/ +electron-packager . Chia --overwrite --icon=./src/assets/img/chia.ico +mv Chia-darwin-x64 ../build_scripts/dist/ cd ../build_scripts -electron-installer-dmg dist/chia-darwin-x64/chia.app Chia \ No newline at end of file +electron-installer-dmg dist/Chia-darwin-x64/Chia.app Chia --overwrite diff --git a/build_scripts/build_windows.ps1 b/build_scripts/build_windows.ps1 index e69de29bb2d1..0270d93f0b13 100644 --- a/build_scripts/build_windows.ps1 +++ b/build_scripts/build_windows.ps1 @@ -0,0 +1,39 @@ +cd .. +mkdir build_scripts\win_build +cd build_scripts\win_build + +curl -OL --show-error --fail https://download.chia.net/simple/miniupnpc/miniupnpc-2.1-cp37-cp37m-win_amd64.whl +curl -OL --show-error --fail https://download.chia.net/simple/setproctitle/setproctitle-1.1.10-cp37-cp37m-win_amd64.whl +# C:\curl\curl.exe -OL --show-error --fail https://download.chia.net/simple/setproctitle/setproctitle-1.1.10-cp37-cp37m-win_amd64.whl +# C:\curl\curl.exe -OL --show-error --fail https://download.chia.net/simple/miniupnpc/miniupnpc-2.1-cp37-cp37m-win_amd64.whl + +Write-Output "checkpoint 1"; +cd ..\.. +python -m pip install --upgrade pip +pip install pep517 wheel +pip wheel --use-pep517 --only-binary cbor2 --extra-index-url https://download.chia.net/simple/ -f . --wheel-dir=.\build_scripts\win_build . +Write-Output "checkpoint 2"; + +python -m venv venv +. .\venv\Scripts\Activate.ps1 +python -m pip install --upgrade pip +cd build_scripts +python install_win.py +Write-Output "checkpoint 3"; + +pip install pywin32 +pip install pyinstaller +pyinstaller daemon_windows.spec +Write-Output "checkpoint 4"; + +cp -r dist/daemon ../electron-react/ +cd ../electron-react + +Write-Output "checkpoint 5"; + +npm install --save-dev electron-winstaller +npm install -g electron-packager +npm install +npm run build +electron-packager . Chia --asar.unpack="**/daemon/**" --overwrite --icon=./src/assets/img/chia.ico +node winstaller.js diff --git a/build_scripts/daemon.spec b/build_scripts/daemon.spec index e82f5e680542..b5bc2d823654 100644 --- a/build_scripts/daemon.spec +++ b/build_scripts/daemon.spec @@ -73,7 +73,7 @@ full_node = Analysis([f"{root}/src/server/start_full_node.py"], wallet = Analysis([f"{root}/src/wallet/websocket_server.py"], pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], binaries = [], - datas=[(f"{root}/src/util/bip39/english.txt", f"."), version_data ], + datas=[(f"{root}/src/util/bip39/english.txt", f"./src/util/bip39/"), version_data ], hiddenimports=subcommand_modules, hookspath=[], runtime_hooks=[], diff --git a/build_scripts/daemon_windows.spec b/build_scripts/daemon_windows.spec index e69de29bb2d1..c5e61b3a23f0 100644 --- a/build_scripts/daemon_windows.spec +++ b/build_scripts/daemon_windows.spec @@ -0,0 +1,262 @@ +# -*- mode: python ; coding: utf-8 -*- +#from src.cmds.chia import SUBCOMMANDS +import pathlib + +from PyInstaller.utils.hooks import collect_submodules, copy_metadata + +keyring_imports = collect_submodules('keyring.backends') + +# keyring uses entrypoints to read keyring.backends from metadata file entry_points.txt. +keyring_datas = copy_metadata('keyring')[0] + +from pkg_resources import get_distribution + +build = pathlib.Path().absolute() +root = build.parent + +from PyInstaller.utils.hooks import copy_metadata +version_data = copy_metadata(get_distribution("chia-blockchain"))[0] + +SUBCOMMANDS = [ + "init", + "keys", + "show", + "start", + "stop", + "version", + "netspace", + "run_daemon", +] +block_cipher = None +subcommand_modules = [f"{root}/src.cmds.%s" % _ for _ in SUBCOMMANDS] +other = ["aiter.active_aiter", "aiter.aiter_forker", "aiter.aiter_to_iter", "aiter.azip", "aiter.flatten_aiter", "aiter.gated_aiter", +"aiter.iter_to_aiter", "aiter.join_aiters", "aiter.map_aiter", "aiter.map_filter_aiter", "aiter.preload_aiter", +"aiter.push_aiter", "aiter.sharable_aiter", "aiter.stoppable_aiter","src.wallet.websocket_server", "win32cred", "pywintypes", "win32ctypes.pywin32"] + +entry_points = ["aiohttp", "aiohttp.aiohttp", + "src.cmds.check_plots", + "src.cmds.create_plots", + "src.wallet.websocket_server", + "src.server.start_full_node", + "src.server.start_harvester", + "src.server.start_farmer", + "src.server.start_introducer", + "src.server.start_timelord", + "src.timelord_launcher", + "src.simulator.start_simulator", + "src.util.bip32"] + +subcommand_modules.extend(other) +subcommand_modules.extend(entry_points) +subcommand_modules.extend(keyring_imports) + +daemon = Analysis([f"{root}/src/daemon/server.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [(f"{root}/venv\Lib\site-packages\\*dll", '.')], + datas=[keyring_datas, version_data, (f"../src/util/initial-config.yaml", f"./src/util/"), + (f"../src/util/initial-plots.yaml", f"./src/util/") ], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +full_node = Analysis([f"{root}/src/server/start_full_node.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [], + datas=[version_data], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +wallet = Analysis([f"{root}/src/wallet/websocket_server.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [], + datas=[(f"{root}/src/util/bip39/english.txt", f"./src/util/bip39/"), version_data ], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +plotter = Analysis([f"{root}/src/cmds/create_plots.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [], + datas=[version_data], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +farmer = Analysis([f"{root}/src/server/start_farmer.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [], + datas=[version_data], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +harvester = Analysis([f"{root}/src/server/start_harvester.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [], + datas=[version_data], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +check_plots = Analysis([f"{root}/src/cmds/check_plots.py"], + pathex=[f"{root}/venv/lib/python3.7/site-packages/aiter/", f"{root}"], + binaries = [], + datas=[version_data], + hiddenimports=subcommand_modules, + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) + +daemon_pyz = PYZ(daemon.pure, daemon.zipped_data, + cipher=block_cipher) +full_node_pyz = PYZ(full_node.pure, full_node.zipped_data, + cipher=block_cipher) +wallet_pyz = PYZ(wallet.pure, wallet.zipped_data, + cipher=block_cipher) +plotter_pyz = PYZ(plotter.pure, plotter.zipped_data, + cipher=block_cipher) +farmer_pyz = PYZ(farmer.pure, farmer.zipped_data, + cipher=block_cipher) +harvester_pyz = PYZ(harvester.pure, harvester.zipped_data, + cipher=block_cipher) +check_plots_pyz = PYZ(check_plots.pure, check_plots.zipped_data, + cipher=block_cipher) + +daemon_exe = EXE(daemon_pyz, + daemon.scripts, + [], + exclude_binaries=True, + name='daemon', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=True ) + +full_node_exe = EXE(full_node_pyz, + full_node.scripts, + [], + exclude_binaries=True, + name='start_full_node', + debug=False, + bootloader_ignore_signals=False, + strip=False) + +wallet_exe = EXE(wallet_pyz, + wallet.scripts, + [], + exclude_binaries=True, + name='websocket_server', + debug=False, + bootloader_ignore_signals=False, + strip=False) + +plotter_exe = EXE(plotter_pyz, + plotter.scripts, + [], + exclude_binaries=True, + name='create_plots', + debug=False, + bootloader_ignore_signals=False, + strip=False) + +farmer_exe = EXE(farmer_pyz, + farmer.scripts, + [], + exclude_binaries=True, + name='start_farmer', + debug=False, + bootloader_ignore_signals=False, + strip=False) + +harvester_exe = EXE(harvester_pyz, + farmer.scripts, + [], + exclude_binaries=True, + name='start_harvester', + debug=False, + bootloader_ignore_signals=False, + strip=False) + +check_plots_exe = EXE(check_plots_pyz, + check_plots.scripts, + [], + exclude_binaries=True, + name='start_harvester', + debug=False, + bootloader_ignore_signals=False, + strip=False) + +coll = COLLECT(daemon_exe, + daemon.binaries, + daemon.zipfiles, + daemon.datas, + + full_node_exe, + full_node.binaries, + full_node.zipfiles, + full_node.datas, + + wallet_exe, + wallet.binaries, + wallet.zipfiles, + wallet.datas, + + plotter_exe, + plotter.binaries, + plotter.zipfiles, + plotter.datas, + + farmer_exe, + farmer.binaries, + farmer.zipfiles, + farmer.datas, + + harvester_exe, + harvester.binaries, + harvester.zipfiles, + harvester.datas, + + check_plots_exe, + check_plots.binaries, + check_plots.zipfiles, + check_plots.datas, + strip = False, + upx_exclude = [], + name = 'daemon' +) diff --git a/build_scripts/install_win.py b/build_scripts/install_win.py new file mode 100644 index 000000000000..7c8a597439e5 --- /dev/null +++ b/build_scripts/install_win.py @@ -0,0 +1,6 @@ +import os +import subprocess +import sys + +for filename in os.listdir('.\win_build'): + subprocess.check_call([sys.executable, "-m", "pip", "install", f".\win_build\{filename}"]) diff --git a/electron-react/package-lock.json b/electron-react/package-lock.json index fe96865229d6..80ff8c164c7f 100644 --- a/electron-react/package-lock.json +++ b/electron-react/package-lock.json @@ -1,5 +1,5 @@ { - "name": "chia-wallet", + "name": "Chia", "version": "0.1.0", "lockfileVersion": 1, "requires": true, @@ -2198,6 +2198,22 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, + "asar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/asar/-/asar-2.1.0.tgz", + "integrity": "sha512-d2Ovma+bfqNpvBzY/KU8oPY67ZworixTpkjSx0PCXnQi67c2cXmssaTxpFDUM0ttopXoGx/KRxNg/GDThYbXQA==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "chromium-pickle-js": "^0.2.0", + "commander": "^2.20.0", + "cuint": "^0.2.2", + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "tmp-promise": "^1.0.5" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -3342,6 +3358,12 @@ "tslib": "^1.9.0" } }, + "chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", + "dev": true + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -4087,6 +4109,12 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==" }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", + "dev": true + }, "cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", @@ -4552,6 +4580,32 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.425.tgz", "integrity": "sha512-JTEOWiqCY4snuKuQAaFy0z6LK2Gdb8Lojkd/csQwpNHgMUF8I6QRjGVKk44IH46dHQhUFKzr4o6zxZrtDBjc2Q==" }, + "electron-winstaller": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-4.0.0.tgz", + "integrity": "sha512-Rq5YUQ/zBiGiDW3ezVaRigF3QbohVjDtfcpZpzmhJxX/1jndc96OQJw2x1HulHmhPV7n9R4WEsMkzkHObufU9g==", + "dev": true, + "requires": { + "asar": "^2.0.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash.template": "^4.2.2", + "temp": "^0.9.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "elliptic": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", @@ -13826,6 +13880,15 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, + "temp": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz", + "integrity": "sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==", + "dev": true, + "requires": { + "rimraf": "~2.6.2" + } + }, "terser": { "version": "4.6.13", "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", @@ -14033,6 +14096,27 @@ "os-tmpdir": "~1.0.2" } }, + "tmp-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-1.1.0.tgz", + "integrity": "sha512-8+Ah9aB1IRXCnIOxXZ0uFozV1nMU5xiu7hhFVUSxZ3bYu+psD4TzagCzVbexUCgNNGJnsmNDQlS4nG3mTyoNkw==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "tmp": "0.1.0" + }, + "dependencies": { + "tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + } + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", diff --git a/electron-react/package.json b/electron-react/package.json index 2ce993e0b4ab..21b63caab781 100644 --- a/electron-react/package.json +++ b/electron-react/package.json @@ -1,8 +1,12 @@ { - "name": "chia-wallet", + "name": "Chia", + "author": "Straya Markovic", + "description": "GUI for Chia Blockchain", + "productName": "Chia", "version": "0.1.0", "private": true, "devDependencies": { + "electron-winstaller": "^4.0.0", "foreman": "^3.0.1", "prettier-eslint": "^9.0.1", "prettier-eslint-cli": "^5.0.0", diff --git a/electron-react/src/assets/img/chia.icns b/electron-react/src/assets/img/chia.icns new file mode 100644 index 000000000000..8b913ef1e6cf Binary files /dev/null and b/electron-react/src/assets/img/chia.icns differ diff --git a/electron-react/src/assets/img/chia.ico b/electron-react/src/assets/img/chia.ico new file mode 100644 index 000000000000..3166d909a124 Binary files /dev/null and b/electron-react/src/assets/img/chia.ico differ diff --git a/electron-react/src/electron-starter.js b/electron-react/src/electron-starter.js index 2a20cf51da4d..1ade9ddc4ea4 100644 --- a/electron-react/src/electron-starter.js +++ b/electron-react/src/electron-starter.js @@ -1,3 +1,10 @@ +//handle setupevents as quickly as possible +const setupEvents = require('./setupEvents') +if (setupEvents.handleSquirrelEvent()) { + // squirrel event handled and app will exit in 1000ms, so don't do anything else + return; +} + const electron = require("electron"); const app = electron.app; const BrowserWindow = electron.BrowserWindow; @@ -21,8 +28,8 @@ global.sharedObj = { local_test: local_test }; * py process *************************************************************/ -const PY_BUILD_FOLDER = "../daemon"; -const PY_DIST_FOLDER = "../daemon"; +const PY_MAC_DIST_FOLDER = "../daemon"; +const PY_WIN_DIST_FOLDER = "../../app.asar.unpacked/daemon"; const PY_DIST_FILE = "daemon"; const PY_FOLDER = "../src/daemon"; const PY_MODULE = "server"; // without .py suffix @@ -30,9 +37,17 @@ const PY_MODULE = "server"; // without .py suffix let pyProc = null; const guessPackaged = () => { - const fullPath = path.join(__dirname, PY_BUILD_FOLDER); + if (process.platform === "win32") { + const fullPath = path.join(__dirname, PY_WIN_DIST_FOLDER); + packed = require("fs").existsSync(fullPath); + console.log(fullPath); + console.log(packed); + return packed + } + const fullPath = path.join(__dirname, PY_MAC_DIST_FOLDER); packed = require("fs").existsSync(fullPath); console.log(fullPath); + console.log(packed); return packed; }; @@ -41,9 +56,9 @@ const getScriptPath = () => { return path.join(PY_FOLDER, PY_MODULE + ".py"); } if (process.platform === "win32") { - return path.join(__dirname, PY_DIST_FOLDER, PY_DIST_FILE + ".exe"); + return path.join(__dirname, PY_WIN_DIST_FOLDER, PY_DIST_FILE + ".exe"); } - return path.join(__dirname, PY_DIST_FOLDER, PY_DIST_FILE); + return path.join(__dirname, PY_MAC_DIST_FOLDER, PY_DIST_FILE); }; const createPyProc = () => { @@ -63,6 +78,8 @@ const createPyProc = () => { } } else { console.log("Running python script"); + console.log("Script " + script); + const Process = require("child_process").spawn; pyProc = new Process("python", [script], processOptions); } diff --git a/electron-react/src/pages/NewWallet.js b/electron-react/src/pages/NewWallet.js index 312be3c26e4e..1ed2912444a9 100644 --- a/electron-react/src/pages/NewWallet.js +++ b/electron-react/src/pages/NewWallet.js @@ -42,10 +42,12 @@ const Iterator = props => { }; const UIPart = props => { - const words = useSelector(state => state.wallet_state.mnemonic); + var words = useSelector(state => state.wallet_state.mnemonic); const dispatch = useDispatch(); const classes = myStyle(); - + if (!words) { + words = [] + } function goBack() { dispatch(changeEntranceMenu(presentSelectKeys)); } diff --git a/electron-react/src/setupEvents.js b/electron-react/src/setupEvents.js new file mode 100644 index 000000000000..21df5237c9d9 --- /dev/null +++ b/electron-react/src/setupEvents.js @@ -0,0 +1,65 @@ +const electron = require('electron') +const app = electron.app + +module.exports = { +handleSquirrelEvent: function() { + if (process.argv.length === 1) { + return false; + } + + const ChildProcess = require('child_process'); + const path = require('path'); + + const appFolder = path.resolve(process.execPath, '..'); + const rootAtomFolder = path.resolve(appFolder, '..'); + const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe')); + const exeName = path.basename(process.execPath); + const spawn = function(command, args) { + let spawnedProcess, error; + + try { + spawnedProcess = ChildProcess.spawn(command, args, {detached: true}); + } catch (error) {} + + return spawnedProcess; + }; + + const spawnUpdate = function(args) { + return spawn(updateDotExe, args); + }; + + const squirrelEvent = process.argv[1]; +switch (squirrelEvent) { + case '--squirrel-install': + case '--squirrel-updated': + // Optionally do things such as: + // - Add your .exe to the PATH + // - Write to the registry for things like file associations and + // explorer context menus + + // Install desktop and start menu shortcuts + spawnUpdate(['--createShortcut', exeName]); + + setTimeout(app.quit, 1000); + return true; + + case '--squirrel-uninstall': + // Undo anything you did in the --squirrel-install and + // --squirrel-updated handlers + + // Remove desktop and start menu shortcuts + spawnUpdate(['--removeShortcut', exeName]); + + setTimeout(app.quit, 1000); + return true; + + case '--squirrel-obsolete': + // This is called on the outgoing version of your app before + // we update to the new version - it's the opposite of + // --squirrel-updated + + app.quit(); + return true; +} +} +} diff --git a/electron-react/windows.json b/electron-react/windows.json new file mode 100644 index 000000000000..03adc7c908c4 --- /dev/null +++ b/electron-react/windows.json @@ -0,0 +1,5 @@ +{ + "dest": "dist/installers/", + "icon": "src/assets/img/chia.ico", + "tags": ["Blockchain"] +} diff --git a/electron-react/winstaller.js b/electron-react/winstaller.js new file mode 100644 index 000000000000..71acbd9f4c8f --- /dev/null +++ b/electron-react/winstaller.js @@ -0,0 +1,25 @@ +const createWindowsInstaller = require('electron-winstaller').createWindowsInstaller +const path = require('path') + +getInstallerConfig() + .then(createWindowsInstaller) + .catch((error) => { + console.error(error.message || error) + process.exit(1) + }) + +function getInstallerConfig () { + console.log('creating windows installer') + const rootPath = path.join('./') + const outPath = path.join(rootPath, 'release-builds') + + return Promise.resolve({ + appDirectory: path.join(rootPath, 'Chia-win32-x64/'), + authors: 'Chia Networks', + noMsi: true, + outputDirectory: path.join(outPath, 'windows-installer'), + exe: 'Chia.exe', + setupExe: 'ChiaSetup.exe', + setupIcon: path.join(rootPath, 'src', 'assets', 'img', 'chia.ico') + }) +} diff --git a/src/daemon/server.py b/src/daemon/server.py index 9c64b4d0a967..728aa1eb0995 100644 --- a/src/daemon/server.py +++ b/src/daemon/server.py @@ -313,6 +313,10 @@ def launch_service(root_path, service_command): service_name = service_array[0] service_executable = executable_for_service(service_name) service_array[0] = service_executable + startupinfo = None + if os.name == 'nt': + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW if service_name == "chia-create-plots": plotter_path = plotter_log_path(root_path) if plotter_path.parent.exists(): @@ -321,9 +325,9 @@ def launch_service(root_path, service_command): else: mkdir(plotter_path.parent) outfile = open(plotter_path.resolve(), "w") - process = subprocess.Popen(service_array, shell=False, stdout=outfile) + process = subprocess.Popen(service_array, shell=False, stdout=outfile, startupinfo=startupinfo) else: - process = subprocess.Popen(service_array, shell=False) + process = subprocess.Popen(service_array, shell=False, startupinfo=startupinfo) pid_path = pid_path_for_service(root_path, service_command) try: mkdir(pid_path.parent) diff --git a/src/server/start_full_node.py b/src/server/start_full_node.py index 8a660a791084..085b04bb0396 100644 --- a/src/server/start_full_node.py +++ b/src/server/start_full_node.py @@ -17,6 +17,7 @@ from src.util.config import load_config_cli, load_config from src.util.default_root import DEFAULT_ROOT_PATH from src.util.setproctitle import setproctitle +from multiprocessing import freeze_support async def async_main(): @@ -109,4 +110,5 @@ def main(): if __name__ == "__main__": + freeze_support() main()