├── .gitattributes
├── .gitignore
├── Doc
├── CoreClassDiagram.drawio
└── CoreClassDiagram.drawio.svg
├── LICENSE
├── README.md
├── SimpleFileBackup.Core
├── BackupWriterFactory.cs
├── Data
│ ├── BackupArguments.cs
│ └── BackupMetadataInfo.cs
├── IBackupWriter.cs
├── Progress
│ ├── BackupProgress.cs
│ ├── BackupProgressInfo.cs
│ └── IBackupProgress.cs
├── SimpleFileBackup.Core.csproj
├── Util
│ ├── BackupProgressHelper.cs
│ ├── DirectoryHelper.cs
│ └── ZipArchiveExtensions.cs
└── Writers
│ ├── BaseBackupWriter.cs
│ ├── CopyFileBackupWriter.cs
│ ├── NamedBackupWriter.cs
│ ├── SubfolderCopyBackupWriter.cs
│ └── ZipBackupWriter.cs
├── SimpleFileBackup.Windows
├── App.config
├── BackupMode.cs
├── FormAbout.Designer.cs
├── FormAbout.cs
├── FormAbout.resx
├── FormMain.Designer.cs
├── FormMain.cs
├── FormMain.resx
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ ├── Settings.settings
│ └── app.manifest
├── Resources
│ └── about.html
├── SFB.ico
├── SimpleFileBackup.Windows.csproj
└── packages.config
└── SimpleFileBackup.sln
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
262 |
263 | # drawio temporary files
264 | *.bkp
--------------------------------------------------------------------------------
/Doc/CoreClassDiagram.drawio:
--------------------------------------------------------------------------------
1 | 7Vxbd5u4Fv41Xqvz4Cxuvj36krSZpmfSNj2ZPJ2lgGxzCsgDIrH760dC4iIksF2DnenwklgbIZC+vT/tvSXRM+f+9n0INutPyIFez9Ccbc9c9AxDH45M8o9Kdlyi6WMmWYWuw2W54Kv7A6YVuTR2HRgJFTFCHnY3otBGQQBtLMhAGKJXsdoSeeJTN2AFJcFXG3iy9NF18JpJx8Yol3+A7mqdPlkfTtgVH6SVeU+iNXDQa0FkXvfMeYgQZr/87Rx6dPTScXm83T16d9+H73//HP0Fvs0+Pvznv33W2M0xt2RdCGGAf7rp+8mL/7jTnOn2i3396ffN0n/8oz/gbUd4lw4YdMj48SIK8RqtUAC861w6C1EcOJA2q5FSXucOoQ0R6kT4f4jxjisDiDEiojX2PX6VdCPc/cnvTwpPtHA1SIuLbfHiYpeVnClVCVK0PRBFrs2EN66XN53q4JCUDhy4dBBQHNqwZrS4ImAQriCuqacbrCIdyoIWclzeQ+RD0i1SIYQewO6LqKqAa/wqq8dvJX0Hu0KFDXIDHBVavqcCUoFbr6ENWYvcdo1BSUP21eemwOuTH+wN0lKhK7ko0bpjNNBiz3wBXszHIY6IcpHbAqVu3oFnwlGCPgHPXQVUKQjMMCSCFxhil3DAlF/wXcdhqgsj9wd4TtqjGsWHkDQ+mPUGC6XK1BoOfRLc9hRMxp8ikIUAPr9LuzInnHKOUwcJv74+EPDTTbEFtFxGRG9FSJsBcdDRSPM0MnojLGKIrKDvYxGxvj62zsAiQ4lF7BACDKO3zCGD5jhkOBS5u280RCmlZlOKaZ9TNAnRGbC/x5tpuIp9yFVWQDZ6dX0PBBSjJQpwyj4UXXvtes4d2KGYAhJh0lJamq1R6P4g9UGqCuRyiLn5G9T+l4QY5shDRC0WAUoekN/0lTbGVSFRDXifAq+XRJ/AVqh4ByLMBTbyPLCJ3OfslX1CD24wQxgjn1c6jocktapUH1MTLXbEW3jNHWbd4nXWRWdZs6oVStCHY8HXJfB7Bum+dhtsYkx4WmHXpK84AS9E32EJLQWAqb17cIkV1o7pHDSLNsB2g9VdUmdh5ZIvfBCoCJF7l14ynawJR8AgmdswwJUcMSNjOafzFGELY07Kel5OCGRDZsM5CkhfgJtADYmmvEKqLYeSi3awEmTe3mGgp/Uax9yowPyPGBPQF27YYd405gPjwpibVZiTPryGLobXWzfCZPA76BuGfjQ+H/RP8eebj/0H/09nivzr2csTXLv9C2ce8ijhSQgS1CFDwxGAdWAEkAJy4RDAHIleoCnkBaTqI1OvqX5yAKDUJnnyeFP+f50FnO7+97Uryxy3EgCkNJH5/6UW2vP/5bwQ8/8/QQwcwra3wRIdEwLsBZjNAadFCr9UWGBY1pUpatVgIs0axlAVGZjjljyGgaQWzGOgQQFFonMS93gK1sFqUB0YKDFvzUmc1EA+Jx4B7iBvGHJFXHBeyHU5+yOa+dfY71BvGHVFSHBe1OUkroSx5ybYMYzTBV39pwDOHDqO6EMSQ/R1CXVTRt1UIOxRp/IeRS52EW0/ZHUV/uElwM1ydfvQbWviHlVZdIj8Umb3Xan8W2fqTWuDfnGGl1O8DPVHmvYJb4CNEX9M5+C35eAPJ2UHP1sLKCqGflYPP1VNiSn2rf90pKC2sJM8fRX27ZGCKrrrPICG4FV59Sp4WzNslX9HDXuepOoY8V9dvbu66ib8xsEfHsjr7dl2lQPYod8++uOLM3tVEqdDv330ld7+WeE3VBP70EsmRwHs4V8x3U/NveCeOdU226zYT7CbWomIakWfYz3NfP68BfJrxf8nz3ELAuBTHfDk0i1tZglsmInFW4QWyUi45ac8h5IkFdwW45tCG8/lO4hsU5atQzpM6e76tI96dXf3DCu5SkdW/MsGVtUmtdTrLbRjDFkv3v1W97bHYMrMdHrMs+cgsInSAepmvZX3oOZuaBzj+xCtSKgXXfLlDnuVEtWqybLEqAVaXCZbZlkozpSTUA0r3wDf9SgBfYDeC6St9oQF17aC2kFpsdowFImviSqiTRmxcfaz5Gy2CI6EQ7eV8WfRL+UzhqYEvqkE32wN/Kq9jAcsZ3eej9qOTsloKOFvzfGx5GRWP8M+Nf93nc/bOPKKZMeZkZc3sBTtPsNepoFOGxrXBsXS5pm1oSr3tVcbmGM5tZmTyXw48SZWi3l0ne40rjuqldPWlCc2Yvthc3vTX063H9zdduH/L9sAc+atslsXs52yxoAXnwqX8o2ytJAfreP7a7PNtuxI3mjfmbzj/MHiBlvliPFc494Ntmle4sIbbHWtfASHH+eq2mIr3WBqo5KanbbJVjmqil05/KzuEtH8xCYLZ8h4UVtV6u3ZN9/W2VQj53e1IVejU0/bmeIB3mzFpNHdtl8efsQPk5u73efBav1eH33cfltfiGJ+7iBuyVjbpQ3laFVoxInw6/pQNGrDKgWl7MX4bbkSHE03+kCMkvVx/ZnefTecTDfKUVbQDaOVC27qP5gvRK2strm6Tf2E1sXt93ojNGOYQqOTFjimzrp++TWAU5O9TfVQufyQpRyTNYDbPANZHAJlfKHuvWr14qARaXpF4/h8uSrWqlrFaT2Bf9iDf710/WQsznlpYFUMtnRLDrZGbQVb48t4Qid/yuTZQzR5X/CfNMF/SpB2QLRO3vN4SPcfajRk76luHmgu5joJ73Q5/TLRdfq7APf+4LqkJC0G17U7ef4p0bU1mggUU4qVpfoDY1xXv6XYWl4oeFMnWGttp5EjrIZplg+bNuPuWqIPbbTg71ZHiTWrvt0JVnE1WKFFh3FWpVbpWvopm3JEXfzswUiRyx01sAlWHdQqgiDqjN7DkOK6oFn4f3cKf48aHJOQqfm0jQr0JhL4yteTuZ1HIDvC75QUoPNt08HeMOyqr9s0BDsp5h9+ZfNF/v1c8/pv
--------------------------------------------------------------------------------
/Doc/CoreClassDiagram.drawio.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Marcel Salvenmoser
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SimpleFileBackup
2 | Simple C# program for copying multiple files to multiple locations at once
3 |
4 | 
5 |
6 | ## Download
7 | https://github.com/malthee/SimpleFileBackup/releases
8 |
9 | # SimpleFileBackup.Windows
10 | ## General
11 | Select files or folders by pressing the Select buttons on the right. You can select multiple files or folders at once. After pressing OK the file locations will be saved in the drop down list. You can also add files by typing the path in the textbox and pressing enter. If you made a wrong selection, you can delete single items by selecting them in the drop down list and pressing "Delete Item". You can clear the list by pressing "Clear List".
12 |
13 | Backup Destinations can be selected through the same process. Every file or folder in "Files to Backup" will be backed up to every "Backup Destination".
14 |
15 | ## Settings
16 |
17 | ### Override idenetical files in directory
18 | If you want to replace your old files with the new files enable the "Override identical files in directory" option. This way, if a file called 123.jpg is already in the directory, it will be replaced. Same goes for ZIP files.
19 |
20 | ### Put files in given directory
21 | Copies the files into the selected directories.
22 |
23 | ### Create a subfolder in directory
24 | Creates a subfolder in every given directory.
25 |
26 | ### Create a .zip file in directory
27 | Create a .zip from the given files and copy it to every listed directory.
28 |
29 | ### Name Folder/.zip
30 | Only works when "Create a subfolder in directory" or "Create a .zip file in directory" is selected.
31 | You can name your folder or .zip file with a maximum of 20 characters. The characters have to be compatible with the windows filesystem.
32 |
33 | ### Add date to Folder/.zip name
34 | Adds your local date to the folder/.zip name in the format name_10-10-2010.
35 |
36 | ### Save Defaults
37 | Saves your file/backup locations and settings to keep them for the next program start.
38 |
39 | ### Save Custom File Paths & Save Custom Backup Paths
40 | Saves your file/backup locations in a text file you can choose the location of.
41 |
42 | ### Open File Paths & Open Backup Paths
43 | You can open a text file that contains paths to files or directories. These paths will be inserted into the drop down list.
44 |
45 | ## Common problems
46 | 1. If you have windows security folder protection enabled, you might get errors like "File cannot be found" or "Permissions error". You can fix this by navigating to the protection history and pressing allow on the blocked entries.
47 |
48 | | Navigate to protection history | Press actions -> allow |
49 | |--|--|
50 | |  |  |
51 |
52 | # SimpleFileBackup.Core
53 | Core is a `.NET Framework 2.0` library for persisting one or more files or folders in one or more other locations in any recoverable format. As an example it can be used to copy files and folders from different drive locations to multiple backup drives at once.
54 |
55 | An overview of the components can be seen in the following diagram:
56 | 
57 |
58 | ## Public interface
59 | * `BackupWriterFactory`: provides implementations of `IBackupWriter`
60 | * `IBackupWriter`: contract every backup writer has to implement. Used to start a backup with or without cancellation and progress reporting.
61 | * `BackupArguments`: used to create a `BackupWriterFactory`. Contains input and output information.
62 | * `BackupMetadataInfo`: can be created with `BackupArguments`. Contains information about file size and count which is handled.
63 | * `IBackupProgress` and `BackupProgress`: extended Interface with `BackupMetadataInfo` for progress calculation and adapter implementation of `Progress`.
64 | * `BackupProgressInfo`: provides the user with information how far the backup is in percent and how many bytes have been written to output locations.
65 |
66 | ## Contribute
67 | Feature requests and bugs must have a ticket and description before any pull request is accepted. There is also a Project board on GitHub in which some current feature requests are prioritized and documented.
68 | Otherwise any contributers are welcome!
69 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/BackupWriterFactory.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using SimpleFileBackup.Core.Writers;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 |
7 | namespace SimpleFileBackup.Core
8 | {
9 | ///
10 | /// Factory for implementations.
11 | ///
12 | public class BackupWriterFactory
13 | {
14 | public const string DefaultDateFormat = "dd-MM-yyyy";
15 |
16 | ///
17 | /// Arguments used to create s with.
18 | ///
19 | public BackupArguments BackupArguments { get; set; }
20 |
21 | public BackupWriterFactory(BackupArguments args)
22 | {
23 | BackupArguments = args;
24 | }
25 |
26 | public IBackupWriter CreateCopyFileBackupWriter()
27 | {
28 | return new CopyFileBackupWriter(BackupArguments);
29 | }
30 |
31 | public IBackupWriter CreateSubfolderCopyBackupWriter(string subfolderName)
32 | {
33 | return new SubfolderCopyBackupWriter(BackupArguments, subfolderName);
34 | }
35 |
36 | public IBackupWriter CreateSubfolderCopyBackupWriter(string subfolderName, DateTime dateSuffix, string dateFormat = DefaultDateFormat)
37 | {
38 | return new SubfolderCopyBackupWriter(BackupArguments, subfolderName, dateSuffix, dateFormat);
39 | }
40 |
41 | public IBackupWriter CreateZipBackupWriter(string zipName)
42 | {
43 | return new ZipBackupWriter(BackupArguments, zipName);
44 | }
45 |
46 | public IBackupWriter CreateZipBackupWriter(string zipName, DateTime dateSuffix, string dateFormat = DefaultDateFormat)
47 | {
48 | return new ZipBackupWriter(BackupArguments, zipName, dateSuffix, dateFormat);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Data/BackupArguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace SimpleFileBackup.Core.Data
7 | {
8 | ///
9 | /// Data class with arguments needed to perform a backup.
10 | ///
11 | public class BackupArguments
12 | {
13 | ///
14 | /// Paths to files or folders.
15 | ///
16 | public IReadOnlyList InputFiles { get; }
17 |
18 | ///
19 | /// Folder paths of output directories.
20 | ///
21 | public IReadOnlyList OutputDirs { get; }
22 |
23 | ///
24 | /// Defines if existing files should be overwritten.
25 | ///
26 | public bool OverwriteExisting { get; }
27 |
28 | ///
29 | /// Creates a new instance with copies of and .
30 | ///
31 | ///
32 | ///
33 | ///
34 | public BackupArguments(IEnumerable inputFiles, IEnumerable outputDirs, bool overwriteExisting)
35 | {
36 | InputFiles = inputFiles.ToList();
37 | OutputDirs = outputDirs.ToList();
38 | OverwriteExisting = overwriteExisting;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Data/BackupMetadataInfo.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Util;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace SimpleFileBackup.Core.Data
10 | {
11 | ///
12 | /// Contains metadata about the input files of a backup.
13 | ///
14 | public class BackupMetadataInfo
15 | {
16 | ///
17 | /// Dictionary of file path and file size in byte. Invalid files will have size -1.
18 | ///
19 | public IReadOnlyDictionary FileSizes { get; }
20 |
21 | ///
22 | /// Count of all files including those nested in directories.
23 | ///
24 | public long FileCount { get; }
25 |
26 | ///
27 | /// Sum of all file sizes in bytes.
28 | ///
29 | public long FileSizeSum { get; }
30 |
31 | ///
32 | /// if the provided files are valid and accessable, otherwise .
33 | ///
34 | public bool FilesValid { get; } = true;
35 |
36 | private BackupMetadataInfo(long fileSizeSum, long fileCount, IReadOnlyDictionary fileSizes, bool filesValid)
37 | {
38 | FileSizeSum = fileSizeSum;
39 | FileCount = fileCount;
40 | FileSizes = fileSizes;
41 | FilesValid = filesValid;
42 | }
43 |
44 | ///
45 | /// Creates a new from . Gets file and directory size info.
46 | /// Includes file duplicates in size and count.
47 | ///
48 | ///
49 | ///
50 | ///
51 | public static Task FromBackupArgumentsAsync(BackupArguments args, CancellationToken cancellationToken = default)
52 | {
53 | return Task.Run(() =>
54 | {
55 | var fileSizes = new Dictionary();
56 | long fileSizeSum = 0, fileCount = 0;
57 | bool filesValid = true;
58 |
59 | foreach (string inputFile in args.InputFiles)
60 | {
61 | cancellationToken.ThrowIfCancellationRequested();
62 | (long currentFileSize, long currentCount) = GetFileOrFolderSize(inputFile);
63 |
64 | if (currentFileSize >= 0)
65 | {
66 | fileSizeSum += currentFileSize;
67 | }
68 | else
69 | {
70 | filesValid = false;
71 | }
72 |
73 | fileCount += currentCount;
74 | fileSizes.Add(inputFile, currentFileSize);
75 | }
76 |
77 | return new BackupMetadataInfo(fileSizeSum, fileCount, fileSizes, filesValid);
78 | });
79 | }
80 |
81 | ///
82 | /// Gets the file size and count of a single file or whole directory.
83 | ///
84 | ///
85 | /// Size in bytes or -1 if read not possible and count of file(s).
86 | private static (long Size, long Count) GetFileOrFolderSize(string inputFile)
87 | {
88 | long size = -1, count = 1;
89 |
90 | if (Directory.Exists(inputFile))
91 | {
92 | var di = new DirectoryInfo(inputFile);
93 | (size, count) = DirectoryHelper.GetRecursiveDirectorySize(di);
94 | }
95 | else if (File.Exists(inputFile))
96 | {
97 | var fi = new FileInfo(inputFile);
98 | size = fi.Length;
99 | }
100 |
101 | return (size, count);
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/IBackupWriter.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Progress;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace SimpleFileBackup.Core
6 | {
7 | public interface IBackupWriter
8 | {
9 | ///
10 | /// Backs up all input files and folders to their output directories.
11 | /// Reports progress through . Cancellable through .
12 | /// Does not revert changes on cancellation.
13 | ///
14 | ///
15 | ///
16 | ///
17 | Task ExecuteAsync(CancellationToken cancellationToken, IBackupProgress progress);
18 |
19 | ///
20 | /// Backs up all input files and folders to their output directories.
21 | /// Is cancellable through .
22 | /// Does not revert changes on cancellation.
23 | ///
24 | ///
25 | ///
26 | Task ExecuteAsync(CancellationToken cancellationToken);
27 |
28 | ///
29 | /// Backs up all input files and folders to their output directories.
30 | /// Reports progress through .
31 | ///
32 | ///
33 | ///
34 | Task ExecuteAsync(IBackupProgress progress);
35 |
36 | ///
37 | /// Backs up all input files and folders to their output directories.
38 | ///
39 | ///
40 | Task ExecuteAsync();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Progress/BackupProgress.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SimpleFileBackup.Core.Progress
7 | {
8 | ///
9 | /// implementation with requiring a
10 | /// for progress calculation.
11 | ///
12 | ///
13 | public class BackupProgress : Progress, IBackupProgress
14 | {
15 | public BackupMetadataInfo BackupMetadataInfo { get; }
16 |
17 | // Hide default constructor because of required Metadata argument
18 | private BackupProgress()
19 | { }
20 |
21 | ///
22 | /// Initializes a instance.
23 | ///
24 | ///
25 | public BackupProgress(BackupMetadataInfo backupMetadataInfo): base()
26 | {
27 | BackupMetadataInfo = backupMetadataInfo;
28 | }
29 |
30 | ///
31 | /// Initializes a with a handler.
32 | ///
33 | ///
34 | ///
35 | public BackupProgress(Action handler, BackupMetadataInfo backupMetadataInfo) : base(handler)
36 | {
37 | BackupMetadataInfo = backupMetadataInfo;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Progress/BackupProgressInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SimpleFileBackup.Core.Progress
6 | {
7 | ///
8 | /// Provides information about a running backup.
9 | ///
10 | public class BackupProgressInfo
11 | {
12 | ///
13 | /// How much progress the backup has made. Does not have to be related to bytes backed up.
14 | ///
15 | public double PercentDone { get; }
16 |
17 | ///
18 | /// How many bytes were backed up to output locations.
19 | ///
20 | public long BytesBackedUp { get; }
21 |
22 | public BackupProgressInfo(double percentDone, long bytesBackedUp)
23 | {
24 | PercentDone = percentDone;
25 | BytesBackedUp = bytesBackedUp;
26 | }
27 |
28 | public BackupProgressInfo WithPercentDone(double percentDone)
29 | {
30 | return new BackupProgressInfo(percentDone, BytesBackedUp);
31 | }
32 |
33 | public BackupProgressInfo WithBytesBackedUp(long bytesBackedUp)
34 | {
35 | return new BackupProgressInfo(PercentDone, bytesBackedUp);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Progress/IBackupProgress.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SimpleFileBackup.Core.Progress
7 | {
8 | ///
9 | /// Extends with a for progress calculation.
10 | ///
11 | ///
12 | public interface IBackupProgress : IProgress
13 | {
14 | BackupMetadataInfo BackupMetadataInfo { get; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/SimpleFileBackup.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Util/BackupProgressHelper.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using SimpleFileBackup.Core.Progress;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace SimpleFileBackup.Core.Util
8 | {
9 | internal class BackupProgressHelper
10 | {
11 | private readonly BackupArguments backupArguments;
12 | private readonly BackupMetadataInfo metadataInfo;
13 |
14 | public BackupProgressHelper(BackupArguments backupArguments, BackupMetadataInfo metadataInfo)
15 | {
16 | this.backupArguments = backupArguments ?? throw new ArgumentNullException(nameof(backupArguments));
17 | this.metadataInfo = metadataInfo ?? throw new ArgumentNullException(nameof(metadataInfo));
18 | }
19 |
20 | public BackupProgressInfo CurrentProgress { get; private set; } = new BackupProgressInfo(0, 0);
21 |
22 | ///
23 | /// Gets a new increased by the progress depending on the file size of the and the
24 | /// count of output directories in .
25 | ///
26 | ///
27 | ///
28 | public BackupProgressInfo AddProgressByFile(string inputFile)
29 | {
30 | metadataInfo.FileSizes.TryGetValue(inputFile, out long fileSize);
31 |
32 | // (1 for each file + size) / ((sizesum + filecount) * output location count)
33 | double percentIncrease = (1 + fileSize) / (double)((metadataInfo.FileSizeSum + backupArguments.InputFiles.Count) * backupArguments.OutputDirs.Count);
34 |
35 | var newProgress = new BackupProgressInfo(
36 | percentDone: Math.Min(1, CurrentProgress.PercentDone + percentIncrease), // prevent going over 1
37 | bytesBackedUp: CurrentProgress.BytesBackedUp + fileSize);
38 |
39 | return CurrentProgress = newProgress;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Util/DirectoryHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 | using System.Xml.Linq;
6 |
7 | namespace SimpleFileBackup.Core.Util
8 | {
9 | internal static class DirectoryHelper
10 | {
11 | ///
12 | /// Get the full size and count of files of a directory and all of its subfolders recursively.
13 | ///
14 | ///
15 | ///
16 | public static (long Size, long Count) GetRecursiveDirectorySize(DirectoryInfo d)
17 | {
18 | long size = 0, count = 0;
19 | // Add directory file sizes.
20 | foreach (FileInfo fi in d.GetFiles())
21 | {
22 | size += fi.Length;
23 | count++;
24 | }
25 |
26 | // Add subdirectory sizes.
27 | foreach (DirectoryInfo di in d.GetDirectories())
28 | {
29 | var (s, c) = GetRecursiveDirectorySize(di);
30 | count += c;
31 | size += s;
32 | }
33 |
34 | return (size, count);
35 | }
36 |
37 | ///
38 | /// Copies all files and subfolders of source into target, keeping the file structure.
39 | ///
40 | ///
41 | ///
42 | ///
43 | public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target, bool overwriteExisting)
44 | {
45 | foreach (DirectoryInfo dir in source.GetDirectories())
46 | {
47 | CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name), overwriteExisting);
48 | }
49 |
50 | // Keep input folder structure
51 | var outputDir = Path.Combine(target.FullName, source.Name);
52 | Directory.CreateDirectory(outputDir);
53 |
54 | foreach (FileInfo file in source.GetFiles())
55 | {
56 | file.CopyTo(Path.Combine(outputDir, file.Name), overwriteExisting);
57 | }
58 | }
59 |
60 | ///
61 | /// Copies a file or a whole directory recursively into .
62 | /// May throw exceptions from IO access.
63 | ///
64 | ///
65 | ///
66 | ///
67 | public static void CopyFileOrDirectory(string inputFile, string outputDir, bool overwriteExisting)
68 | {
69 | if (Directory.Exists(inputFile))
70 | {
71 | CopyFilesRecursively(new DirectoryInfo(inputFile), new DirectoryInfo(outputDir), overwriteExisting);
72 | }
73 | else // Should be file, throws exception when does not exist.
74 | {
75 | string fileName = Path.GetFileName(inputFile);
76 | File.Copy(inputFile, Path.Combine(outputDir, fileName), overwriteExisting);
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Util/ZipArchiveExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO.Compression;
4 | using System.IO;
5 | using System.Text;
6 | using System.Linq;
7 |
8 | namespace SimpleFileBackup.Core.Util
9 | {
10 | // https://stackoverflow.com/a/51514527
11 | public static class ZipArchiveExtensions
12 | {
13 | ///
14 | /// Creates a new entry in the zip either from a file or directory.
15 | ///
16 | ///
17 | ///
18 | ///
19 | public static void CreateEntryFromAny(this ZipArchive archive, string sourceName, string pathPrefix = "")
20 | {
21 | var fileName = Path.GetFileName(sourceName);
22 | if (File.GetAttributes(sourceName).HasFlag(FileAttributes.Directory))
23 | {
24 | archive.CreateEntryFromDirectory(sourceName, Path.Combine(pathPrefix, fileName));
25 | }
26 | else
27 | {
28 | archive.CreateEntryFromFile(sourceName, Path.Combine(pathPrefix, fileName), CompressionLevel.Fastest);
29 | }
30 | }
31 |
32 | ///
33 | /// Creates a new entry in the zip keeping the structure of the input directory.
34 | ///
35 | ///
36 | ///
37 | ///
38 | public static void CreateEntryFromDirectory(this ZipArchive archive, string sourceDirName, string pathPrefix = "")
39 | {
40 | string[] files = Directory.GetFiles(sourceDirName).Concat(Directory.GetDirectories(sourceDirName)).ToArray();
41 |
42 | foreach (var file in files)
43 | {
44 | archive.CreateEntryFromAny(file, pathPrefix);
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Writers/BaseBackupWriter.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using SimpleFileBackup.Core.Progress;
3 | using SimpleFileBackup.Core.Util;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 |
13 | namespace SimpleFileBackup.Core.Writers
14 | {
15 | ///
16 | /// Sets up the base arguments for a BackupWriter and routes ExecuteAsync overloads with default parameters.
17 | ///
18 | internal abstract class BaseBackupWriter : IBackupWriter
19 | {
20 | protected readonly BackupArguments backupArgs;
21 |
22 | internal BaseBackupWriter(BackupArguments backupArguments)
23 | {
24 | this.backupArgs = backupArguments;
25 | }
26 |
27 | ///
28 | /// Performs the backup with provided arguments.
29 | ///
30 | ///
31 | ///
32 | public abstract Task PerformBackup(CancellationToken cancellationToken = default, IBackupProgress progress = null);
33 |
34 | #region ExecuteAsync overloads, argument check
35 |
36 | public async Task ExecuteAsync(CancellationToken cancellationToken, IBackupProgress progress)
37 | {
38 | if (progress is null)
39 | {
40 | throw new ArgumentNullException(nameof(progress));
41 | }
42 |
43 | if (progress is null)
44 | {
45 | throw new ArgumentNullException(nameof(progress));
46 | }
47 |
48 | await PerformBackup(cancellationToken, progress);
49 | }
50 |
51 | public async Task ExecuteAsync(CancellationToken cancellationToken)
52 | {
53 | await PerformBackup(cancellationToken);
54 | }
55 |
56 | public async Task ExecuteAsync(IBackupProgress progress)
57 | {
58 | if (progress is null)
59 | {
60 | throw new ArgumentNullException(nameof(progress));
61 | }
62 |
63 | await PerformBackup(progress: progress);
64 | }
65 |
66 | public async Task ExecuteAsync()
67 | {
68 | await PerformBackup();
69 | }
70 |
71 | #endregion
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Writers/CopyFileBackupWriter.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using SimpleFileBackup.Core.Progress;
3 | using SimpleFileBackup.Core.Util;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 |
13 | namespace SimpleFileBackup.Core.Writers
14 | {
15 | ///
16 | /// Writer that copies files from locations into other locations.
17 | ///
18 | internal class CopyFileBackupWriter : BaseBackupWriter
19 | {
20 | public CopyFileBackupWriter(BackupArguments backupArguments) : base(backupArguments)
21 | {
22 | }
23 |
24 | public override Task PerformBackup(CancellationToken cancellationToken = default, IBackupProgress progress = null)
25 | {
26 | BackupProgressHelper progressHelper = progress == null ? null : new BackupProgressHelper(backupArgs, progress.BackupMetadataInfo);
27 |
28 | return Task.Run(() =>
29 | {
30 | // Copy each file into each dir
31 | foreach (var outputDir in backupArgs.OutputDirs)
32 | {
33 | foreach (var inputFile in backupArgs.InputFiles)
34 | {
35 | cancellationToken.ThrowIfCancellationRequested();
36 | Directory.CreateDirectory(outputDir);
37 | DirectoryHelper.CopyFileOrDirectory(inputFile, outputDir, backupArgs.OverwriteExisting);
38 | progress?.Report(progressHelper.AddProgressByFile(inputFile));
39 | }
40 | }
41 | }, cancellationToken);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Writers/NamedBackupWriter.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SimpleFileBackup.Core.Writers
7 | {
8 | ///
9 | /// Base class for backup writers that allow setting a name with optional date suffix.
10 | ///
11 | internal abstract class NamedBackupWriter : BaseBackupWriter
12 | {
13 | protected readonly string backupName;
14 |
15 | public NamedBackupWriter(BackupArguments backupArguments, string backupName, DateTime dateSuffix, string dateFormat) : this(backupArguments, backupName)
16 | {
17 | this.backupName = dateSuffix != null ? $"{backupName}_{dateSuffix.ToString(dateFormat)}" : backupName;
18 | }
19 |
20 | public NamedBackupWriter(BackupArguments backupArguments, string backupName) : base(backupArguments)
21 | {
22 | if (string.IsNullOrWhiteSpace(backupName))
23 | {
24 | throw new ArgumentException($"'{nameof(backupName)}' cannot be null or whitespace.", nameof(backupName));
25 | }
26 |
27 | this.backupName = backupName;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Writers/SubfolderCopyBackupWriter.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using SimpleFileBackup.Core.Progress;
3 | using SimpleFileBackup.Core.Util;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace SimpleFileBackup.Core.Writers
12 | {
13 | internal class SubfolderCopyBackupWriter : NamedBackupWriter
14 | {
15 | public SubfolderCopyBackupWriter(BackupArguments backupArguments, string subfolderName, DateTime dateSuffix, string dateFormat)
16 | : base(backupArguments, subfolderName, dateSuffix, dateFormat)
17 | {
18 | }
19 |
20 | public SubfolderCopyBackupWriter(BackupArguments backupArguments, string subfolderName)
21 | : base(backupArguments, subfolderName)
22 | {
23 | }
24 |
25 | public override Task PerformBackup(CancellationToken cancellationToken = default, IBackupProgress progress = null)
26 | {
27 | BackupProgressHelper progressHelper = progress == null ? null : new BackupProgressHelper(backupArgs, progress.BackupMetadataInfo);
28 |
29 | return Task.Run(() =>
30 | {
31 | // Copy each file into each dir, create new subdir
32 | foreach (var outputDir in backupArgs.OutputDirs)
33 | {
34 | var outputSubDir = Directory.CreateDirectory(Path.Combine(outputDir, backupName));
35 |
36 | foreach (var inputFile in backupArgs.InputFiles)
37 | {
38 | cancellationToken.ThrowIfCancellationRequested();
39 | DirectoryHelper.CopyFileOrDirectory(inputFile, outputSubDir.FullName, backupArgs.OverwriteExisting);
40 | progress?.Report(progressHelper.AddProgressByFile(inputFile));
41 | }
42 | }
43 | }, cancellationToken);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Core/Writers/ZipBackupWriter.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core.Data;
2 | using SimpleFileBackup.Core.Progress;
3 | using SimpleFileBackup.Core.Util;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.IO.Compression;
8 | using System.Runtime.InteropServices.ComTypes;
9 | using System.Text;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 |
13 | namespace SimpleFileBackup.Core.Writers
14 | {
15 | internal class ZipBackupWriter : NamedBackupWriter
16 | {
17 | public ZipBackupWriter(BackupArguments backupArguments, string fileName, DateTime dateSuffix, string dateFormat)
18 | : base(backupArguments, fileName, dateSuffix, dateFormat)
19 | {
20 | }
21 |
22 | public ZipBackupWriter(BackupArguments backupArguments, string fileName)
23 | : base(backupArguments, fileName)
24 | {
25 | }
26 |
27 | public override Task PerformBackup(CancellationToken cancellationToken = default, IBackupProgress progress = null)
28 | {
29 | return Task.Run(() =>
30 | {
31 | var outputDirs = backupArgs.OutputDirs.GetEnumerator();
32 | if (!outputDirs.MoveNext()) return;
33 |
34 | Directory.CreateDirectory(outputDirs.Current);
35 | string originZip = CreateZipFromArguments(outputDirs.Current, cancellationToken, progress);
36 | long dirCount = 1;
37 | long zipSize = new FileInfo(originZip).Length;
38 | progress?.Report(new BackupProgressInfo(dirCount / (double)backupArgs.OutputDirs.Count, zipSize));
39 |
40 | // Copy the zip into other outputs
41 | while (outputDirs.MoveNext())
42 | {
43 | cancellationToken.ThrowIfCancellationRequested();
44 | Directory.CreateDirectory(outputDirs.Current);
45 | File.Copy(originZip, Path.Combine(outputDirs.Current, backupName + ".zip"), backupArgs.OverwriteExisting);
46 |
47 | dirCount++;
48 | progress?.Report(new BackupProgressInfo(dirCount / (double)backupArgs.OutputDirs.Count, zipSize * dirCount));
49 | }
50 | }, cancellationToken);
51 | }
52 |
53 | ///
54 | /// Creates a new zip archive with all input files from . Deletes existing file first if overwrite existing is enabled.
55 | ///
56 | ///
57 | ///
58 | /// Path to the new zip file.
59 | private string CreateZipFromArguments(string location, CancellationToken cancellationToken, IBackupProgress progress = null)
60 | {
61 | BackupProgressHelper progressHelper = progress == null ? null : new BackupProgressHelper(backupArgs, progress.BackupMetadataInfo);
62 | cancellationToken.ThrowIfCancellationRequested();
63 |
64 | // Create zip in first backup dir, delete first if exists
65 | var fileLocation = Path.Combine(location, backupName + ".zip");
66 | if (backupArgs.OverwriteExisting)
67 | {
68 | File.Delete(fileLocation);
69 | }
70 |
71 | // Add all input files and directories to zip
72 | using (var zipFile = ZipFile.Open(fileLocation, ZipArchiveMode.Create))
73 | {
74 | foreach (var inputFile in backupArgs.InputFiles)
75 | {
76 | zipFile.CreateEntryFromAny(inputFile);
77 | if (progressHelper != null)
78 | {
79 | // While creating zip bytesBackedUp will stay 0
80 | progress?.Report(progressHelper.AddProgressByFile(inputFile).WithBytesBackedUp(0));
81 | }
82 | progress?.Report(progressHelper.CurrentProgress);
83 | cancellationToken.ThrowIfCancellationRequested();
84 | }
85 | }
86 |
87 | return fileLocation;
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 0
15 |
16 |
17 |
18 |
19 |
20 | False
21 |
22 |
23 | False
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/BackupMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace SimpleFileBackup.Windows
8 | {
9 | internal enum BackupMode
10 | {
11 | Copy,
12 | Subfolder,
13 | Zip
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/FormAbout.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace SimpleFileBackup.Windows
2 | {
3 | partial class FormAbout
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.webBrowser = new System.Windows.Forms.WebBrowser();
32 | this.SuspendLayout();
33 | //
34 | // webBrowser
35 | //
36 | this.webBrowser.AllowNavigation = false;
37 | this.webBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
38 | this.webBrowser.Location = new System.Drawing.Point(0, 0);
39 | this.webBrowser.MinimumSize = new System.Drawing.Size(20, 20);
40 | this.webBrowser.Name = "webBrowser";
41 | this.webBrowser.Size = new System.Drawing.Size(333, 455);
42 | this.webBrowser.TabIndex = 0;
43 | //
44 | // FormAbout
45 | //
46 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
47 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
48 | this.ClientSize = new System.Drawing.Size(333, 455);
49 | this.Controls.Add(this.webBrowser);
50 | this.MaximizeBox = false;
51 | this.MinimizeBox = false;
52 | this.Name = "FormAbout";
53 | this.ShowIcon = false;
54 | this.Text = "About";
55 | this.Load += new System.EventHandler(this.FormAbout_Load);
56 | this.ResumeLayout(false);
57 |
58 | }
59 |
60 | #endregion
61 | private System.Windows.Forms.WebBrowser webBrowser;
62 | }
63 | }
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/FormAbout.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace SimpleFileBackup.Windows
12 | {
13 | public partial class FormAbout : Form
14 | {
15 | public FormAbout()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void FormAbout_Load(object sender, EventArgs e)
21 | {
22 | string html = Properties.Resources.about;
23 | webBrowser.DocumentText = html;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/FormAbout.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/FormMain.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace SimpleFileBackup.Windows
2 | {
3 | partial class FormMain
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
32 | this.buttonFilestobackup = new System.Windows.Forms.Button();
33 | this.labelFilesBackup = new System.Windows.Forms.Label();
34 | this.labelBackup = new System.Windows.Forms.Label();
35 | this.buttonBackupLocationsBrowse = new System.Windows.Forms.Button();
36 | this.buttonOK = new System.Windows.Forms.Button();
37 | this.labelInfotext = new System.Windows.Forms.Label();
38 | this.comboBoxFilestobackup = new System.Windows.Forms.ComboBox();
39 | this.buttonFilestobackupClear = new System.Windows.Forms.Button();
40 | this.buttonFilestobackupDeleteitem = new System.Windows.Forms.Button();
41 | this.comboBoxBackupLocations = new System.Windows.Forms.ComboBox();
42 | this.buttonBackupLocationsDeleteItem = new System.Windows.Forms.Button();
43 | this.buttonBackupLocationsClear = new System.Windows.Forms.Button();
44 | this.menuStrip = new System.Windows.Forms.MenuStrip();
45 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
46 | this.saveDefaultsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
47 | this.saveCustomFilePathsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
48 | this.saveCustomBackupPathsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
49 | this.openFilePathsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
50 | this.openBackupPathsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
51 | this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
52 | this.groupBoxSettings = new System.Windows.Forms.GroupBox();
53 | this.radioButtonNormal = new System.Windows.Forms.RadioButton();
54 | this.radioButtonZIP = new System.Windows.Forms.RadioButton();
55 | this.radioButtonFolder = new System.Windows.Forms.RadioButton();
56 | this.textBoxName = new System.Windows.Forms.TextBox();
57 | this.checkBoxDate = new System.Windows.Forms.CheckBox();
58 | this.progressBarMain = new System.Windows.Forms.ProgressBar();
59 | this.checkBoxOverride = new System.Windows.Forms.CheckBox();
60 | this.buttonFolderstobackup = new System.Windows.Forms.Button();
61 | this.buttonCancel = new System.Windows.Forms.Button();
62 | this.labelProgress = new System.Windows.Forms.Label();
63 | this.menuStrip.SuspendLayout();
64 | this.groupBoxSettings.SuspendLayout();
65 | this.SuspendLayout();
66 | //
67 | // buttonFilestobackup
68 | //
69 | this.buttonFilestobackup.Location = new System.Drawing.Point(376, 60);
70 | this.buttonFilestobackup.Name = "buttonFilestobackup";
71 | this.buttonFilestobackup.Size = new System.Drawing.Size(90, 20);
72 | this.buttonFilestobackup.TabIndex = 2;
73 | this.buttonFilestobackup.Text = "Select Files";
74 | this.buttonFilestobackup.UseVisualStyleBackColor = true;
75 | this.buttonFilestobackup.Click += new System.EventHandler(this.ButtonFilestobackup_Click);
76 | //
77 | // labelFilesBackup
78 | //
79 | this.labelFilesBackup.AutoSize = true;
80 | this.labelFilesBackup.Location = new System.Drawing.Point(12, 44);
81 | this.labelFilesBackup.Name = "labelFilesBackup";
82 | this.labelFilesBackup.Size = new System.Drawing.Size(80, 13);
83 | this.labelFilesBackup.TabIndex = 0;
84 | this.labelFilesBackup.Text = "Files to Backup";
85 | //
86 | // labelBackup
87 | //
88 | this.labelBackup.AutoSize = true;
89 | this.labelBackup.Location = new System.Drawing.Point(12, 135);
90 | this.labelBackup.Name = "labelBackup";
91 | this.labelBackup.Size = new System.Drawing.Size(105, 13);
92 | this.labelBackup.TabIndex = 6;
93 | this.labelBackup.Text = "Backup Destinations";
94 | //
95 | // buttonBackupLocationsBrowse
96 | //
97 | this.buttonBackupLocationsBrowse.Location = new System.Drawing.Point(376, 151);
98 | this.buttonBackupLocationsBrowse.Name = "buttonBackupLocationsBrowse";
99 | this.buttonBackupLocationsBrowse.Size = new System.Drawing.Size(90, 20);
100 | this.buttonBackupLocationsBrowse.TabIndex = 8;
101 | this.buttonBackupLocationsBrowse.Text = "Select Folders";
102 | this.buttonBackupLocationsBrowse.UseVisualStyleBackColor = true;
103 | this.buttonBackupLocationsBrowse.Click += new System.EventHandler(this.ButtonBackupBrowse_Click);
104 | //
105 | // buttonOK
106 | //
107 | this.buttonOK.Location = new System.Drawing.Point(15, 360);
108 | this.buttonOK.Name = "buttonOK";
109 | this.buttonOK.Size = new System.Drawing.Size(448, 44);
110 | this.buttonOK.TabIndex = 19;
111 | this.buttonOK.Text = "Backup";
112 | this.buttonOK.UseVisualStyleBackColor = true;
113 | this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
114 | //
115 | // labelInfotext
116 | //
117 | this.labelInfotext.AutoEllipsis = true;
118 | this.labelInfotext.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
119 | this.labelInfotext.Location = new System.Drawing.Point(239, 221);
120 | this.labelInfotext.Name = "labelInfotext";
121 | this.labelInfotext.Size = new System.Drawing.Size(224, 65);
122 | this.labelInfotext.TabIndex = 19;
123 | this.labelInfotext.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
124 | this.labelInfotext.Visible = false;
125 | //
126 | // comboBoxFilestobackup
127 | //
128 | this.comboBoxFilestobackup.FormattingEnabled = true;
129 | this.comboBoxFilestobackup.Location = new System.Drawing.Point(15, 61);
130 | this.comboBoxFilestobackup.Name = "comboBoxFilestobackup";
131 | this.comboBoxFilestobackup.Size = new System.Drawing.Size(355, 21);
132 | this.comboBoxFilestobackup.TabIndex = 1;
133 | this.comboBoxFilestobackup.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ComboBoxFilestobackup_KeyDown);
134 | //
135 | // buttonFilestobackupClear
136 | //
137 | this.buttonFilestobackupClear.Location = new System.Drawing.Point(376, 98);
138 | this.buttonFilestobackupClear.Name = "buttonFilestobackupClear";
139 | this.buttonFilestobackupClear.Size = new System.Drawing.Size(90, 20);
140 | this.buttonFilestobackupClear.TabIndex = 4;
141 | this.buttonFilestobackupClear.Text = "Clear List";
142 | this.buttonFilestobackupClear.UseVisualStyleBackColor = true;
143 | this.buttonFilestobackupClear.Click += new System.EventHandler(this.ButtonFilestobackupClear_Click);
144 | //
145 | // buttonFilestobackupDeleteitem
146 | //
147 | this.buttonFilestobackupDeleteitem.Location = new System.Drawing.Point(376, 117);
148 | this.buttonFilestobackupDeleteitem.Name = "buttonFilestobackupDeleteitem";
149 | this.buttonFilestobackupDeleteitem.Size = new System.Drawing.Size(90, 20);
150 | this.buttonFilestobackupDeleteitem.TabIndex = 5;
151 | this.buttonFilestobackupDeleteitem.Text = "Delete Item";
152 | this.buttonFilestobackupDeleteitem.UseVisualStyleBackColor = true;
153 | this.buttonFilestobackupDeleteitem.Click += new System.EventHandler(this.ButtonFilestobackupDeleteitem_Click);
154 | //
155 | // comboBoxBackupLocations
156 | //
157 | this.comboBoxBackupLocations.FormattingEnabled = true;
158 | this.comboBoxBackupLocations.Location = new System.Drawing.Point(15, 152);
159 | this.comboBoxBackupLocations.Name = "comboBoxBackupLocations";
160 | this.comboBoxBackupLocations.Size = new System.Drawing.Size(355, 21);
161 | this.comboBoxBackupLocations.TabIndex = 7;
162 | this.comboBoxBackupLocations.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ComboBoxBackupLocations_KeyDown);
163 | //
164 | // buttonBackupLocationsDeleteItem
165 | //
166 | this.buttonBackupLocationsDeleteItem.Location = new System.Drawing.Point(376, 189);
167 | this.buttonBackupLocationsDeleteItem.Name = "buttonBackupLocationsDeleteItem";
168 | this.buttonBackupLocationsDeleteItem.Size = new System.Drawing.Size(90, 20);
169 | this.buttonBackupLocationsDeleteItem.TabIndex = 10;
170 | this.buttonBackupLocationsDeleteItem.Text = "Delete Item";
171 | this.buttonBackupLocationsDeleteItem.UseVisualStyleBackColor = true;
172 | this.buttonBackupLocationsDeleteItem.Click += new System.EventHandler(this.ButtonBackupLocationsDeleteItem_Click);
173 | //
174 | // buttonBackupLocationsClear
175 | //
176 | this.buttonBackupLocationsClear.Location = new System.Drawing.Point(376, 170);
177 | this.buttonBackupLocationsClear.Name = "buttonBackupLocationsClear";
178 | this.buttonBackupLocationsClear.Size = new System.Drawing.Size(90, 20);
179 | this.buttonBackupLocationsClear.TabIndex = 9;
180 | this.buttonBackupLocationsClear.Text = "Clear List";
181 | this.buttonBackupLocationsClear.UseVisualStyleBackColor = true;
182 | this.buttonBackupLocationsClear.Click += new System.EventHandler(this.ButtonBackupLocationsClear_Click);
183 | //
184 | // menuStrip
185 | //
186 | this.menuStrip.BackColor = System.Drawing.SystemColors.ControlLight;
187 | this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
188 | this.fileToolStripMenuItem,
189 | this.aboutToolStripMenuItem});
190 | this.menuStrip.Location = new System.Drawing.Point(0, 0);
191 | this.menuStrip.Name = "menuStrip";
192 | this.menuStrip.Size = new System.Drawing.Size(479, 24);
193 | this.menuStrip.TabIndex = 23;
194 | this.menuStrip.Text = "menuStrip1";
195 | //
196 | // fileToolStripMenuItem
197 | //
198 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
199 | this.saveDefaultsToolStripMenuItem,
200 | this.saveCustomFilePathsToolStripMenuItem,
201 | this.saveCustomBackupPathsToolStripMenuItem,
202 | this.openFilePathsToolStripMenuItem,
203 | this.openBackupPathsToolStripMenuItem});
204 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
205 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
206 | this.fileToolStripMenuItem.Text = "File";
207 | //
208 | // saveDefaultsToolStripMenuItem
209 | //
210 | this.saveDefaultsToolStripMenuItem.Name = "saveDefaultsToolStripMenuItem";
211 | this.saveDefaultsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
212 | this.saveDefaultsToolStripMenuItem.Size = new System.Drawing.Size(258, 22);
213 | this.saveDefaultsToolStripMenuItem.Text = "Save Defaults";
214 | this.saveDefaultsToolStripMenuItem.Click += new System.EventHandler(this.SaveDefaultsToolStripMenuItem_Click);
215 | //
216 | // saveCustomFilePathsToolStripMenuItem
217 | //
218 | this.saveCustomFilePathsToolStripMenuItem.Name = "saveCustomFilePathsToolStripMenuItem";
219 | this.saveCustomFilePathsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
220 | this.saveCustomFilePathsToolStripMenuItem.Size = new System.Drawing.Size(258, 22);
221 | this.saveCustomFilePathsToolStripMenuItem.Text = "Save Custom File Paths";
222 | this.saveCustomFilePathsToolStripMenuItem.Click += new System.EventHandler(this.SaveCustomFilePathsToolStripMenuItem_Click);
223 | //
224 | // saveCustomBackupPathsToolStripMenuItem
225 | //
226 | this.saveCustomBackupPathsToolStripMenuItem.Name = "saveCustomBackupPathsToolStripMenuItem";
227 | this.saveCustomBackupPathsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.B)));
228 | this.saveCustomBackupPathsToolStripMenuItem.Size = new System.Drawing.Size(258, 22);
229 | this.saveCustomBackupPathsToolStripMenuItem.Text = "Save Custom Backup Paths";
230 | this.saveCustomBackupPathsToolStripMenuItem.Click += new System.EventHandler(this.SaveCustomBackupPathsToolStripMenuItem_Click);
231 | //
232 | // openFilePathsToolStripMenuItem
233 | //
234 | this.openFilePathsToolStripMenuItem.Name = "openFilePathsToolStripMenuItem";
235 | this.openFilePathsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
236 | this.openFilePathsToolStripMenuItem.Size = new System.Drawing.Size(258, 22);
237 | this.openFilePathsToolStripMenuItem.Text = "Open File Paths";
238 | this.openFilePathsToolStripMenuItem.Click += new System.EventHandler(this.OpenPaths_Click);
239 | //
240 | // openBackupPathsToolStripMenuItem
241 | //
242 | this.openBackupPathsToolStripMenuItem.Name = "openBackupPathsToolStripMenuItem";
243 | this.openBackupPathsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
244 | | System.Windows.Forms.Keys.O)));
245 | this.openBackupPathsToolStripMenuItem.Size = new System.Drawing.Size(258, 22);
246 | this.openBackupPathsToolStripMenuItem.Text = "Open Backup Paths";
247 | this.openBackupPathsToolStripMenuItem.Click += new System.EventHandler(this.OpenPaths_Click);
248 | //
249 | // aboutToolStripMenuItem
250 | //
251 | this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
252 | this.aboutToolStripMenuItem.Size = new System.Drawing.Size(52, 20);
253 | this.aboutToolStripMenuItem.Text = "About";
254 | this.aboutToolStripMenuItem.Click += new System.EventHandler(this.AboutToolStripMenuItem_Click);
255 | //
256 | // groupBoxSettings
257 | //
258 | this.groupBoxSettings.Controls.Add(this.radioButtonNormal);
259 | this.groupBoxSettings.Controls.Add(this.radioButtonZIP);
260 | this.groupBoxSettings.Controls.Add(this.radioButtonFolder);
261 | this.groupBoxSettings.Controls.Add(this.textBoxName);
262 | this.groupBoxSettings.Controls.Add(this.checkBoxDate);
263 | this.groupBoxSettings.Location = new System.Drawing.Point(18, 221);
264 | this.groupBoxSettings.Name = "groupBoxSettings";
265 | this.groupBoxSettings.Size = new System.Drawing.Size(215, 133);
266 | this.groupBoxSettings.TabIndex = 12;
267 | this.groupBoxSettings.TabStop = false;
268 | this.groupBoxSettings.Text = "Settings";
269 | //
270 | // radioButtonNormal
271 | //
272 | this.radioButtonNormal.AutoSize = true;
273 | this.radioButtonNormal.Checked = true;
274 | this.radioButtonNormal.Location = new System.Drawing.Point(6, 19);
275 | this.radioButtonNormal.Name = "radioButtonNormal";
276 | this.radioButtonNormal.Size = new System.Drawing.Size(145, 17);
277 | this.radioButtonNormal.TabIndex = 13;
278 | this.radioButtonNormal.TabStop = true;
279 | this.radioButtonNormal.Text = "Put files in given directory";
280 | this.radioButtonNormal.UseVisualStyleBackColor = true;
281 | this.radioButtonNormal.CheckedChanged += new System.EventHandler(this.RadioButtons_CheckedChanged);
282 | //
283 | // radioButtonZIP
284 | //
285 | this.radioButtonZIP.AutoSize = true;
286 | this.radioButtonZIP.Location = new System.Drawing.Point(6, 65);
287 | this.radioButtonZIP.Name = "radioButtonZIP";
288 | this.radioButtonZIP.Size = new System.Drawing.Size(154, 17);
289 | this.radioButtonZIP.TabIndex = 15;
290 | this.radioButtonZIP.Text = "Create a .zip file in directory";
291 | this.radioButtonZIP.UseVisualStyleBackColor = true;
292 | this.radioButtonZIP.CheckedChanged += new System.EventHandler(this.RadioButtons_CheckedChanged);
293 | //
294 | // radioButtonFolder
295 | //
296 | this.radioButtonFolder.AutoSize = true;
297 | this.radioButtonFolder.Location = new System.Drawing.Point(6, 42);
298 | this.radioButtonFolder.Name = "radioButtonFolder";
299 | this.radioButtonFolder.Size = new System.Drawing.Size(165, 17);
300 | this.radioButtonFolder.TabIndex = 14;
301 | this.radioButtonFolder.Text = "Create a subfolder in directory";
302 | this.radioButtonFolder.UseVisualStyleBackColor = true;
303 | this.radioButtonFolder.CheckedChanged += new System.EventHandler(this.RadioButtons_CheckedChanged);
304 | //
305 | // textBoxName
306 | //
307 | this.textBoxName.Enabled = false;
308 | this.textBoxName.Location = new System.Drawing.Point(6, 87);
309 | this.textBoxName.MaxLength = 20;
310 | this.textBoxName.Name = "textBoxName";
311 | this.textBoxName.Size = new System.Drawing.Size(171, 20);
312 | this.textBoxName.TabIndex = 16;
313 | this.textBoxName.Text = "Name Folder/.zip";
314 | this.textBoxName.Click += new System.EventHandler(this.TextBoxName_Click);
315 | this.textBoxName.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.TextBoxName_PreviewKeyDown);
316 | //
317 | // checkBoxDate
318 | //
319 | this.checkBoxDate.AutoSize = true;
320 | this.checkBoxDate.Enabled = false;
321 | this.checkBoxDate.Location = new System.Drawing.Point(6, 113);
322 | this.checkBoxDate.Name = "checkBoxDate";
323 | this.checkBoxDate.Size = new System.Drawing.Size(163, 17);
324 | this.checkBoxDate.TabIndex = 17;
325 | this.checkBoxDate.Text = "Add date to Folder/.zip name";
326 | this.checkBoxDate.UseVisualStyleBackColor = true;
327 | //
328 | // progressBarMain
329 | //
330 | this.progressBarMain.Location = new System.Drawing.Point(239, 330);
331 | this.progressBarMain.Name = "progressBarMain";
332 | this.progressBarMain.Size = new System.Drawing.Size(224, 24);
333 | this.progressBarMain.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
334 | this.progressBarMain.TabIndex = 18;
335 | //
336 | // checkBoxOverride
337 | //
338 | this.checkBoxOverride.AutoSize = true;
339 | this.checkBoxOverride.Location = new System.Drawing.Point(15, 179);
340 | this.checkBoxOverride.Name = "checkBoxOverride";
341 | this.checkBoxOverride.Size = new System.Drawing.Size(183, 17);
342 | this.checkBoxOverride.TabIndex = 11;
343 | this.checkBoxOverride.Text = "Override identical files in directory";
344 | this.checkBoxOverride.UseVisualStyleBackColor = true;
345 | //
346 | // buttonFolderstobackup
347 | //
348 | this.buttonFolderstobackup.Location = new System.Drawing.Point(376, 79);
349 | this.buttonFolderstobackup.Name = "buttonFolderstobackup";
350 | this.buttonFolderstobackup.Size = new System.Drawing.Size(90, 20);
351 | this.buttonFolderstobackup.TabIndex = 3;
352 | this.buttonFolderstobackup.Text = "Select Folders";
353 | this.buttonFolderstobackup.UseVisualStyleBackColor = true;
354 | this.buttonFolderstobackup.Click += new System.EventHandler(this.ButtonFolderstobackup_Click);
355 | //
356 | // buttonCancel
357 | //
358 | this.buttonCancel.Location = new System.Drawing.Point(15, 360);
359 | this.buttonCancel.Name = "buttonCancel";
360 | this.buttonCancel.Size = new System.Drawing.Size(448, 44);
361 | this.buttonCancel.TabIndex = 20;
362 | this.buttonCancel.Text = "Cancel";
363 | this.buttonCancel.UseVisualStyleBackColor = true;
364 | this.buttonCancel.Visible = false;
365 | this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
366 | //
367 | // labelProgress
368 | //
369 | this.labelProgress.AutoEllipsis = true;
370 | this.labelProgress.Location = new System.Drawing.Point(239, 286);
371 | this.labelProgress.Name = "labelProgress";
372 | this.labelProgress.Size = new System.Drawing.Size(224, 37);
373 | this.labelProgress.TabIndex = 22;
374 | this.labelProgress.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
375 | //
376 | // FormMain
377 | //
378 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
379 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
380 | this.BackColor = System.Drawing.SystemColors.Control;
381 | this.ClientSize = new System.Drawing.Size(479, 416);
382 | this.Controls.Add(this.labelProgress);
383 | this.Controls.Add(this.buttonCancel);
384 | this.Controls.Add(this.buttonFolderstobackup);
385 | this.Controls.Add(this.checkBoxOverride);
386 | this.Controls.Add(this.progressBarMain);
387 | this.Controls.Add(this.groupBoxSettings);
388 | this.Controls.Add(this.buttonBackupLocationsDeleteItem);
389 | this.Controls.Add(this.buttonBackupLocationsClear);
390 | this.Controls.Add(this.comboBoxBackupLocations);
391 | this.Controls.Add(this.buttonFilestobackupDeleteitem);
392 | this.Controls.Add(this.buttonFilestobackupClear);
393 | this.Controls.Add(this.comboBoxFilestobackup);
394 | this.Controls.Add(this.labelInfotext);
395 | this.Controls.Add(this.buttonOK);
396 | this.Controls.Add(this.labelBackup);
397 | this.Controls.Add(this.buttonBackupLocationsBrowse);
398 | this.Controls.Add(this.labelFilesBackup);
399 | this.Controls.Add(this.buttonFilestobackup);
400 | this.Controls.Add(this.menuStrip);
401 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
402 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
403 | this.MainMenuStrip = this.menuStrip;
404 | this.MaximizeBox = false;
405 | this.Name = "FormMain";
406 | this.ShowIcon = false;
407 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
408 | this.Text = "SimpleFileBackup";
409 | this.Load += new System.EventHandler(this.FormMain_Load);
410 | this.menuStrip.ResumeLayout(false);
411 | this.menuStrip.PerformLayout();
412 | this.groupBoxSettings.ResumeLayout(false);
413 | this.groupBoxSettings.PerformLayout();
414 | this.ResumeLayout(false);
415 | this.PerformLayout();
416 |
417 | }
418 |
419 | #endregion
420 | private System.Windows.Forms.Button buttonFilestobackup;
421 | private System.Windows.Forms.Label labelFilesBackup;
422 | private System.Windows.Forms.Label labelBackup;
423 | private System.Windows.Forms.Button buttonBackupLocationsBrowse;
424 | private System.Windows.Forms.Button buttonOK;
425 | private System.Windows.Forms.Label labelInfotext;
426 | private System.Windows.Forms.ComboBox comboBoxFilestobackup;
427 | private System.Windows.Forms.Button buttonFilestobackupClear;
428 | private System.Windows.Forms.Button buttonFilestobackupDeleteitem;
429 | private System.Windows.Forms.ComboBox comboBoxBackupLocations;
430 | private System.Windows.Forms.Button buttonBackupLocationsDeleteItem;
431 | private System.Windows.Forms.Button buttonBackupLocationsClear;
432 | private System.Windows.Forms.MenuStrip menuStrip;
433 | private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
434 | private System.Windows.Forms.GroupBox groupBoxSettings;
435 | private System.Windows.Forms.CheckBox checkBoxDate;
436 | private System.Windows.Forms.TextBox textBoxName;
437 | private System.Windows.Forms.ProgressBar progressBarMain;
438 | private System.Windows.Forms.RadioButton radioButtonZIP;
439 | private System.Windows.Forms.RadioButton radioButtonFolder;
440 | private System.Windows.Forms.RadioButton radioButtonNormal;
441 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
442 | private System.Windows.Forms.CheckBox checkBoxOverride;
443 | private System.Windows.Forms.ToolStripMenuItem saveCustomFilePathsToolStripMenuItem;
444 | private System.Windows.Forms.ToolStripMenuItem saveCustomBackupPathsToolStripMenuItem;
445 | private System.Windows.Forms.ToolStripMenuItem openFilePathsToolStripMenuItem;
446 | private System.Windows.Forms.ToolStripMenuItem openBackupPathsToolStripMenuItem;
447 | private System.Windows.Forms.Button buttonFolderstobackup;
448 | private System.Windows.Forms.Button buttonCancel;
449 | private System.Windows.Forms.Label labelProgress;
450 | private System.Windows.Forms.ToolStripMenuItem saveDefaultsToolStripMenuItem;
451 | }
452 | }
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/FormMain.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Threading.Tasks;
6 | using System.Windows.Forms;
7 | using System.IO;
8 | using System.IO.Compression;
9 | using Microsoft.WindowsAPICodePack.Dialogs;
10 | using SimpleFileBackup.Core.Data;
11 | using SimpleFileBackup.Core;
12 | using SimpleFileBackup.Core.Progress;
13 | using System.Threading;
14 | using System.Security.Cryptography;
15 | using System.Linq;
16 | using System.Collections.Specialized;
17 |
18 | namespace SimpleFileBackup.Windows
19 | {
20 | ///
21 | /// Logic behind the SimpleFileBackup Windows Forms User Controls.
22 | ///
23 | public partial class FormMain : Form
24 | {
25 | public FormMain()
26 | {
27 | InitializeComponent();
28 | }
29 |
30 | #region DisplayText
31 |
32 | private CancellationTokenSource displayCancellation = new CancellationTokenSource();
33 |
34 | private async void DisplayText(string text, int ms, Color color)
35 | {
36 | if (text == labelInfotext.Text)
37 | {
38 | return; // If it's the same message don't display twice
39 | }
40 |
41 | displayCancellation?.Cancel(); // Cancel old message
42 | using (var currentTokenSource = new CancellationTokenSource())
43 | {
44 | displayCancellation = currentTokenSource;
45 | labelInfotext.ForeColor = color;
46 | labelInfotext.Text = text;
47 | labelInfotext.Visible = true;
48 | try
49 | {
50 | await Task.Delay(ms, currentTokenSource.Token);
51 | labelInfotext.Visible = false; // Only hide when no other display task has started
52 | labelInfotext.Text = "";
53 | }
54 | catch (OperationCanceledException) { } // ignored
55 | finally { displayCancellation = null; }
56 | }
57 | }
58 |
59 | #endregion
60 |
61 | /* --- Form Events --- */
62 |
63 | #region Form Load, Init Paths and Settings
64 |
65 | private void FormMain_Load(object sender, EventArgs e)
66 | {
67 | var settings = Properties.Settings.Default;
68 | var inputFiles = settings.InputFiles?.Cast().ToArray();
69 | if (inputFiles != null && inputFiles.Length > 0)
70 | {
71 | comboBoxFilestobackup.Items.AddRange(inputFiles);
72 | comboBoxFilestobackup.SelectedItem = comboBoxFilestobackup.Items[0];
73 | }
74 |
75 | var outputDirs = settings.OutputDirectories?.Cast().ToArray();
76 | if (outputDirs != null && outputDirs.Length > 0)
77 | {
78 | comboBoxBackupLocations.Items.AddRange(outputDirs);
79 | comboBoxBackupLocations.SelectedItem = comboBoxBackupLocations.Items[0];
80 | }
81 |
82 | if (Enum.TryParse(settings.BackupMode.ToString(), out var mode))
83 | {
84 | radioButtonNormal.Checked = mode == BackupMode.Copy;
85 | radioButtonFolder.Checked = mode == BackupMode.Subfolder;
86 | radioButtonZIP.Checked = mode == BackupMode.Zip;
87 | }
88 |
89 | checkBoxDate.Checked = settings.AddDate;
90 | checkBoxOverride.Checked = settings.Overwrite;
91 | textBoxName.Text = settings.BackupName;
92 | }
93 |
94 | #endregion
95 |
96 | #region Select Backup Files or Folders
97 |
98 | private void ButtonFilestobackup_Click(object sender, EventArgs e)
99 | {
100 | using (OpenFileDialog ofd = new OpenFileDialog { Multiselect = true })
101 | {
102 | ofd.ShowDialog();
103 |
104 | if (ofd.FileName == "") //no item selected cancel
105 | return;
106 |
107 | foreach (string s in ofd.FileNames)
108 | {
109 | if (!comboBoxFilestobackup.Items.Contains(s)) //only add if does not exist yet
110 | comboBoxFilestobackup.Items.Add(s);
111 | }
112 |
113 | comboBoxFilestobackup.SelectedItem = comboBoxFilestobackup.Items[comboBoxFilestobackup.Items.Count - 1]; //display last item
114 | }
115 | }
116 |
117 | private void ButtonFolderstobackup_Click(object sender, EventArgs e)
118 | {
119 | using (CommonOpenFileDialog cof = new CommonOpenFileDialog { IsFolderPicker = true, Multiselect = true })
120 | {
121 | if (cof.ShowDialog() != CommonFileDialogResult.Ok)
122 | return; //if the user cancels the dialog
123 |
124 | foreach (string s in cof.FileNames)
125 | {
126 | if (!comboBoxFilestobackup.Items.Contains(s)) //only add if does not exist yet
127 | comboBoxFilestobackup.Items.Add(s);
128 | }
129 |
130 | comboBoxFilestobackup.SelectedItem = comboBoxFilestobackup.Items[comboBoxFilestobackup.Items.Count - 1]; //display last item
131 | }
132 | }
133 |
134 | private void ButtonFilestobackupClear_Click(object sender, EventArgs e)
135 | {
136 | comboBoxFilestobackup.Items.Clear();
137 | comboBoxFilestobackup.Text = "";
138 | DisplayText("Successfully cleared list.", 1500, Color.Green);
139 | }
140 |
141 | private void ComboBoxFilestobackup_KeyDown(object sender, KeyEventArgs e) //add or edit items
142 | {
143 | if (e.KeyCode == Keys.Enter)
144 | {
145 | if (!File.Exists(comboBoxFilestobackup.Text) && !Directory.Exists(comboBoxFilestobackup.Text))
146 | {
147 | DisplayText("File or directory does not exist!", 1500, Color.Red);
148 | return;
149 | }
150 |
151 | if (comboBoxFilestobackup.SelectedItem != null) //delete old item and add new
152 | comboBoxFilestobackup.Items.Remove(comboBoxFilestobackup.SelectedItem);
153 |
154 | if (comboBoxFilestobackup.Items.Contains(comboBoxFilestobackup.Text)) //only add if does not exist yet
155 | {
156 | DisplayText("File or directory already exists!", 1500, Color.Red);
157 | return;
158 | }
159 |
160 | comboBoxFilestobackup.Items.Add(comboBoxFilestobackup.Text);
161 | DisplayText("Successfully added item.", 1500, Color.Green);
162 | }
163 | }
164 |
165 | private void ButtonFilestobackupDeleteitem_Click(object sender, EventArgs e)
166 | {
167 | if (comboBoxFilestobackup.SelectedItem != null)
168 | {
169 | comboBoxFilestobackup.Items.Remove(comboBoxFilestobackup.SelectedItem);
170 | comboBoxFilestobackup.Text = "";
171 | DisplayText("Successfully deleted item.", 1500, Color.Green);
172 | }
173 | else
174 | DisplayText("No item to delete!", 1500, Color.Red);
175 |
176 | }
177 |
178 | #endregion
179 |
180 | #region Select Backup Locations
181 |
182 | private void ComboBoxBackupLocations_KeyDown(object sender, KeyEventArgs e)
183 | {
184 | if (e.KeyCode == Keys.Enter)
185 | {
186 | DirectoryInfo dir;
187 | try
188 | {
189 | // Create dir if not exists already
190 | dir = Directory.CreateDirectory(comboBoxBackupLocations.Text);
191 | }
192 | catch (Exception ex)
193 | {
194 | DisplayText(ex.Message, 1500, Color.Red);
195 | return;
196 | }
197 |
198 | if (comboBoxBackupLocations.SelectedItem != null) //delete old item and add new
199 | comboBoxBackupLocations.Items.Remove(comboBoxBackupLocations.SelectedItem);
200 |
201 | if (comboBoxBackupLocations.Items.Contains(dir.FullName))
202 | {
203 | DisplayText("Directory already exists!", 1500, Color.Red);
204 | return;
205 | }
206 |
207 | comboBoxBackupLocations.Items.Add(dir.FullName);
208 | DisplayText("Successfully added path.", 1500, Color.Green);
209 | }
210 | }
211 |
212 | private void ButtonBackupBrowse_Click(object sender, EventArgs e)
213 | {
214 | using (CommonOpenFileDialog cof = new CommonOpenFileDialog { IsFolderPicker = true, Multiselect = true })
215 | {
216 | if (cof.ShowDialog() != CommonFileDialogResult.Ok)
217 | return; //if the user cancels the dialog
218 |
219 | foreach (string s in cof.FileNames)
220 | {
221 | if (!comboBoxBackupLocations.Items.Contains(s)) //only add if not yet added
222 | comboBoxBackupLocations.Items.Add(s);
223 | }
224 |
225 | comboBoxBackupLocations.SelectedItem = comboBoxBackupLocations.Items[comboBoxBackupLocations.Items.Count - 1]; //select last added item
226 | }
227 | }
228 |
229 | private void ButtonBackupLocationsClear_Click(object sender, EventArgs e)
230 | {
231 | comboBoxBackupLocations.Items.Clear();
232 | comboBoxBackupLocations.Text = "";
233 | DisplayText("Successfully cleared list.", 1500, Color.Green);
234 | }
235 |
236 | private void ButtonBackupLocationsDeleteItem_Click(object sender, EventArgs e)
237 | {
238 | if (comboBoxBackupLocations.SelectedItem != null)
239 | {
240 | comboBoxBackupLocations.Items.Remove(comboBoxBackupLocations.SelectedItem);
241 | comboBoxBackupLocations.Text = "";
242 | DisplayText("Successfully deleted item.", 1500, Color.Green);
243 | }
244 | else
245 | DisplayText("No item to delete!", 1500, Color.Red);
246 |
247 | }
248 |
249 | #endregion
250 |
251 | #region Show About
252 |
253 | private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
254 | {
255 | using (FormAbout fa = new FormAbout())
256 | {
257 | fa.ShowDialog();
258 | }
259 | }
260 |
261 | #endregion
262 |
263 | #region Set Backup Name
264 |
265 | private const string BackupNamePlaceholder = "Name Folder/.zip";
266 |
267 | private void TextBoxName_Click(object sender, EventArgs e)
268 | {
269 | if (textBoxName.Text.Equals(BackupNamePlaceholder))
270 | textBoxName.Text = "";
271 | }
272 | //^v when entering the textboxname delete the standard text
273 | private void TextBoxName_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
274 | {
275 | if (textBoxName.Text.Equals(BackupNamePlaceholder))
276 | textBoxName.Text = "";
277 | }
278 |
279 | #endregion
280 |
281 | #region Radio Buttons
282 |
283 | private void RadioButtons_CheckedChanged(object sender, EventArgs e)
284 | {
285 | RadioButton rb = (RadioButton)sender;
286 | if (rb == radioButtonNormal)
287 | {
288 | // Toggle controls, which can only be used when rbfolder or rbzip is checked
289 | textBoxName.Enabled = false;
290 | textBoxName.Text = BackupNamePlaceholder;
291 | checkBoxDate.Enabled = false;
292 | checkBoxDate.Checked = false;
293 | }
294 | else
295 | {
296 | textBoxName.Enabled = true;
297 | checkBoxDate.Enabled = true;
298 | }
299 | }
300 |
301 | #endregion
302 |
303 | /* --- Saved Settings and Locations --- */
304 |
305 | #region Settings Save
306 |
307 | private void SaveDefaultsToolStripMenuItem_Click(object sender, EventArgs e)
308 | {
309 | var settings = Properties.Settings.Default;
310 | settings.AddDate = checkBoxDate.Checked;
311 | settings.Overwrite = checkBoxOverride.Checked;
312 | settings.BackupName = textBoxName.Text;
313 | var inputFiles = new StringCollection();
314 | inputFiles.AddRange(comboBoxFilestobackup.Items.Cast().ToArray());
315 | var outputDirs = new StringCollection();
316 | outputDirs.AddRange(comboBoxBackupLocations.Items.Cast().ToArray());
317 | settings.InputFiles = inputFiles;
318 | settings.OutputDirectories = outputDirs;
319 | settings.BackupMode =
320 | radioButtonZIP.Checked ? (uint)BackupMode.Zip :
321 | radioButtonFolder.Checked ? (uint)BackupMode.Subfolder :
322 | (uint)BackupMode.Copy;
323 |
324 | settings.Save();
325 | DisplayText("Successfully saved default values.", 1500, Color.Green);
326 | }
327 |
328 | #endregion
329 |
330 | #region Save and Open persisted Backup Path files
331 |
332 | private void OpenPaths_Click(object sender, EventArgs e)
333 | {
334 | ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
335 | ComboBox boxToFill;
336 |
337 | if (menuItem == openFilePathsToolStripMenuItem)
338 | boxToFill = comboBoxFilestobackup;
339 | else if (menuItem == openBackupPathsToolStripMenuItem)
340 | boxToFill = comboBoxBackupLocations;
341 | else
342 | throw new NotSupportedException("Invalid menu item.");
343 |
344 | using (OpenFileDialog ofd = new OpenFileDialog { Filter = "Text files|*.txt" })
345 | {
346 | ofd.ShowDialog();
347 | if (ofd.FileName != "")
348 | {
349 | boxToFill.Items.Clear();
350 |
351 | using (StreamReader sr = new StreamReader(ofd.FileName))
352 | {
353 | int linesRead = 0;
354 | while (!sr.EndOfStream)
355 | {
356 | string readData = sr.ReadLine();
357 | // v1.1 Removed restrictions
358 | //if (linesRead > 50 || readData.Length > 200)
359 | // break; //maximum of lines read should be around 50 and max lenght of path should be 200 to prevent memory problems
360 | boxToFill.Items.Add(readData);
361 | linesRead++;
362 | }
363 | }
364 |
365 | if (boxToFill.Items.Count != 0) //select first item, so the user know something is there
366 | boxToFill.SelectedItem = boxToFill.Items[0];
367 |
368 | DisplayText("Successfully opened '" + ofd.FileName + "'", 1500, Color.Green);
369 | }
370 | }
371 | }
372 |
373 | private void SaveCustomFilePathsToolStripMenuItem_Click(object sender, EventArgs e)
374 | {
375 | using (SaveFileDialog sfd = new SaveFileDialog { AddExtension = true, Filter = "Text files|*.txt" })
376 | {
377 | if (sfd.ShowDialog() == DialogResult.OK)
378 | {
379 | using (StreamWriter sw = new StreamWriter(sfd.FileName))
380 | {
381 | foreach (string s in comboBoxFilestobackup.Items)
382 | {
383 | sw.WriteLine(s);
384 | }
385 |
386 | DisplayText("Successfully saved custom file paths.", 1500, Color.Green);
387 | }
388 | }
389 | }
390 | }
391 |
392 | private void SaveCustomBackupPathsToolStripMenuItem_Click(object sender, EventArgs e)
393 | {
394 | using (SaveFileDialog sfd = new SaveFileDialog { AddExtension = true, Filter = "Text files|*.txt" })
395 | {
396 | if (sfd.ShowDialog() == DialogResult.OK)
397 | {
398 | using (StreamWriter sw = new StreamWriter(sfd.FileName))
399 | {
400 | foreach (string s in comboBoxBackupLocations.Items)
401 | {
402 | sw.WriteLine(s);
403 | }
404 |
405 | DisplayText("Successfully saved custom backup paths.", 1500, Color.Green);
406 | }
407 | }
408 |
409 | }
410 | }
411 |
412 | #endregion
413 |
414 | /* ---- Backup Logic --- */
415 |
416 | #region Backup
417 |
418 | private CancellationTokenSource backupCancellation = new CancellationTokenSource();
419 |
420 | private bool ValidateArguments(BackupArguments backupArgs)
421 | {
422 | if (comboBoxFilestobackup.Items.Count == 0) // If no files to backup are given
423 | {
424 | DisplayText("No file selected!", 1500, Color.Red);
425 | return false;
426 | }
427 |
428 | if (comboBoxBackupLocations.Items.Count == 0) // If no backup locations are given
429 | {
430 | DisplayText("No backup path set!", 1500, Color.Red);
431 | return false;
432 | }
433 |
434 | // Check if files still exist
435 | foreach (string s in backupArgs.InputFiles)
436 | {
437 | if (!File.Exists(s) && !Directory.Exists(s))
438 | {
439 | DisplayText("'" + s + "' does not exist!", 1500, Color.Red);
440 | return false;
441 | }
442 | }
443 |
444 | // Check if the folder/zip is named
445 | if ((radioButtonFolder.Checked || radioButtonZIP.Checked) && (textBoxName.Text.Equals("Name Folder/.zip") || (textBoxName.Text.Trim().Equals(""))))
446 | {
447 | DisplayText("Please enter a name for your Folder/.zip!", 1500, Color.Red);
448 | return false;
449 | }
450 |
451 | return true;
452 | }
453 |
454 | private async void ButtonOK_Click(object sender, EventArgs e)
455 | {
456 | DateTime dt = DateTime.Now; // For adding date to file names
457 | BackupArguments backupArgs = new BackupArguments(comboBoxFilestobackup.Items.Cast(), comboBoxBackupLocations.Items.Cast(), checkBoxOverride.Checked);
458 |
459 | // First validate input
460 | if (!ValidateArguments(backupArgs)) return;
461 |
462 | ResetBackupUi();
463 |
464 | backupCancellation?.Cancel(); // Cancel currently running backup if not cancelled already
465 | var currentTokenSource = new CancellationTokenSource();
466 | backupCancellation = currentTokenSource;
467 | BackupWriterFactory factory = new BackupWriterFactory(backupArgs);
468 | BackupMetadataInfo meta = await BackupMetadataInfo.FromBackupArgumentsAsync(backupArgs);
469 | BackupProgress progress = new BackupProgress(ReportBackupProgress, meta);
470 | IBackupWriter writer;
471 |
472 | if (radioButtonNormal.Checked) { writer = factory.CreateCopyFileBackupWriter(); }
473 | else if (radioButtonFolder.Checked) { writer = checkBoxDate.Checked ? factory.CreateSubfolderCopyBackupWriter(textBoxName.Text, dt) : factory.CreateSubfolderCopyBackupWriter(textBoxName.Text); }
474 | else if (radioButtonZIP.Checked) { writer = checkBoxDate.Checked ? factory.CreateZipBackupWriter(textBoxName.Text, dt) : factory.CreateZipBackupWriter(textBoxName.Text); }
475 | else { throw new NotSupportedException("Unsupported BackupWriter."); }
476 |
477 | labelProgress.Text = string.Format("{0} files and {1:n0} KB input", meta.FileCount, meta.FileSizeSum / 1000);
478 |
479 | try
480 | {
481 | await writer.ExecuteAsync(currentTokenSource.Token, progress);
482 | progressBarMain.Value = 100;
483 | DisplayText("File backup successful.", 3000, Color.Green);
484 | }
485 | catch (Exception ex)
486 | {
487 | progressBarMain.Value = 0;
488 | if (ex is OperationCanceledException)
489 | DisplayText("Successfully cancelled Backup.", 3000, Color.Green);
490 | else
491 | DisplayText(ex.Message, 3000, Color.Red);
492 | }
493 | finally
494 | {
495 | buttonOK.Visible = true; // Enable controls again
496 | buttonCancel.Visible = false;
497 | groupBoxSettings.Enabled = true;
498 | backupCancellation = null;
499 | currentTokenSource.Dispose();
500 | }
501 | }
502 |
503 | private void ButtonCancel_Click(object sender, EventArgs e)
504 | {
505 | backupCancellation.Cancel();
506 | DisplayText("Cancellation requested.", 3000, Color.Black);
507 | buttonCancel.Enabled = false;
508 | }
509 |
510 | private void ReportBackupProgress(BackupProgressInfo info)
511 | {
512 | progressBarMain.Value = (int)(info.PercentDone * 100);
513 | labelProgress.Text = labelProgress.Text.Split('\n')[0]
514 | + string.Format("\n{0:n0} KB written to output", info.BytesBackedUp / 1000);
515 | }
516 |
517 | private void ResetBackupUi()
518 | {
519 | buttonOK.Visible = false; // Disable and switch controls in the meantime
520 | buttonCancel.Visible = true;
521 | buttonCancel.Enabled = true;
522 | groupBoxSettings.Enabled = false;
523 | progressBarMain.Value = 0;
524 | labelProgress.Text = "";
525 | }
526 |
527 | #endregion
528 | }
529 | }
530 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/FormMain.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 |
125 |
126 | AAABAAEAICAAAAEACACoCAAAFgAAACgAAAAgAAAAQAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
127 | AAAAAAAAAQEBAAkJCQAPDw8AEhISABQUFAA4ODgASEhIALa2tgC7u7sA8/PzAPT09AD///8AAAAAAAAA
128 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
129 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
130 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
131 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
132 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
133 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
134 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
135 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
136 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
137 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
138 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
139 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
140 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
141 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
142 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
143 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
144 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
145 | AAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAMCQgICAgICAgICAgI
146 | CAgICAgICAkMAAAAAAAAAAAAAAwDAAAAAAAAAAAAAAAAAAAAAAAAAwwAAAAAAAAAAAAADAUAAAAAAAAA
147 | AAAAAAAAAAAAAAAFDAAAAAAAAAAAAAAMBQAAAAAAAAwAAAAADAAAAAAAAAUMAAAAAAAAAAAAAAwFAAAA
148 | AAAADAwMDAwMAAAAAAAABQwAAAAAAAAAAAAADAUAAAAAAAAADAwMDAAAAAAAAAAFDAAAAAAAAAAAAAAM
149 | BQAAAAAAAAAAAAAAAAAAAAAAAAUMAAAAAAAAAAAAAAwCAAAAAAAAAAAAAAAAAAAAAAAAAgwAAAAAAAAA
150 | AAAADAsKCgoKCgoKCgoKCgoKCgoKCgoLDAAAAAAAAAAAAAAMBwYGBgYGBgYGBgYGBgYGBgYGBgcMAAAA
151 | AAAAAAAAAAwFAAAAAAAAAAAAAAAAAAAAAAAABQwAAAAAAAAAAAAADAUAAAAAAAAAAAAAAAAAAAAAAAAF
152 | DAAAAAAAAAAAAAAMBQAAAAAAAAwAAAAADAAAAAAAAAUMAAAAAAAAAAAAAAwFAAAAAAAADAwMDAwMAAAA
153 | AAAABQwAAAAAAAAAAAAADAUAAAAAAAAADAwMDAAAAAAAAAAFDAAAAAAAAAAAAAAMBQAAAAAAAAAAAAAA
154 | AAAAAAAAAAUMAAAAAAAAAAAAAAwHBgYGBgYGBgYGBgYGBgYGBgYGBwwAAAAAAAAAAAAADAsKCgoKCgoK
155 | CgoKCgoKCgoKCgoLDAAAAAAAAAAAAAAMAgAAAAAAAAAAAAAAAAAAAAAAAAIMAAAAAAAAAAAAAAwFAAAA
156 | AAAAAAAAAAAAAAAAAAAABQwAAAAAAAAAAAAADAUAAAAAAAAMAQAAAQwAAAAAAAAFDAAAAAAAAAAAAAAM
157 | BQAAAAAAAAwMDAwMDAAAAAAAAAUMAAAAAAAAAAAAAAwFAAAAAAAABAwMDAwEAAAAAAAABQwAAAAAAAAA
158 | AAAADAUAAAAAAAAAAAAAAAAAAAAAAAAFDAAAAAAAAAAAAAAMAwAAAAAAAAAAAAAAAAAAAAAAAAMMAAAA
159 | AAAAAAAAAAwJCAgICAgICAgICAgICAgICAgICQwAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwM
160 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
161 | AAAAAAAAAAAAAP///////////AAAP/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/gA
162 | AB/4AAAf+AAAH/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/gA
163 | AB/4AAAf/AAAP///////////
164 |
165 |
166 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Program.cs:
--------------------------------------------------------------------------------
1 | using SimpleFileBackup.Core;
2 | using SimpleFileBackup.Core.Data;
3 | using SimpleFileBackup.Core.Progress;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 |
10 | namespace SimpleFileBackup.Windows
11 | {
12 | static class Program
13 | {
14 | ///
15 | /// The main entry point for the application.
16 | ///
17 | [STAThread]
18 | static void Main()
19 | {
20 | Application.EnableVisualStyles();
21 | Application.SetCompatibleTextRenderingDefault(false);
22 | Application.Run(new FormMain());
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SimpleFileBackup Windows GUI")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SimpleFileBackup")]
13 | [assembly: AssemblyCopyright("")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("2753db89-6f2b-495a-80fc-7f9155dbd2a0")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.1.0.0")]
36 | [assembly: AssemblyFileVersion("1.1.0.0")]
37 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SimpleFileBackup.Windows.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SimpleFileBackup.Windows.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to <!DOCTYPE html>
65 | ///<html>
66 | ///<head>
67 | /// <meta charset="utf-8" />
68 | /// <title></title>
69 | ///</head>
70 | ///<body style="font-family:arial;">
71 | /// <center>
72 | /// <h1>Simple File Backup Windows</h1>
73 | /// Program by Marcel Salvenmoser
74 | /// <br>
75 | /// <br>
76 | /// <h3>General</h3>
77 | /// Select files or folders by pressing the Select buttons on the right. You can select multiple files or folders at once.
78 | /// After pressing OK the file locations will be saved in the drop down list. You can also add files [rest of string was truncated]";.
79 | ///
80 | internal static string about {
81 | get {
82 | return ResourceManager.GetString("about", resourceCulture);
83 | }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\about.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
123 |
124 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SimpleFileBackup.Windows.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | public global::System.Collections.Specialized.StringCollection InputFiles {
29 | get {
30 | return ((global::System.Collections.Specialized.StringCollection)(this["InputFiles"]));
31 | }
32 | set {
33 | this["InputFiles"] = value;
34 | }
35 | }
36 |
37 | [global::System.Configuration.UserScopedSettingAttribute()]
38 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
39 | public global::System.Collections.Specialized.StringCollection OutputDirectories {
40 | get {
41 | return ((global::System.Collections.Specialized.StringCollection)(this["OutputDirectories"]));
42 | }
43 | set {
44 | this["OutputDirectories"] = value;
45 | }
46 | }
47 |
48 | [global::System.Configuration.UserScopedSettingAttribute()]
49 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
50 | [global::System.Configuration.DefaultSettingValueAttribute("0")]
51 | public uint BackupMode {
52 | get {
53 | return ((uint)(this["BackupMode"]));
54 | }
55 | set {
56 | this["BackupMode"] = value;
57 | }
58 | }
59 |
60 | [global::System.Configuration.UserScopedSettingAttribute()]
61 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
62 | [global::System.Configuration.DefaultSettingValueAttribute("")]
63 | public string BackupName {
64 | get {
65 | return ((string)(this["BackupName"]));
66 | }
67 | set {
68 | this["BackupName"] = value;
69 | }
70 | }
71 |
72 | [global::System.Configuration.UserScopedSettingAttribute()]
73 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
74 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
75 | public bool AddDate {
76 | get {
77 | return ((bool)(this["AddDate"]));
78 | }
79 | set {
80 | this["AddDate"] = value;
81 | }
82 | }
83 |
84 | [global::System.Configuration.UserScopedSettingAttribute()]
85 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
86 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
87 | public bool Overwrite {
88 | get {
89 | return ((bool)(this["Overwrite"]));
90 | }
91 | set {
92 | this["Overwrite"] = value;
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 0
13 |
14 |
15 |
16 |
17 |
18 | False
19 |
20 |
21 | False
22 |
23 |
24 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
55 |
56 |
70 |
--------------------------------------------------------------------------------
/SimpleFileBackup.Windows/Resources/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Simple File Backup Windows
10 | Program by Marcel Salvenmoser
11 |
12 |
13 |
General
14 | Select files or folders by pressing the Select buttons on the right. You can select multiple files or folders at once.
15 | After pressing OK the file locations will be saved in the drop down list. You can also add files by typing the path in the textbox and pressing enter. If you made a wrong selection, you can delete single items by selecting them in the drop down list and pressing "Delete Item".
16 | You can clear the list by pressing "Clear List".
17 |
18 |
19 | Backup Destinations can be selected through the same process. Every file or folder in "Files to Backup" will be backed up to every "Backup Destination".
20 |
21 |
22 |
Settings
23 | Override idenetical files in directory
24 |
25 |
26 | If you want to replace your old files with the new files enable the "Override identical files in directory" option.
27 | This way, if a file called 123.jpg is already in the directory, it will be replaced. Same goes for ZIP files.
28 |
29 |
30 | Put files in given directory
31 |
32 |
33 | Copies the files and folders into the selected directories.
34 |
35 |
36 | Create a subfolder in directory
37 |
38 |
39 | Creates a subfolder in every given directory with the provided name.
40 |
41 |
42 | Create a .zip file in directory
43 |
44 |
45 | Create a .zip with the provided name from the given files and folders and copy it to every listed directory.
46 |
47 |
48 | Name Folder/.zip
49 |
50 |
51 | Only works when "Create a subfolder in directory" or "Create a .zip file in directory" is selected.
52 |
53 | You can name your folder or .zip file with a maximum of 20 characters. The characters have to be compatible with the windows filesystem.
54 |
55 |
56 | Add date to Folder/.zip name
57 |
58 |
59 | Adds your local date to the folder/.zip name in the format name_10-10-2010.
60 |
61 |
62 | Save Defaults
63 |
64 |
65 | Saves your file/backup locations and settings to keep them for the next program start.
66 |
67 |
68 | Save Custom File Paths & Save Custom Backup Paths
69 |
70 |
71 | Saves your file/backup locations in a text file you can choose the location of.
72 |
73 |
74 | Open File Paths & Open Backup Paths
75 |
76 |
77 | You can open a text file that contains paths to files or directories. These paths will be inserted into the drop down list.
78 |
79 |
80 |
88 |
89 |
90 |
91 | This is my first publicly released program. I made it because I needed a tool to backup files to more locations at once and I wanted to code something in my summer holidays. I do not expect much from this program but any feedback or criticism is appreciated.
92 |
93 |