diff --git a/.gitignore b/.gitignore
index ff4880b230899f52bc521a1f1db1e85b58f658b6..dc7b3ca10d89e7fee9cfa4eba43096fe6c454f08 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
obj/
bin/
.ionide/
+*.wixobj
+*.wixpdb
+*.msi
+rsync-mingw64-files.wxs
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a045810d0e710398c0516709c9808df6026d597b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,29 @@
+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
+all: test release dist
+dist: mbackup.msi rsync-mingw64.msi
+release:
+ dotnet publish -c Release -r win10-x64 --nologo
+test:
+ dotnet test mbackup-tests
+check: test
+build:
+ dotnet build
+clean:
+ dotnet clean
+ del *.wixobj *.msi
+%.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
diff --git a/mbackup-for-windows.fsproj b/mbackup-for-windows.fsproj
index 717b65461d3fab2d4c195aec9aa9ffa66224c4a8..213547fcb14078475c8def57098ebdcdf5838792 100644
--- a/mbackup-for-windows.fsproj
+++ b/mbackup-for-windows.fsproj
@@ -3,6 +3,7 @@
Exe
netcoreapp3.0
+ win10-x64
Mbackup
diff --git a/mbackup.wxs b/mbackup.wxs
new file mode 100644
index 0000000000000000000000000000000000000000..6436e5f32a0ee892255f2aef20944171765e0c59
--- /dev/null
+++ b/mbackup.wxs
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/operational b/operational
index 0aa7687d86d50284cde47133bfb8eae3c0e80f5e..0b8f10be74f2f0c641251f7509295a7528e0ede7 100644
--- a/operational
+++ b/operational
@@ -64,6 +64,10 @@ dotnet run -- -i
https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tostring?view=netframework-4.8
Standard Date and Time Format Strings | Microsoft Docs
https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings?view=netframework-4.8
+ The Option type | F# for fun and profit
+ https://fsharpforfunandprofit.com/posts/the-option-type/
+ Pattern Matching - F# | Microsoft Docs
+ https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
- FSharpLint
http://fsprojects.github.io/FSharpLint/
http://fsprojects.github.io/FSharpLint/index.html
@@ -84,7 +88,16 @@ C:\Program Files\mbackup\rsync-w64\usr\bin\ssh.exe
C:\ProgramData\mbackup\mbackup-default.exclude
C:\ProgramData\mbackup\mbackup-default.list
C:\ProgramData\mbackup\user-default.list
-C:\ProgramData\mbackup\mbackup.ini
+C:\ProgramData\mbackup\mbackup.txt
+
+- optional user configs
+ like /etc/mbackup/ in linux
+ C:\ProgramData\mbackup\local.list
+ C:\ProgramData\mbackup\local.exclude
+
+ like ~/.mbackup/ in linux
+ /mbackup/local.list
+ /mbackup/local.exclude
** 2019-11-14 notes :development:
- Argu optional param support.
@@ -94,6 +107,16 @@ C:\ProgramData\mbackup\mbackup.ini
results.TryGetResult Target
or
results.GetResult(Target, defaultValue = xxx)
+- WiX wxs file
+
+ Platform="x64" has the same meaning as candle -arch x64.
+
+- Wix for creating installer for 64bit app, you need to add in attribute
+ Win64="yes"
+
+ 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
-
* later :entry:
@@ -103,105 +126,162 @@ it can only support open a namespace.
using the vscode Ionide-fsharp extension.
* current :entry:
**
-** 2019-11-13 next todos
-- DONE fix TODOs in F# code
-- DONE add rsync command and arguments for running in windows.
- i.e. -e etc.
+** TODO 2019-11-15 additionally support /mbackup/local.list file.
+This file is easier to open and backup.
+
+no. programdata should be good enough.
+but this is per user extra config file.
+each user could have their own local file to backup.
+one user don't want to manage all other user's local backup list.
+
+yes. I should support this.
+
+Both local.list and local.exclude.
+
+** 2019-11-14 learn how to create an msi installer.
+- WiX Toolset
+ https://wixtoolset.org/
+ c# - How to create MSI installer for ASP.NET Core application using Wix Toolset - Stack Overflow
+ https://stackoverflow.com/questions/46878752/how-to-create-msi-installer-for-asp-net-core-application-using-wix-toolset
+
+ Windows Installer XML (WiX)
+ https://wixtoolset.org/documentation/manual/v3/main/
+
+- Introducing dotGet: an installer for .NET Core CLI apps
+ https://medium.com/@tonerdo/introducing-dotget-an-installer-for-net-core-cli-apps-9ba79ac7cd89
+
+ requires nuget. then it can install your dotnet core console project.
+ this is not what I need here.
+- Packaging a self-contained .NET Core app for Windows Installer
+ https://nblumhardt.com/2017/04/netcore-msi/
+
+ This is the first time I’ve tried packaging a .NET Core app for the Windows
+ Installer, so I thought I’d write these brief notes to help anyone else
+ interested in taking the same path.
+
+- should I include rsync-mingw64 in the same msi file?
+ distributing it alone is not very useful, since people can just use msys2 or cygwin.
+
+ If I include it in the same msi, I don't need to use wix bundle, and I can install rsync to the same dir as mbackup.
+ it seems cleaner this way. Just like a VPN client bundle openvpn or a python program bundle python.
+ yes. include it in the same msi and install in a sub dir.
+- try Wix.
+ - install wix.
+ requires .net 3.5 windows feature.
+ - Building Installation Package Bundles
+ https://wixtoolset.org/documentation/manual/v3/bundle/
+ - How To Guides
+ 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
+
+ build mbackup binaries
+ dotnet publish -c Release
- --stats -togr --chown=sylecn:sylecn --exclude-from=/cygdrive/d/sylecn_docs/texts/configs/rsync-exclude
- --files-from=/cygdrive/d/sylecn_docs/texts/configs/rsync-file-list
- --log-file=/cygdrive/d/sylecn_docs/rsync-b75i3.log
- -e ".\ssh.exe -F c:/users/sylecn/.ssh/config -i c:/Users/sylecn/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
- / sheni:/data/backup/server-backup/b75i3/
+- problems
+ - each file require it's own tag.
+ rsync mingw have many files. I seems I need to generate an installer for
+ rsync for windows.
+ - search: wix only install file if it does not exist
+ windows installer - Copy if not exist in WiX - Stack Overflow
+ https://stackoverflow.com/questions/1912037/copy-if-not-exist-in-wix
+ installer - What is the wix 'KeyPath' attribute? - Stack Overflow
+ https://stackoverflow.com/questions/2003043/what-is-the-wix-keypath-attribute/2003366#2003366
+ Component Table - Win32 apps | Microsoft Docs
+ 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?
+ I don't want to create a Component for every file there.
+
+ windows installer - Wix custom action to unzip a file - Stack Overflow
+ https://stackoverflow.com/questions/47691477/wix-custom-action-to-unzip-a-file
+
+ the suggestion is to include the files in msi.
+ or unzip the files at app runtime.
+
+ I will try create a msi file for mingw64 rsync.
+ then use wix bundle to install it as dependency.
+
+ - search: wix install all files in a folder
+
+ - Include all Files in Bin folder in Wix installer - Stack Overflow
+ https://stackoverflow.com/questions/36756311/include-all-files-in-bin-folder-in-wix-installer
+
+ create rsync-mingw64-files.wxs
+ &"C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe" dir "D:\downloads\apps\rsync-w64" -cg RsyncHeatGenerated -dr ProgramFiles64Folder -var var.RsyncSourceDir -gg -nologo -out rsync-mingw64-files.wxs -sw5150
+
+ compile and build rsync-mingw64.msi
+ &"C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" -dRsyncSourceDir=D:\downloads\apps\rsync-w64\ .\rsync-mingw64.wxs .\rsync-mingw64-files.wxs
+ &"C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" .\rsync-mingw64.wixobj .\rsync-mingw64-files.wixobj -o rsync-mingw64.msi
+
+ build is getting complex. I need make and Makefile.
+ - problems
+ - how to pass in preprocessor variable?
+ WiX undefined preprocessor variable - Stack Overflow
+ https://stackoverflow.com/questions/2063630/wix-undefined-preprocessor-variable
+ To pass values for preprocessor variables like $(var.MyProject.TargetDir), use options like -dMyProject.TargetDir=c:\foo.
+ - why rsync-mingw64 is installed to C:\Program Files (x86)\rsync-w64? I expect C:\Program Files\rsync-w64\
+ wix-users - 64 Bit program files folder
+ http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/64-Bit-program-files-folder-td5948080.html
+ - INVALID make pattern rule doesn't work in windows
+ it works. it is because my source file is missing.
+ - why mbackup.exe is 32 bit component?
+ try this:
+ dotnet publish -c Release -r win10-x64
+ still same error.
+ D:\sylecn_docs\projects\mbackup-for-windows\mbackup.wxs(16) : error LGHT0204 : ICE80: This 32BitComponent mbackup.exe uses 64BitDirectory APPLICATIONROOTDIRECTORY
+ search: dotnet core how to build x64 exe file
+ dotnet is building x64 exe file. it's WIX issue.
+ need to add Win64="yes" in attribute.
+
+ - DONE how to run wix to create msi file?
+ two command line tool
+ light
+ candle
+ it's not added in PATH.
+ C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe
+ C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe
+
+ There is offline doc.
+ C:\Program Files (x86)\WiX Toolset v3.11\doc\WiX.chm
+ C:\Program Files (x86)\WiX Toolset v3.11\doc\msi.chm
+
+ do read the WiX Tutorial.
+ https://www.firegiant.com/wix/tutorial/
+ https://www.firegiant.com/wix/tutorial/getting-started/
+
+ &"C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" .\mbackup.wxs
+ &"C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" .\mbackup.wixobj
+ it works.
+ mbackup.msi file is created.
+ -
-- DONE test param parsing is working.
- command line param > env var > mbackup default value.
- support --node-name param.
-- test run in console and scheduled task.
- run in console works.
- try run in scheduled task.
+** 2019-11-12 make code work in a specific dir. then create an installer.
+- bundle dotnet core 3 with installer.
+- install binary files to %programfiles%
+- install mbackup config files to %programdata%
+- install scheduled tasks as admin
SCHTASKS /Create /?
# run mbackup 15m after user logon.
- SCHTASKS /Create /U /SC ONLOGON /TN mbackup-logon /TR "\"\" \"args\"" /DELAY 15:00
+ SCHTASKS /Create /NP /SC ONLOGON /TN mbackup-logon /TR "\"\" \"args\"" /DELAY 15:00
# run mbackup at 10am and 4pm.
- SCHTASKS /Create /U /SC DAILY /TN mbackup-morning /TR "\"\" \"args\"" /ST 10:00 /ET 13:00 /K
- SCHTASKS /Create /U /SC DAILY /TN mbackup-afternoon /TR "\"\" \"args\"" /ST 16:00 /ET 19:00 /K
+ SCHTASKS /Create /NP /SC DAILY /TN mbackup-morning /TR "\"\" \"args\"" /ST 10:00 /ET 13:00 /K
+ SCHTASKS /Create /NP /SC DAILY /TN mbackup-afternoon /TR "\"\" \"args\"" /ST 16:00 /ET 19:00 /K
# debug purpose, one time only
- SCHTASKS /Create /U /SC ONCE /TN mbackup-afternoon /TR "\"\" \"args\"" /ST 12:03
-
- - problems
- - how many scheduled task to run on a multi-user PC?
- each user have its own user-default.list expansion.
- should I iter over all users on PC?
- I think only current user can get it's profile dir and special dirs.
- - maybe config mbackup to run after user logon. with 15minute delay.
- always run as current user.
- - how to not require any param when running mbackup.exe?
- put TARGET and other option in a config file?
- define system level TARGET env variable.
-
- use config file is easier for user to edit and making the change effective.
- userConfigDir / mbackup.conf
-
- search: F# read config file
- FSharp.Configuration
- http://fsprojects.github.io/FSharp.Configuration/
- - FSharp.Configuration missing reference to System.Runtime.Caching
- search: how to reference System.Runtime.Caching for dotnet core project
- https://www.nuget.org/packages/System.Runtime.Caching/
- dotnet add package System.Runtime.Caching --version 4.6.0
- should I add 4.0.0? Can I use a higher version?
-
- still not compatible.
- search: use FSharp.Configuration with dotnet core 3
- - give up on FSharp.Configuration.
- - try this:
- FsConfig
- https://www.demystifyfp.com/FsConfig/
- AppSettings is only supported in V0.0.6 or below.
- try F# AppSettings directly.
- If nothing is easy to use, write my own parser.
- Support similar config format as python wells lib.
- - ConfigurationManager.AppSettings Property (System.Configuration) | Microsoft Docs
- https://docs.microsoft.com/en-us/dotnet/api/system.configuration.configurationmanager.appsettings?view=netframework-4.8
- where should I save the App.config xml file?
- search: what is app.config
- App.Config: Basics and Best Practices - SubMain Blog
- https://blog.submain.com/app-config-basics-best-practices/
- What is App.config in C#.NET? How to use it? - Stack Overflow
- https://stackoverflow.com/questions/13043530/what-is-app-config-in-c-net-how-to-use-it
- Okay. This is not what I want.
- This is for application configuration (rarely change), not for user configuration (can change any time).
- dotnet will create .exe.config from your App.config file.
- - how to use multiple files in F# dotnet core project?
- search: f# module and namespace
- search: f# module
- Modules - F# | Microsoft Docs
- https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/modules
+ SCHTASKS /Create /NP /SC ONCE /TN mbackup-test /TR "\"\" \"args\"" /ST 19:18
-- create an installer. The installer should add scheduled task on install and
- delete scheduled task on removal.
+ In admin powershell,
+ SCHTASKS /Create /NP /SC ONCE /TN mbackup-test /TR $mbackupexe /ST 19:32
+ /NP option requires admin privilledge.
+ it works.
-- problems
- - how to write unit test in F#?
- Unit testing F# in .NET Core with dotnet test and NUnit - .NET Core | Microsoft Docs
- https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-fsharp-with-nunit
- mkdir mbackup-tests
- cd mbackup-tests
- dotnet new nunit -lang F#
- //wait.
- dotnet test
+ to delete it,
+ schtasks /delete /tn mbackup-test
- dotnet add reference ../mbackup-for-windows.fsproj
- dotnet build # this will build both ref project and test project.
- dotnet test
- - how to support short option names?
- --dry-run -n
- -
-** 2019-11-12 make code work in a specific dir. then create an installer.
-- install to %programfiles%
- config is installed/saved to %appdata% roaming dir.
- problems
- config should be system wide. %appdata% is per-user dir.
@@ -307,6 +387,126 @@ using the vscode Ionide-fsharp extension.
it contains hostname.
-
* done :entry:
+** 2019-11-13 next todos; scheduled task command line.
+- DONE fix TODOs in F# code
+- DONE add rsync command and arguments for running in windows.
+ i.e. -e etc.
+
+ --stats -togr --chown=sylecn:sylecn --exclude-from=/cygdrive/d/sylecn_docs/texts/configs/rsync-exclude
+ --files-from=/cygdrive/d/sylecn_docs/texts/configs/rsync-file-list
+ --log-file=/cygdrive/d/sylecn_docs/rsync-b75i3.log
+ -e ".\ssh.exe -F c:/users/sylecn/.ssh/config -i c:/Users/sylecn/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ / sheni:/data/backup/server-backup/b75i3/
+
+- DONE test param parsing is working.
+ command line param > env var > mbackup default value.
+ support --node-name param.
+- DONE test run in console and scheduled task.
+ run in console works.
+ try run in scheduled task.
+
+ SCHTASKS /Create /?
+ # run mbackup 15m after user logon.
+ SCHTASKS /Create /U /SC ONLOGON /TN mbackup-logon /TR "\"\" \"args\"" /DELAY 15:00
+ # run mbackup at 10am and 4pm.
+ SCHTASKS /Create /U /SC DAILY /TN mbackup-morning /TR "\"\" \"args\"" /ST 10:00 /ET 13:00 /K
+ SCHTASKS /Create /U /SC DAILY /TN mbackup-afternoon /TR "\"\" \"args\"" /ST 16:00 /ET 19:00 /K
+
+ # debug purpose, one time only
+ SCHTASKS /Create /SC ONCE /TN mbackup-test /TR "\"\" \"args\"" /ST 19:18
+
+ in powershell,
+ $mbackupexe = "D:\sylecn_docs\projects\mbackup-for-windows\bin\Debug\netcoreapp3.0\mbackup-for-windows.exe"
+ SCHTASKS /Create /SC ONCE /TN mbackup-test /TR $mbackupexe /ST 19:21
+ default run as user is current user.
+
+ in admin powershell,
+ SCHTASKS /Create /SC ONCE /TN mbackup-test /TR $mbackupexe /ST 19:32 /NP
+ /NP option requires admin privilledge.
+ it works.
+
+ to delete it,
+ schtasks /delete /tn mbackup-test
+
+ - problems
+ - how many scheduled task to run on a multi-user PC?
+ each user have its own user-default.list expansion.
+ should I iter over all users on PC?
+ I think only current user can get it's profile dir and special dirs.
+ - maybe config mbackup to run after user logon. with 15minute delay.
+ always run as current user.
+ - how to not require any param when running mbackup.exe?
+ put TARGET and other option in a config file?
+ define system level TARGET env variable.
+
+ use config file is easier for user to edit and making the change effective.
+ userConfigDir / mbackup.conf
+
+ search: F# read config file
+ FSharp.Configuration
+ http://fsprojects.github.io/FSharp.Configuration/
+ - FSharp.Configuration missing reference to System.Runtime.Caching
+ search: how to reference System.Runtime.Caching for dotnet core project
+ https://www.nuget.org/packages/System.Runtime.Caching/
+ dotnet add package System.Runtime.Caching --version 4.6.0
+ should I add 4.0.0? Can I use a higher version?
+
+ still not compatible.
+ search: use FSharp.Configuration with dotnet core 3
+ - give up on FSharp.Configuration.
+ - try this:
+ FsConfig
+ https://www.demystifyfp.com/FsConfig/
+ AppSettings is only supported in V0.0.6 or below.
+ try F# AppSettings directly.
+ If nothing is easy to use, write my own parser.
+ Support similar config format as python wells lib.
+ - ConfigurationManager.AppSettings Property (System.Configuration) | Microsoft Docs
+ https://docs.microsoft.com/en-us/dotnet/api/system.configuration.configurationmanager.appsettings?view=netframework-4.8
+ where should I save the App.config xml file?
+ search: what is app.config
+ App.Config: Basics and Best Practices - SubMain Blog
+ https://blog.submain.com/app-config-basics-best-practices/
+ What is App.config in C#.NET? How to use it? - Stack Overflow
+ https://stackoverflow.com/questions/13043530/what-is-app-config-in-c-net-how-to-use-it
+ Okay. This is not what I want.
+ This is for application configuration (rarely change), not for user configuration (can change any time).
+ dotnet will create .exe.config from your App.config file.
+ - how to use multiple files in F# dotnet core project?
+ search: f# module and namespace
+ search: f# module
+ Modules - F# | Microsoft Docs
+ https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/modules
+ - SCHTASKS /Create /SC ONCE /TN mbackup-test /TR $mbackupexe /ST 19:21
+ this runs, it will show a console window. how to not show console window?
+
+ search: schedule tasks do not show console window
+
+ In the “General” tab, under the “Security options” section, select the Run
+ whether user is logged on or not option. (This is the option that will make
+ the command window not to appear when the task runs automatically.)
+
+ try /NP option.
+
+- create an installer. The installer should add scheduled task on install and
+ delete scheduled task on removal.
+
+- problems
+ - how to write unit test in F#?
+ Unit testing F# in .NET Core with dotnet test and NUnit - .NET Core | Microsoft Docs
+ https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-fsharp-with-nunit
+ mkdir mbackup-tests
+ cd mbackup-tests
+ dotnet new nunit -lang F#
+ //wait.
+ dotnet test
+
+ dotnet add reference ../mbackup-for-windows.fsproj
+ dotnet build # this will build both ref project and test project.
+ dotnet test
+ - how to support short option names?
+ --dry-run -n
+ -
** 2019-11-14 support mbackup.txt config.
config file will have wells config file format.
empty lines and comment lines are ignored.
diff --git a/rsync-mingw64.wxs b/rsync-mingw64.wxs
new file mode 100644
index 0000000000000000000000000000000000000000..f132d2eb52ea3ea080cd215786527eb67d3fe8af
--- /dev/null
+++ b/rsync-mingw64.wxs
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+