diff --git a/basicswap/interface/xmr.py b/basicswap/interface/xmr.py
index 48ddcc7..f6fcc20 100644
--- a/basicswap/interface/xmr.py
+++ b/basicswap/interface/xmr.py
@@ -5,6 +5,7 @@
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
+import os
import json
import logging
@@ -96,6 +97,13 @@ class XMRInterface(CoinInterface):
params = {'filename': filename}
if self._wallet_password is not None:
params['password'] = self._wallet_password
+
+ try:
+ # Can't reopen the same wallet in windows, !is_keys_file_locked()
+ if os.name == 'nt':
+ self.rpc_wallet_cb('close_wallet')
+ except Exception:
+ pass
self.rpc_wallet_cb('open_wallet', params)
def initialiseWallet(self, key_view, key_spend, restore_height=None):
diff --git a/basicswap/templates/offer.html b/basicswap/templates/offer.html
index 85a0526..c54cd72 100644
--- a/basicswap/templates/offer.html
+++ b/basicswap/templates/offer.html
@@ -178,7 +178,7 @@
diff --git a/bin/basicswap_prepare.py b/bin/basicswap_prepare.py
index 6b2f092..5d18007 100755
--- a/bin/basicswap_prepare.py
+++ b/bin/basicswap_prepare.py
@@ -318,6 +318,24 @@ def extractCore(coin, version_data, settings, bin_dir, release_path, extra_opts=
else:
raise ValueError('Unknown coin')
+ if 'win32' in BIN_ARCH or 'win64' in BIN_ARCH:
+ with zipfile.ZipFile(release_path) as fz:
+ namelist = fz.namelist()
+ for b in bins:
+ b += '.exe'
+ out_path = os.path.join(bin_dir, b)
+ if (not os.path.exists(out_path)) or extract_core_overwrite:
+ for entry in namelist:
+ if entry.endswith(b):
+ with open(out_path, 'wb') as fout:
+ fout.write(fz.read(entry))
+ try:
+ os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH)
+ except Exception as e:
+ logging.warning('Unable to set file permissions: %s, for %s', str(e), out_path)
+ break
+ return
+
num_exist = 0
for b in bins:
out_path = os.path.join(bin_dir, b)
@@ -934,8 +952,11 @@ def printHelp():
def finalise_daemon(d):
logging.info('Interrupting {}'.format(d.pid))
- d.send_signal(signal.SIGINT)
- d.wait(timeout=120)
+ try:
+ d.send_signal(signal.CTRL_C_EVENT if os.name == 'nt' else signal.SIGINT)
+ d.wait(timeout=120)
+ except Exception as e:
+ logging.info(f'Error {e}'.format(d.pid))
for fp in (d.stdout, d.stderr, d.stdin):
if fp:
fp.close()
@@ -995,7 +1016,8 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
if c == Coins.XMR:
if coin_settings['manage_wallet_daemon']:
- daemons.append(startXmrWalletDaemon(coin_settings['datadir'], coin_settings['bindir'], 'monero-wallet-rpc'))
+ filename = 'monero-wallet-rpc' + ('.exe' if os.name == 'nt' else '')
+ daemons.append(startXmrWalletDaemon(coin_settings['datadir'], coin_settings['bindir'], filename))
else:
if coin_settings['manage_daemon']:
filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '')
@@ -1063,6 +1085,10 @@ def load_config(config_path):
return json.load(fs)
+def signal_handler(sig, frame):
+ logger.info('Signal %d detected' % (sig))
+
+
def main():
global use_tor_proxy
data_dir = None
@@ -1084,6 +1110,10 @@ def main():
tor_control_password = None
extra_opts = {}
+ if os.name == 'nt':
+ # On windows sending signal.CTRL_C_EVENT to a subprocess causes it to be sent to the parent process too
+ signal.signal(signal.SIGINT, signal_handler)
+
for v in sys.argv[1:]:
if len(v) < 2 or v[0] != '-':
exitWithError('Unknown argument {}'.format(v))
diff --git a/bin/basicswap_run.py b/bin/basicswap_run.py
index 4606155..625916e 100755
--- a/bin/basicswap_run.py
+++ b/bin/basicswap_run.py
@@ -153,9 +153,10 @@ def runClient(fp, data_dir, chain):
if c == 'monero':
if v['manage_daemon'] is True:
swap_client.log.info(f'Starting {display_name} daemon')
- daemons.append(startXmrDaemon(v['datadir'], v['bindir'], 'monerod'))
+ filename = 'monerod' + ('.exe' if os.name == 'nt' else '')
+ daemons.append(startXmrDaemon(v['datadir'], v['bindir'], filename))
pid = daemons[-1].pid
- swap_client.log.info('Started {} {}'.format('monerod', pid))
+ swap_client.log.info('Started {} {}'.format(filename, pid))
if v['manage_wallet_daemon'] is True:
swap_client.log.info(f'Starting {display_name} wallet daemon')
@@ -167,9 +168,10 @@ def runClient(fp, data_dir, chain):
if daemon_rpcuser != '':
opts.append('--daemon-login')
opts.append(daemon_rpcuser + ':' + daemon_rpcpass)
- daemons.append(startXmrWalletDaemon(v['datadir'], v['bindir'], 'monero-wallet-rpc', opts))
+ filename = 'monero-wallet-rpc' + ('.exe' if os.name == 'nt' else '')
+ daemons.append(startXmrWalletDaemon(v['datadir'], v['bindir'], filename, opts))
pid = daemons[-1].pid
- swap_client.log.info('Started {} {}'.format('monero-wallet-rpc', pid))
+ swap_client.log.info('Started {} {}'.format(filename, pid))
continue
if v['manage_daemon'] is True:
@@ -235,7 +237,7 @@ def runClient(fp, data_dir, chain):
for d in daemons:
swap_client.log.info('Interrupting {}'.format(d.pid))
try:
- d.send_signal(signal.SIGINT)
+ d.send_signal(signal.CTRL_C_EVENT if os.name == 'nt' else signal.SIGINT)
except Exception as e:
swap_client.log.info('Interrupting %d, error %s', d.pid, str(e))
for d in daemons:
diff --git a/doc/notes.md b/doc/notes.md
index a35da73..37ba9c3 100644
--- a/doc/notes.md
+++ b/doc/notes.md
@@ -55,6 +55,44 @@ On the remote machine open an ssh tunnel to port 18081:
And start monerod
+## Installing on windows natively
+
+This is not a supported installation method!
+
+Install prerequisites:
+- https://gitforwindows.org/
+- https://www.python.org/downloads/windows/
+
+
+In the start menu find Git / Git Bash
+Right click Git Bash -> More -> run as administrator
+
+
+Create and activate a venv
+
+ python -m venv c:\bsx_venv
+ c:/bsx_venv/scripts/activate
+
+
+Install coincurve
+
+ git clone https://github.com/tecnovert/coincurve.git -b bsx_windows
+ cd coincurve/
+ pip3 install .
+
+
+Install basicswap
+
+ git clone https://github.com/tecnovert/basicswap.git
+ cd basicswap
+ pip3 install .
+
+
+Test:
+
+ basicswap-prepare.exe --help
+
+
## Run One Test
```
|