diff --git a/.gitignore b/.gitignore
index dc7b3ca10d89e7fee9cfa4eba43096fe6c454f08..ee654e19581e320108fc394100b985077f6e4b77 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,4 @@ bin/
*.wixobj
*.wixpdb
*.msi
-rsync-mingw64-files.wxs
+*-files.wxs
diff --git a/Makefile b/Makefile
index a045810d0e710398c0516709c9808df6026d597b..ff461be9d012330ebeb8f8d5a8a97503fadc357a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,29 +1,36 @@
-WIX_DIR := "C:\Program Files (x86)\WiX Toolset v3.11\bin"
-HEAT := "C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe"
-CANDLE := "C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" -arch x64
-LIGHT := "C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe"
-default: test
+WIX_DIR := C:\Program Files (x86)\WiX Toolset v3.11\bin
+HEAT := "$(WIX_DIR)\heat.exe"
+CANDLE := "$(WIX_DIR)\candle.exe" -arch x64 -nologo
+LIGHT := "$(WIX_DIR)\light.exe" -nologo
+
+RSYNC_MINGW_DIR := D:\downloads\apps\rsync-w64
+MBACKUP_PUBLISH_DIR := bin\Release\netcoreapp3.0\publish
+
+default: build
+help:
+ @cmd /C echo 'Usage: make [build|test|release|clean|dist|all]'
all: test release dist
-dist: mbackup.msi rsync-mingw64.msi
+dist: mbackup.msi
release:
- dotnet publish -c Release -r win10-x64 --nologo
+ dotnet publish --nologo -c Release --self-contained false
test:
- dotnet test mbackup-tests
+ dotnet test --nologo mbackup-tests
check: test
build:
- dotnet build
+ dotnet build --nologo
clean:
- dotnet clean
- del *.wixobj *.msi
+ dotnet clean --nologo
+ cmd /C 'del *.wixobj *.wixpdb *.msi rsync-mingw64-files.wxs'
%.wixobj: %.wxs
$(CANDLE) $<
-mbackup.msi: mbackup.wixobj release
- $(LIGHT) $<
-# standalone rsync-mingw64
rsync-mingw64-files.wxs:
- $(HEAT) dir "D:\downloads\apps\rsync-w64" -cg RsyncHeatGenerated -dr ProgramFiles64Folder -var var.RsyncSourceDir -gg -nologo -out rsync-mingw64-files.wxs -sw5150
-rsync-mingw64.msi: rsync-mingw64.wxs rsync-mingw64-files.wxs
- $(CANDLE) -dRsyncSourceDir=D:\downloads\apps\rsync-w64\ .\rsync-mingw64.wxs .\rsync-mingw64-files.wxs
- $(LIGHT) rsync-mingw64.wixobj rsync-mingw64-files.wixobj -o rsync-mingw64.msi
-# END standalone rsync-mingw64
-.PHONY: default all dist release test check build clean
+ $(HEAT) dir $(RSYNC_MINGW_DIR) -cg RsyncHeatGenerated -dr MBACKUP_PROGRAM_FILES -var var.RsyncSourceDir -gg -nologo -out $@ -sw5150
+rsync-mingw64-files.wixobj: rsync-mingw64-files.wxs
+ $(CANDLE) -dRsyncSourceDir=$(RSYNC_MINGW_DIR) $<
+mbackup-files.wxs: release
+ $(HEAT) dir $(MBACKUP_PUBLISH_DIR) -cg MbackupHeatGenerated -dr MBACKUP_PROGRAM_FILES -var var.MbackupPublishDir -gg -nologo -out $@ -sw5150
+mbackup-files.wixobj: mbackup-files.wxs
+ $(CANDLE) -dMbackupPublishDir=$(MBACKUP_PUBLISH_DIR) $<
+mbackup.msi: mbackup.wixobj rsync-mingw64-files.wixobj mbackup-files.wixobj
+ $(LIGHT) $^ -o $@
+.PHONY: default help all dist release test check build clean rsync-mingw64-files.wxs mbackup-files.wxs
diff --git a/Program.fs b/Program.fs
index dd10a5faca98e38388c4403a5f541138a3675810..8830fc3c3f1d1355a79e7d8c93c5ebe66634f350 100644
--- a/Program.fs
+++ b/Program.fs
@@ -44,6 +44,11 @@ with
| Node_Name _ -> "local node's name, used in remote logging"
| Ssh_Key _ -> "ssh private key, used when backup to remote ssh node"
+let programFilesDirWin = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) |> ensureWinDir
+let programFilesDir = toMingwPath programFilesDirWin
+let mbackupProgramDirWin = programFilesDirWin + "mbackup\\"
+let mbackupProgramDir = toMingwPath mbackupProgramDirWin
+
let appDataRoamingDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) |> toMingwPath |> ensureDir
let programDataDirWin = getEnv "PROGRAMDATA" |> ensureWinDir
let programDataDir = toMingwPath programDataDirWin
@@ -115,7 +120,7 @@ let generateMbackupList (logger: Logger) =
let lines = readMbackupListFile mbackupLocalList |> Seq.map toMingwPath
(true, lines)
with
- | :? System.IO.FileNotFoundException ->
+ | :? FileNotFoundException ->
(true, Seq.empty)
| ex ->
logger.Error "Read mbackupLocalList failed: %s" ex.Message
@@ -151,6 +156,7 @@ let main argv =
logger.Info "user config dir: %s" userConfigDirWin
logger.Info "runtime dir: %s" runtimeDirWin
+ logger.Debug "program dir: %s" mbackupProgramDirWin
let rsyncCmd: string list = []
let rsyncCmd = appendWhen dryRun rsyncCmd "--dry-run"
@@ -170,13 +176,10 @@ let main argv =
let localLogFile = runtimeDir + "mbackup.log"
let rsyncCmd = List.append rsyncCmd [sprintf "--log-file=%s" localLogFile]
- // TODO remove usage of test dir.
- let mbackupInstallDirWinTest = "D:\\downloads\\apps\\mbackupTest\\"
- let mbackupInstallDirTest = mbackupInstallDirWinTest |> toMingwPath |> ensureDir
- let sshExeFile = mbackupInstallDirTest + "rsync-w64/usr/bin/ssh.exe"
+ let sshExeFile = mbackupProgramDir + "rsync-w64/usr/bin/ssh.exe"
let sshConfigFile = userHome + ".ssh/config"
let sshPrivateKeyFile = results.GetResult(Ssh_Key, defaultValue = userHome + ".ssh/id_rsa") |> toMingwPath
- let rsyncCmd = List.append rsyncCmd [sprintf "-e \"%s -F %s -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\"" sshExeFile sshConfigFile sshPrivateKeyFile]
+ let rsyncCmd = List.append rsyncCmd [sprintf "-e \"'%s' -F %s -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\"" sshExeFile sshConfigFile sshPrivateKeyFile]
// precedence: command line argument > environment variable > config file
let normalizeTarget target =
@@ -211,13 +214,12 @@ let main argv =
let rsyncCmd = List.append rsyncCmd ["/"]
let rsyncCmd = List.append rsyncCmd [backupTarget]
let rsyncArgs = rsyncCmd |> String.concat " "
- let rsyncExe = mbackupInstallDirWinTest + "rsync-w64\\usr\\bin\\rsync.exe"
- let echoExe = "C:\\Program Files\\Git\\usr\\bin\\echo.exe"
+ let rsyncExe = mbackupProgramDirWin + "rsync-w64\\usr\\bin\\rsync.exe"
try
- IO.Directory.CreateDirectory(runtimeDir) |> ignore
- IO.Directory.CreateDirectory(userConfigDir) |> ignore
- let proc = Process.Start(rsyncExe, rsyncArgs)
+ Directory.CreateDirectory(runtimeDir) |> ignore
+ Directory.CreateDirectory(userConfigDir) |> ignore
logger.Info "Note: if you run the following rsync command yourself, make sure the generated file list (%s) is up-to-date.\n%s" mbackupFile (rsyncExe + " " + rsyncArgs)
+ let proc = Process.Start(rsyncExe, rsyncArgs)
if proc.WaitForExit Int32.MaxValue then
logger.Info "mbackup exit"
proc.ExitCode
@@ -225,7 +227,7 @@ let main argv =
logger.Error "mbackup timed out while waiting for rsync to complete"
ExitTimeout
with
- | :? System.IO.IOException as ex ->
+ | :? IOException as ex ->
logger.Error "IO Error: %s %s" ex.Source ex.Message
ExitIOError
| ex ->
diff --git a/mbackup-tests/mbackup-tests.fsproj b/mbackup-tests/mbackup-tests.fsproj
index f3cd82691280285e420e4f6db2b7cab56be659e8..27274ddcf9ba49af08df7e3bff297d4426cdeaff 100644
--- a/mbackup-tests/mbackup-tests.fsproj
+++ b/mbackup-tests/mbackup-tests.fsproj
@@ -20,7 +20,7 @@
-
+
diff --git a/mbackup-for-windows.fsproj b/mbackup.fsproj
similarity index 89%
rename from mbackup-for-windows.fsproj
rename to mbackup.fsproj
index 213547fcb14078475c8def57098ebdcdf5838792..7ac4a9e55d30ca90e55c76a2c5e98cadd43ceb0a 100644
--- a/mbackup-for-windows.fsproj
+++ b/mbackup.fsproj
@@ -5,6 +5,7 @@
netcoreapp3.0
win10-x64
Mbackup
+ true
diff --git a/mbackup.wxs b/mbackup.wxs
index 6436e5f32a0ee892255f2aef20944171765e0c59..ea786d9e8511be47dc3d960b9e536482e4d58e28 100644
--- a/mbackup.wxs
+++ b/mbackup.wxs
@@ -5,20 +5,14 @@
-
+
-
+
-
-
-
-
-
-
-
+
@@ -35,7 +29,8 @@
-
+
+
diff --git a/operational b/operational
index 0b8f10be74f2f0c641251f7509295a7528e0ede7..87647fc9c23429bd2d087c6094fad905a3b81e31 100644
--- a/operational
+++ b/operational
@@ -85,6 +85,8 @@ dotnet run -- -i
** 2019-11-13 install dir layout.
C:\Program Files\mbackup\rsync-w64\usr\bin\rsync.exe
C:\Program Files\mbackup\rsync-w64\usr\bin\ssh.exe
+C:\Program Files\mbackup\publish\mbackup.exe
+C:\Program Files\mbackup\publish\mbackup.dll
C:\ProgramData\mbackup\mbackup-default.exclude
C:\ProgramData\mbackup\mbackup-default.list
C:\ProgramData\mbackup\user-default.list
@@ -117,6 +119,8 @@ C:\ProgramData\mbackup\mbackup.txt
use candle -arch x64 can add Win64="yes" automatically if there is no Win64 attribute specified in Component.
wix3.6 - WiX Heat tool, create Component with Win64 attribute - Stack Overflow
https://stackoverflow.com/questions/11981498/wix-heat-tool-create-component-with-win64-attribute
+- Wix to install file in another name, add Name attribute in .
+
-
* later :entry:
@@ -174,10 +178,22 @@ Both local.list and local.exclude.
https://wixtoolset.org/documentation/manual/v3/howtos/
- How To: Add a File to Your Installer
https://wixtoolset.org/documentation/manual/v3/howtos/files_and_registry/add_a_file.html
- - create installer.wxs
+ - create mbackup.wxs
build mbackup binaries
dotnet publish -c Release
+ - TODO how to show a message when installer is finished succesfully?
+ currently it installs very fast and just exit without any user notification.
+ maybe show a installer window and let user click Next and Finish.
+ - TODO how to add some dir to PATH?
+ I only have one exe. Maybe just create a start menu or desktop shortcut?
+ create desktop shortcut to mbackup.exe
+ - TODO how to support upgrade when I click a new msi?
+ currently every msi is a standalone msi and will always install fresh.
+ is the UpgradeCode used for this?
+ - mbackup.msi works on B75I3 host.
+ - try mbackup.msi on win 10 VM.
+ how to require dotnet core 3.0 in .wxs file?
- problems
- each file require it's own tag.
@@ -192,7 +208,7 @@ Both local.list and local.exclude.
https://docs.microsoft.com/en-us/windows/win32/msi/component-table?redirectedfrom=MSDN
How To: Check for .NET Framework Versions
https://wixtoolset.org/documentation/manual/v3/howtos/redistributables_and_install_checks/check_for_dotnet.html
- - TODO how to unpack zip file to target dir?
+ - WONTFIX how to unpack zip file to target dir?
I don't want to create a Component for every file there.
windows installer - Wix custom action to unzip a file - Stack Overflow
@@ -256,7 +272,40 @@ Both local.list and local.exclude.
&"C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" .\mbackup.wixobj
it works.
mbackup.msi file is created.
- -
+ - the mbackup.exe can't run without all those dlls.
+ dotnet publish -c Release -r win10-x64 --nologo
+ maybe I should build a exe that requires dotnet core 3 to run.
+ I don't want to create a big msi.
+ try this:
+ dotnet publish -c Release --nologo
+ and update wix xml files.
+
+ need to add all files in bin\Release\netcoreapp3.0\publish\ dir.
+ use heat to create another wxs file.
+ - heat can't add some dll.
+ "C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe" dir bin\Release\netcoreapp3.0\publish -cg MbackupHeatGenerated -dr MBACKUP_PROGRAM_FILES -var var.MbackupPublishDir -gg -nologo -out mbackup-files.wxs -sw5150
+ heat.exe : warning HEAT5151 : Could not harvest data from a file that was expected to be an assembly: D:\sylecn_docs\projects\mbackup-for-windows\bin\Release\netcoreapp3.0\publish\Argu.dll. If this file is not an assembly you can ignore this warning. Otherwise, this error detail may be helpful to diagnose the failure: 未能加载文件或程序集“FSharp.Core, Version=4.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到
+ 指定的文件。
+ heat.exe : warning HEAT5151 : Could not harvest data from a file that was expected to be an assembly: D:\sylecn_docs\projects\mbackup-for-windows\bin\Release\netcoreapp3.0\publish\mbackup.dll. If this file is not an assembly
+ you can ignore this warning. Otherwise, this error detail may be helpful to diagnose the failure: 未能加载文件或程序集“System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统
+ 找不到指定的文件。
+
+ .net - Wix Toolkit: Heat balking about DLL's - Stack Overflow
+ https://stackoverflow.com/questions/43992433/wix-toolkit-heat-balking-about-dlls
+ com - Cannot register DLL using WiX - Stack Overflow
+ https://stackoverflow.com/questions/12463256/cannot-register-dll-using-wix
+ - TODO dup file?
+
+
+
+
+ why there are duplicated dll in publish dir? check publish doc.
+ this is the only duplicated file. I will ignore it for now.
+ - DONE ssh.exe path escape issue.
+ &"C:\Program Files\mbackup\rsync-w64\usr\bin\rsync.exe" -h --stats -togr --delete --delete-excluded --ignore-missing-args --files-from=/cygdrive/c/Users/sylecn/AppData/Local/mbackup/mbackup.list --exclude-from=/cygdrive/c/ProgramData/mbackup/mbackup-default.exclude --log-file=/cygdrive/c/Users/sylecn/AppData/Local/mbackup/mbackup.log -e "/cygdrive/c/Program Files/mbackup/rsync-w64/usr/bin/ssh.exe -F /cygdrive/c/Users/sylecn/.ssh/config -i /cygdrive/c/Users/sylecn/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --remote-option=--log-file=/var/log/mbackup/B75I3.log --chown=sylecn:sylecn / root@sylecn01.emacsos.com:/data/backup/PC-backup/B75I3/
+ rsync: Failed to exec /cygdrive/c/Program: No such file or directory (2)
+
+ &"C:\Program Files\mbackup\rsync-w64\usr\bin\rsync.exe" -h --stats -togr --delete --delete-excluded --ignore-missing-args --files-from=/cygdrive/c/Users/sylecn/AppData/Local/mbackup/mbackup.list --exclude-from=/cygdrive/c/ProgramData/mbackup/mbackup-default.exclude --log-file=/cygdrive/c/Users/sylecn/AppData/Local/mbackup/mbackup.log -e "'/cygdrive/c/Program Files/mbackup/rsync-w64/usr/bin/ssh.exe' -F /cygdrive/c/Users/sylecn/.ssh/config -i /cygdrive/c/Users/sylecn/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --remote-option=--log-file=/var/log/mbackup/B75I3.log --chown=sylecn:sylecn / root@sylecn01.emacsos.com:/data/backup/PC-backup/B75I3/
** 2019-11-12 make code work in a specific dir. then create an installer.
- bundle dotnet core 3 with installer.
diff --git a/rsync-mingw64.wxs b/rsync-mingw64.wxs
deleted file mode 100644
index f132d2eb52ea3ea080cd215786527eb67d3fe8af..0000000000000000000000000000000000000000
--- a/rsync-mingw64.wxs
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-