From a00a1c3c2ca2e3176162c5a821f1768515c9a206 Mon Sep 17 00:00:00 2001 From: Yuanle Song Date: Fri, 15 Nov 2019 02:34:11 +0800 Subject: [PATCH] mbackup.msi works on dev node. - renmaed mbackup-for-windows.fsproj to mbackup.fsproj this file name is the project name. now exe is named mbackup.exe - use framework dependent release. - include rsync-mingw in one msi - use installed rsync and ssh path in Program.fs --- .gitignore | 2 +- Makefile | 47 ++++++++++------- Program.fs | 26 ++++----- mbackup-tests/mbackup-tests.fsproj | 2 +- mbackup-for-windows.fsproj => mbackup.fsproj | 1 + mbackup.wxs | 15 ++---- operational | 55 ++++++++++++++++++-- rsync-mingw64.wxs | 15 ------ 8 files changed, 101 insertions(+), 62 deletions(-) rename mbackup-for-windows.fsproj => mbackup.fsproj (89%) delete mode 100644 rsync-mingw64.wxs diff --git a/.gitignore b/.gitignore index dc7b3ca..ee654e1 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 a045810..ff461be 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 dd10a5f..8830fc3 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 f3cd826..27274dd 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 213547f..7ac4a9e 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 6436e5f..ea786d9 100644 --- a/mbackup.wxs +++ b/mbackup.wxs @@ -5,20 +5,14 @@ - + - + - - - - - - - + @@ -35,7 +29,8 @@ - + + diff --git a/operational b/operational index 0b8f10b..87647fc 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 f132d2e..0000000 --- a/rsync-mingw64.wxs +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - -- GitLab