Merge branch 'master' into feature/fix_for_different_blockhash_and_filehash_plus_multiblocks_metadata

# Conflicts:
#	Duplicati/Library/Main/Database/LocalDatabase.cs
#	Duplicati/Library/Main/Database/LocalRecreateDatabase.cs
#	Duplicati/Library/Main/Operation/RecreateDatabaseHandler.cs
#	Duplicati/UnitTest/BorderTests.cs
This commit is contained in:
Kenneth Skovhede
2016-10-17 13:28:27 +02:00
666 changed files with 62377 additions and 56904 deletions
+2
View File
@@ -20,3 +20,5 @@ Installer/oem
Updates/build
packages
changelog-news.txt
binfiles.wxs
.idea/
+61 -7
View File
@@ -2,20 +2,74 @@ language: csharp
solution: Duplicati.sln
install:
- nuget restore Duplicati.sln
- nuget install NUnit.Runners -Version 2.6.4 -OutputDirectory testrunner
- nuget install NUnit.Runners -Version 3.4.1 -OutputDirectory testrunner
- sudo pip install selenium
addons:
sauce_connect:
username: $SAUCE_USERNAME
access_key: $SAUCE_ACCESS_KEY
env:
general:
- USAGEREPORTER_Duplicati_LEVEL=none
- AUTOUPDATER_Duplicati_SKIP_UPDATE=1
matrix:
- JOB=job1
- JOB=job2
notifications:
webhooks:
urls:
- $GITTER_WEBHOOK_URL
on_success: always
on_failure: always
on_start: never
cache:
directories:
- $HOME/download
script:
# build duplicati
- echo "travis_fold:start:build_duplicati"
- xbuild /p:Configuration=Release Duplicati.sln
- echo "travis_fold:end:build_duplicati"
- cp -r ./Duplicati/Server/webroot ./Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release/webroot
# download and extract testdata
- echo "travis_fold:start:download_extract_testdata"
- ls -la .
- if [ ! -d ~/download ]; then mkdir ~/download; fi
- if [ ! -f ~/download/DSMCBE.zip ]; then wget "https://s3.amazonaws.com/duplicati-test-file-hosting/DSMCBE.zip" -O ~/download/DSMCBE.zip; fi
- if [ ! -f ~/download/data.zip ]; then wget "https://s3.amazonaws.com/duplicati-test-file-hosting/data.zip" -O ~/download/data.zip; fi
- ls -la .
- mkdir ~/testdata
- mkdir ~/testdata/data
- mkdir ~/testdata/DSMCBE
- wget "https://s3.amazonaws.com/duplicati-test-file-hosting/DSMCBE.zip"
- wget "https://s3.amazonaws.com/duplicati-test-file-hosting/data.zip"
- unzip -q DSMCBE.zip -d ~/testdata/
- unzip -q data.zip -d ~/testdata/
- unzip -q ~/download/DSMCBE.zip -d ~/testdata/
- unzip -q ~/download/data.zip -d ~/testdata/
- chown -R travis ~/testdata/
- chmod -R 755 ~/testdata
- ls -la ~/testdata
- ls -la ~/testdata/DSMCBE
- ls -la ~/testdata/data
- export USAGEREPORTER_Duplicati_LEVEL=none
- mono ./testrunner/NUnit.Runners.2.6.4/tools/nunit-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll
- echo "travis_fold:end:download_extract_testdata"
# run unit tests
- echo "travis_fold:start:unit_tests_border"
- if [[ "$JOB" == "job1" ]]; then mono ./testrunner/NUnit.ConsoleRunner.3.4.1/tools/nunit3-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll --where:cat==Border --workers=1; fi
- echo "travis_fold:end:unit_tests_border"
- echo "travis_fold:start:unit_tests_bulknormal"
- if [[ "$JOB" == "job2" ]]; then mono ./testrunner/NUnit.ConsoleRunner.3.4.1/tools/nunit3-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll --where:cat==BulkNormal --workers=1; fi
- echo "travis_fold:end:unit_tests_bulknormal"
- echo "travis_fold:start:unit_tests_bulknosize"
- if [[ "$JOB" == "job2" ]]; then mono ./testrunner/NUnit.ConsoleRunner.3.4.1/tools/nunit3-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll --where:cat==BulkNoSize --workers=1; fi
- echo "travis_fold:end:unit_tests_bulknosize"
- echo "travis_fold:start:unit_tests_svndata"
- if [[ "$JOB" == "job1" ]]; then mono ./testrunner/NUnit.ConsoleRunner.3.4.1/tools/nunit3-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll --where:cat==SVNData --workers=1; fi
- echo "travis_fold:end:unit_tests_svndata"
- echo "travis_fold:start:unit_tests_svndatalong"
- if [[ "$JOB" == "job1" ]]; then mono ./testrunner/NUnit.ConsoleRunner.3.4.1/tools/nunit3-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll --where:cat==SVNDataLong --workers=1; fi
- echo "travis_fold:end:unit_tests_svndatalong"
- echo "travis_fold:start:unit_tests_targeted"
- if [[ "$JOB" == "job1" ]]; then mono ./testrunner/NUnit.ConsoleRunner.3.4.1/tools/nunit3-console.exe ./Duplicati/UnitTest/bin/Release/Duplicati.UnitTest.dll --where:cat==Targeted --workers=1; fi
- echo "travis_fold:end:unit_tests_targeted"
# start server and run gui tests
- mono ./Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release/Duplicati.Server.exe &
- if [[ "$JOB" == "job2" ]]; then python guiTests/guiTest.py; fi
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{fill:#D0CDC6;}
.st2{fill:#FFFFFF;}
.st3{fill:#1D4775;}
.st4{fill:#8194A9;}
.st5{fill:#EBF1F5;}
.st6{fill:#65B1DD;}
.st7{fill:#336697;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-16" y="-16" width="64" height="64"/>
<rect id="win2k" x="-16" y="-16" class="st1" width="64" height="64"/>
<rect id="white" x="-16" y="-16" class="st2" width="64" height="64"/>
<rect id="win7_aero" x="-16" y="-16" class="st3" width="64" height="64"/>
<rect id="win7_1_" x="-16" y="-16" class="st4" width="64" height="64"/>
<rect id="macosx" x="-16" y="-16" class="st5" width="64" height="64"/>
</g>
<g id="icon">
<g id="small_8_">
<path class="st6" d="M15,28c-1.7,0-3-1.3-3-3v-5c0-1.7,1.3-3,3-3h8c1.7,0,3,1.3,3,3v5c0,1.7-1.3,3-3,3H15z"/>
<path class="st2" d="M23,18c1.1,0,2,0.9,2,2v5c0,1.1-0.9,2-2,2h-8c-1.1,0-2-0.9-2-2v-5c0-1.1,0.9-2,2-2H23 M23,16h-8
c-2.2,0-4,1.8-4,4v5c0,2.2,1.8,4,4,4h8c2.2,0,4-1.8,4-4v-5C27,17.8,25.2,16,23,16L23,16z"/>
</g>
<g id="middle_8_">
<path class="st7" d="M4,30c-1.7,0-3-1.3-3-3v-7c0-1.7,1.3-3,3-3h10c1.7,0,3,1.3,3,3v7c0,1.7-1.3,3-3,3H4z"/>
<path class="st2" d="M14,18c1.1,0,2,0.9,2,2v7c0,1.1-0.9,2-2,2H4c-1.1,0-2-0.9-2-2v-7c0-1.1,0.9-2,2-2H14 M14,16H4
c-2.2,0-4,1.8-4,4v7c0,2.2,1.8,4,4,4h10c2.2,0,4-1.8,4-4v-7C18,17.8,16.2,16,14,16L14,16z"/>
</g>
<g id="big_10_">
<path class="st3" d="M12,21c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h16c1.7,0,3,1.3,3,3v12c0,1.7-1.3,3-3,3H12z"/>
<path class="st2" d="M28,4c1.1,0,2,0.9,2,2v12c0,1.1-0.9,2-2,2H12c-1.1,0-2-0.9-2-2V6c0-1.1,0.9-2,2-2H28 M28,2H12
C9.8,2,8,3.8,8,6v12c0,2.2,1.8,4,4,4h16c2.2,0,4-1.8,4-4V6C32,3.8,30.2,2,28,2L28,2z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+36
View File
@@ -0,0 +1,36 @@
@echo off
rem ImageMagick and inkscape needed
mkdir temp
inkscape -z -e temp/application_16.png -w 16 -h 16 application_icon.svg
inkscape -z -e temp/application_20.png -w 20 -h 20 application_icon.svg
inkscape -z -e temp/application_24.png -w 24 -h 24 application_icon.svg
inkscape -z -e temp/application_32.png -w 32 -h 32 application_icon.svg
inkscape -z -e temp/application_40.png -w 40 -h 40 application_icon.svg
inkscape -z -e temp/application_48.png -w 48 -h 48 application_icon.svg
inkscape -z -e temp/application_64.png -w 64 -h 64 application_icon.svg
inkscape -z -e temp/application_96.png -w 96 -h 96 application_icon.svg
inkscape -z -e temp/application_256.png -w 256 -h 256 application_icon.svg
mkdir osx_appicon
inkscape -z -e osx_appicon/icon_16x16.png -w 16 -h 16 application_icon.svg
inkscape -z -e osx_appicon/icon_16x16@2x.png -w 32 -h 32 application_icon.svg
inkscape -z -e osx_appicon/icon_32x32.png -w 32 -h 32 application_icon.svg
inkscape -z -e osx_appicon/icon_32x32@2x.png -w 64 -h 64 application_icon.svg
inkscape -z -e osx_appicon/icon_64x64.png -w 64 -h 64 application_icon.svg
inkscape -z -e osx_appicon/icon_64x64@2x.png -w 128 -h 128 application_icon.svg
inkscape -z -e osx_appicon/icon_128x128.png -w 128 -h 128 application_icon.svg
inkscape -z -e osx_appicon/icon_128x128@2x.png -w 256 -h 256 application_icon.svg
inkscape -z -e osx_appicon/icon_256x256.png -w 256 -h 256 application_icon.svg
inkscape -z -e osx_appicon/icon_256x256@2x.png -w 512 -h 512 application_icon.svg
inkscape -z -e osx_appicon/icon_512x512.png -w 512 -h 512 application_icon.svg
inkscape -z -e osx_appicon/icon_512x512@2x.png -w 1024 -h 1024 application_icon.svg
rem On OSX, the icns is created by:
rem mv osx_appicon osx_appicon.iconset
rem iconutil -c icns osx_appicon.iconset
convert temp/application_16.png temp/application_20.png temp/application_24.png temp/application_32.png temp/application_40.png temp/application_48.png temp/application_64.png temp/application_96.png temp/application_256.png application_icon.ico
rd /s /q temp
pause
Binary file not shown.
-32
View File
@@ -1,32 +0,0 @@
@echo off
rem ImageMagick and inkscape needed
mkdir pngs
inkscape -z -e pngs\error_16.png -w 16 -h 16 tray_icons_error.svg
inkscape -z -e pngs\error_24.png -w 24 -h 24 tray_icons_error.svg
inkscape -z -e pngs\error_32.png -w 32 -h 32 tray_icons_error.svg
inkscape -z -e pngs\error_48.png -w 48 -h 48 tray_icons_error.svg
inkscape -z -e pngs\error_256.png -w 256 -h 256 tray_icons_error.svg
inkscape -z -e pngs\inactive_16.png -w 16 -h 16 tray_icons_inactive.svg
inkscape -z -e pngs\inactive_24.png -w 24 -h 24 tray_icons_inactive.svg
inkscape -z -e pngs\inactive_32.png -w 32 -h 32 tray_icons_inactive.svg
inkscape -z -e pngs\inactive_48.png -w 48 -h 48 tray_icons_inactive.svg
inkscape -z -e pngs\inactive_256.png -w 256 -h 256 tray_icons_inactive.svg
inkscape -z -e pngs\paused_16.png -w 16 -h 16 tray_icons_paused.svg
inkscape -z -e pngs\paused_24.png -w 24 -h 24 tray_icons_paused.svg
inkscape -z -e pngs\paused_32.png -w 32 -h 32 tray_icons_paused.svg
inkscape -z -e pngs\paused_48.png -w 48 -h 48 tray_icons_paused.svg
inkscape -z -e pngs\paused_256.png -w 256 -h 256 tray_icons_paused.svg
inkscape -z -e pngs\running_16.png -w 16 -h 16 tray_icons_running.svg
inkscape -z -e pngs\running_24.png -w 24 -h 24 tray_icons_running.svg
inkscape -z -e pngs\running_32.png -w 32 -h 32 tray_icons_running.svg
inkscape -z -e pngs\running_48.png -w 48 -h 48 tray_icons_running.svg
inkscape -z -e pngs\running_256.png -w 256 -h 256 tray_icons_running.svg
convert pngs\error_16.png pngs\error_24.png pngs\error_32.png pngs\error_48.png pngs\error_256.png error.ico
convert pngs\inactive_16.png pngs\inactive_24.png pngs\inactive_32.png pngs\inactive_48.png pngs\inactive_256.png inactive.ico
convert pngs\paused_16.png pngs\paused_24.png pngs\paused_32.png pngs\paused_48.png pngs\paused_256.png paused.ico
convert pngs\running_16.png pngs\running_24.png pngs\running_32.png pngs\running_48.png pngs\running_256.png running.ico
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,35 @@
@echo off
rem ImageMagick and inkscape needed
mkdir temp
inkscape -z -e temp/pause_16.png -w 16 -h 16 tray_context_menu_pause.svg
inkscape -z -e temp/pause_24.png -w 24 -h 24 tray_context_menu_pause.svg
inkscape -z -e temp/pause_32.png -w 32 -h 32 tray_context_menu_pause.svg
inkscape -z -e temp/pause_48.png -w 48 -h 48 tray_context_menu_pause.svg
inkscape -z -e temp/pause_256.png -w 256 -h 256 tray_context_menu_pause.svg
inkscape -z -e temp/resume_16.png -w 16 -h 16 tray_context_menu_resume.svg
inkscape -z -e temp/resume_24.png -w 24 -h 24 tray_context_menu_resume.svg
inkscape -z -e temp/resume_32.png -w 32 -h 32 tray_context_menu_resume.svg
inkscape -z -e temp/resume_48.png -w 48 -h 48 tray_context_menu_resume.svg
inkscape -z -e temp/resume_256.png -w 256 -h 256 tray_context_menu_resume.svg
inkscape -z -e temp/open_16.png -w 16 -h 16 tray_context_menu_open.svg
inkscape -z -e temp/open_24.png -w 24 -h 24 tray_context_menu_open.svg
inkscape -z -e temp/open_32.png -w 32 -h 32 tray_context_menu_open.svg
inkscape -z -e temp/open_48.png -w 48 -h 48 tray_context_menu_open.svg
inkscape -z -e temp/open_256.png -w 256 -h 256 tray_context_menu_open.svg
inkscape -z -e temp/quit_16.png -w 16 -h 16 tray_context_menu_quit.svg
inkscape -z -e temp/quit_24.png -w 24 -h 24 tray_context_menu_quit.svg
inkscape -z -e temp/quit_32.png -w 32 -h 32 tray_context_menu_quit.svg
inkscape -z -e temp/quit_48.png -w 48 -h 48 tray_context_menu_quit.svg
inkscape -z -e temp/quit_256.png -w 256 -h 256 tray_context_menu_quit.svg
convert temp/pause_16.png temp/pause_24.png temp/pause_32.png temp/pause_48.png temp/pause_256.png context_menu_pause.ico
convert temp/resume_16.png temp/resume_24.png temp/resume_32.png temp/resume_48.png temp/resume_256.png context_menu_play.ico
convert temp/open_16.png temp/open_24.png temp/open_32.png temp/open_48.png temp/open_256.png context_menu_open.ico
convert temp/quit_16.png temp/quit_24.png temp/quit_32.png temp/quit_48.png temp/quit_256.png context_menu_quit.ico
rd /s /q temp
pause
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,13 @@
<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<defs>
<style>
.cls-1 {
fill: #65b1dd;
}
</style>
</defs>
<title>tray context menu icons</title>
<g id="show_Kopie" data-name="show Kopie">
<polygon class="cls-1" points="8 4.001 2 10.301 3.5 11.876 8 7.072 12.5 11.876 14 10.301 8 4.001"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 427 B

@@ -0,0 +1,14 @@
<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<defs>
<style>
.cls-1 {
fill: #65b1dd;
}
</style>
</defs>
<title>tray context menu icons</title>
<g id="pause_Kopie" data-name="pause Kopie">
<rect class="cls-1" x="4" y="2" width="3" height="12"/>
<rect class="cls-1" x="9" y="2" width="3" height="12"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 445 B

@@ -0,0 +1,13 @@
<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="15.997" height="16" viewBox="0 0 15.997 16">
<defs>
<style>
.cls-1 {
fill: #65b1dd;
}
</style>
</defs>
<title>tray context menu icons</title>
<g id="stop_Kopie" data-name="stop Kopie">
<polygon id="stop" class="cls-1" points="13.998 3.95 12.048 2 7.998 6.05 3.948 2 1.998 3.95 6.049 8 1.998 12.05 3.948 14 7.998 9.95 12.048 14 13.998 12.05 9.949 8 13.998 3.95"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 513 B

@@ -0,0 +1,13 @@
<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<defs>
<style>
.cls-1 {
fill: #65b1dd;
}
</style>
</defs>
<title>tray context menu icons</title>
<g id="resume_Kopie" data-name="resume Kopie">
<polygon class="cls-1" points="5 14 13 8 5 2 5 14"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 384 B

+35
View File
@@ -0,0 +1,35 @@
@echo off
rem ImageMagick and inkscape needed
mkdir temp
inkscape -z -e temp/error_16.png -w 16 -h 16 tray_icons_error.svg
inkscape -z -e temp/error_24.png -w 24 -h 24 tray_icons_error.svg
inkscape -z -e temp/error_32.png -w 32 -h 32 tray_icons_error.svg
inkscape -z -e temp/error_48.png -w 48 -h 48 tray_icons_error.svg
inkscape -z -e temp/error_256.png -w 256 -h 256 tray_icons_error.svg
inkscape -z -e temp/inactive_16.png -w 16 -h 16 tray_icons_inactive.svg
inkscape -z -e temp/inactive_24.png -w 24 -h 24 tray_icons_inactive.svg
inkscape -z -e temp/inactive_32.png -w 32 -h 32 tray_icons_inactive.svg
inkscape -z -e temp/inactive_48.png -w 48 -h 48 tray_icons_inactive.svg
inkscape -z -e temp/inactive_256.png -w 256 -h 256 tray_icons_inactive.svg
inkscape -z -e temp/paused_16.png -w 16 -h 16 tray_icons_paused.svg
inkscape -z -e temp/paused_24.png -w 24 -h 24 tray_icons_paused.svg
inkscape -z -e temp/paused_32.png -w 32 -h 32 tray_icons_paused.svg
inkscape -z -e temp/paused_48.png -w 48 -h 48 tray_icons_paused.svg
inkscape -z -e temp/paused_256.png -w 256 -h 256 tray_icons_paused.svg
inkscape -z -e temp/running_16.png -w 16 -h 16 tray_icons_running.svg
inkscape -z -e temp/running_24.png -w 24 -h 24 tray_icons_running.svg
inkscape -z -e temp/running_32.png -w 32 -h 32 tray_icons_running.svg
inkscape -z -e temp/running_48.png -w 48 -h 48 tray_icons_running.svg
inkscape -z -e temp/running_256.png -w 256 -h 256 tray_icons_running.svg
convert temp/error_16.png temp/error_24.png temp/error_32.png temp/error_48.png temp/error_256.png error.ico
convert temp/inactive_16.png temp/inactive_24.png temp/inactive_32.png temp/inactive_48.png temp/inactive_256.png inactive.ico
convert temp/paused_16.png temp/paused_24.png temp/paused_32.png temp/paused_48.png temp/paused_256.png paused.ico
convert temp/running_16.png temp/running_24.png temp/running_32.png temp/running_48.png temp/running_256.png running.ico
rd /s /q temp
pause
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long
+83
View File
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{display:inline;fill:#FAF1F5;}
.st8{opacity:0.74;}
.st9{fill:#C91517;}
.st10{display:inline;fill:#C91517;}
.st11{display:inline;fill:#FFFFFF;}
.st12{display:none;fill:#C91517;}
.st13{display:inline;fill:#2C933D;}
.st14{display:inline;opacity:0.87;fill:#FFFFFF;stroke:#000000;stroke-width:1.75;stroke-miterlimit:10;}
.st15{fill:#2C933D;}
.st16{display:none;fill:#2C933D;}
.st17{fill:#676767;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-88" y="-16" class="st1" width="120" height="80"/>
<rect id="win2k" x="-88" y="-16" class="st2" width="120" height="80"/>
<rect id="white" x="-88" y="-16" class="st3" width="120" height="80"/>
<rect id="win7_aero" x="-88" y="-16" class="st4" width="120" height="80"/>
<rect id="win7_1_" x="-88" y="-16" class="st5" width="120" height="80"/>
<rect id="macosx" x="-88" y="-16" class="st6" width="120" height="80"/>
<rect id="macosx2" x="-88" y="-16" class="st7" width="120" height="80"/>
</g>
<g id="_x31_8x18_optimized__x28_OSX_x29_">
<g id="error_mono">
<g id="cross">
</g>
<g id="error_1_" class="st0">
</g>
</g>
<g id="paused_mono">
<g id="pause">
</g>
<g id="pause_Kopie" class="st0">
</g>
</g>
<g id="inactive_mono">
<g id="based_on" class="st0">
</g>
</g>
<g id="running_mono">
</g>
</g>
<g id="_x31_6x16_optimized__x28_Win_x29_">
<g id="error">
<g id="small_6_">
<path class="st9" d="M8.5,13.5c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2h3c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H8.5z"/>
<path class="st3" d="M11.5,9c0.8,0,1.5,0.7,1.5,1.5v1c0,0.8-0.7,1.5-1.5,1.5h-3C7.7,13,7,12.3,7,11.5v-1C7,9.7,7.7,9,8.5,9H11.5
M11.5,8h-3C7.1,8,6,9.1,6,10.5v1C6,12.9,7.1,14,8.5,14h3c1.4,0,2.5-1.1,2.5-2.5v-1C14,9.1,12.9,8,11.5,8L11.5,8z"/>
</g>
<g id="middle_6_">
<path class="st9" d="M3,14.5c-1.4,0-2.5-1.1-2.5-2.5v-1c0-1.4,1.1-2.5,2.5-2.5h3c1.4,0,2.5,1.1,2.5,2.5v1c0,1.4-1.1,2.5-2.5,2.5
H3z"/>
<path class="st3" d="M6,9c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H3c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2H6 M6,8H3c-1.7,0-3,1.3-3,3v1
c0,1.7,1.3,3,3,3h3c1.7,0,3-1.3,3-3v-1C9,9.3,7.7,8,6,8L6,8z"/>
</g>
<g id="big_6_">
<path class="st9" d="M7,10.5c-1.4,0-2.5-1.1-2.5-2.5V4c0-1.4,1.1-2.5,2.5-2.5h6c1.4,0,2.5,1.1,2.5,2.5v4c0,1.4-1.1,2.5-2.5,2.5H7
z"/>
<path class="st3" d="M13,2c1.1,0,2,0.9,2,2v4c0,1.1-0.9,2-2,2H7c-1.1,0-2-0.9-2-2V4c0-1.1,0.9-2,2-2H13 M13,1H7C5.3,1,4,2.3,4,4
v4c0,1.7,1.3,3,3,3h6c1.7,0,3-1.3,3-3V4C16,2.3,14.7,1,13,1L13,1z"/>
</g>
<rect x="9.5" y="1.7" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 12.8713 17.2959)" class="st3" width="1" height="8.5"/>
<rect x="9.5" y="1.8" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -1.3163 8.8347)" class="st3" width="1" height="8.5"/>
</g>
<g id="paused">
</g>
<g id="inactive">
</g>
<g id="running_1_">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

+79
View File
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{display:inline;fill:#FAF1F5;}
.st8{opacity:0.74;}
.st9{fill:#C91517;}
.st10{display:inline;fill:#C91517;}
.st11{display:inline;fill:#FFFFFF;}
.st12{display:none;fill:#C91517;}
.st13{display:inline;fill:#2C933D;}
.st14{display:inline;opacity:0.87;fill:#FFFFFF;stroke:#000000;stroke-width:1.75;stroke-miterlimit:10;}
.st15{fill:#2C933D;}
.st16{display:none;fill:#2C933D;}
.st17{fill:#676767;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-40" y="-16" class="st1" width="120" height="80"/>
<rect id="win2k" x="-40" y="-16" class="st2" width="120" height="80"/>
<rect id="white" x="-40" y="-16" class="st3" width="120" height="80"/>
<rect id="win7_aero" x="-40" y="-16" class="st4" width="120" height="80"/>
<rect id="win7_1_" x="-40" y="-16" class="st5" width="120" height="80"/>
<rect id="macosx" x="-40" y="-16" class="st6" width="120" height="80"/>
<rect id="macosx2" x="-40" y="-16" class="st7" width="120" height="80"/>
</g>
<g id="_x31_8x18_optimized__x28_OSX_x29_">
<g id="error_mono">
<g id="cross">
</g>
<g id="error_1_" class="st0">
</g>
</g>
<g id="paused_mono">
<g id="pause">
</g>
<g id="pause_Kopie" class="st0">
</g>
</g>
<g id="inactive_mono">
<g id="based_on" class="st0">
</g>
</g>
<g id="running_mono">
</g>
</g>
<g id="_x31_6x16_optimized__x28_Win_x29_">
<g id="error">
</g>
<g id="paused">
</g>
<g id="inactive">
<g id="small_4_">
<path d="M8.5,13.5c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2h3c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H8.5z"/>
<path class="st3" d="M11.5,9c0.8,0,1.5,0.7,1.5,1.5v1c0,0.8-0.7,1.5-1.5,1.5h-3C7.7,13,7,12.3,7,11.5v-1C7,9.7,7.7,9,8.5,9H11.5
M11.5,8h-3C7.1,8,6,9.1,6,10.5v1C6,12.9,7.1,14,8.5,14h3c1.4,0,2.5-1.1,2.5-2.5v-1C14,9.1,12.9,8,11.5,8L11.5,8z"/>
</g>
<g id="middle_4_">
<path d="M3,14.5c-1.4,0-2.5-1.1-2.5-2.5v-1c0-1.4,1.1-2.5,2.5-2.5h3c1.4,0,2.5,1.1,2.5,2.5v1c0,1.4-1.1,2.5-2.5,2.5H3z"/>
<path class="st3" d="M6,9c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H3c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2H6 M6,8H3c-1.7,0-3,1.3-3,3v1
c0,1.7,1.3,3,3,3h3c1.7,0,3-1.3,3-3v-1C9,9.3,7.7,8,6,8L6,8z"/>
</g>
<g id="big_4_">
<path d="M7,10.5c-1.4,0-2.5-1.1-2.5-2.5V4c0-1.4,1.1-2.5,2.5-2.5h6c1.4,0,2.5,1.1,2.5,2.5v4c0,1.4-1.1,2.5-2.5,2.5H7z"/>
<path class="st3" d="M13,2c1.1,0,2,0.9,2,2v4c0,1.1-0.9,2-2,2H7c-1.1,0-2-0.9-2-2V4c0-1.1,0.9-2,2-2H13 M13,1H7C5.3,1,4,2.3,4,4
v4c0,1.7,1.3,3,3,3h6c1.7,0,3-1.3,3-3V4C16,2.3,14.7,1,13,1L13,1z"/>
</g>
</g>
<g id="running_1_">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

+83
View File
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{display:inline;fill:#FAF1F5;}
.st8{opacity:0.74;}
.st9{fill:#C91517;}
.st10{display:inline;fill:#C91517;}
.st11{display:inline;fill:#FFFFFF;}
.st12{display:none;fill:#C91517;}
.st13{display:inline;fill:#2C933D;}
.st14{display:inline;opacity:0.87;fill:#FFFFFF;stroke:#000000;stroke-width:1.75;stroke-miterlimit:10;}
.st15{fill:#2C933D;}
.st16{display:none;fill:#2C933D;}
.st17{fill:#676767;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-64" y="-16" class="st1" width="120" height="80"/>
<rect id="win2k" x="-64" y="-16" class="st2" width="120" height="80"/>
<rect id="white" x="-64" y="-16" class="st3" width="120" height="80"/>
<rect id="win7_aero" x="-64" y="-16" class="st4" width="120" height="80"/>
<rect id="win7_1_" x="-64" y="-16" class="st5" width="120" height="80"/>
<rect id="macosx" x="-64" y="-16" class="st6" width="120" height="80"/>
<rect id="macosx2" x="-64" y="-16" class="st7" width="120" height="80"/>
</g>
<g id="_x31_8x18_optimized__x28_OSX_x29_">
<g id="error_mono">
<g id="cross">
</g>
<g id="error_1_" class="st0">
</g>
</g>
<g id="paused_mono">
<g id="pause">
</g>
<g id="pause_Kopie" class="st0">
</g>
</g>
<g id="inactive_mono">
<g id="based_on" class="st0">
</g>
</g>
<g id="running_mono">
</g>
</g>
<g id="_x31_6x16_optimized__x28_Win_x29_">
<g id="error">
</g>
<g id="paused">
<g id="small_3_">
<path class="st17" d="M8.5,13.5c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2h3c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H8.5z"/>
<path class="st3" d="M11.5,9c0.8,0,1.5,0.7,1.5,1.5v1c0,0.8-0.7,1.5-1.5,1.5h-3C7.7,13,7,12.3,7,11.5v-1C7,9.7,7.7,9,8.5,9H11.5
M11.5,8h-3C7.1,8,6,9.1,6,10.5v1C6,12.9,7.1,14,8.5,14h3c1.4,0,2.5-1.1,2.5-2.5v-1C14,9.1,12.9,8,11.5,8L11.5,8z"/>
</g>
<g id="middle_3_">
<path class="st17" d="M3,14.5c-1.4,0-2.5-1.1-2.5-2.5v-1c0-1.4,1.1-2.5,2.5-2.5h3c1.4,0,2.5,1.1,2.5,2.5v1c0,1.4-1.1,2.5-2.5,2.5
H3z"/>
<path class="st3" d="M6,9c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H3c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2H6 M6,8H3c-1.7,0-3,1.3-3,3v1
c0,1.7,1.3,3,3,3h3c1.7,0,3-1.3,3-3v-1C9,9.3,7.7,8,6,8L6,8z"/>
</g>
<g id="big_3_">
<path class="st17" d="M7,10.5c-1.4,0-2.5-1.1-2.5-2.5V4c0-1.4,1.1-2.5,2.5-2.5h6c1.4,0,2.5,1.1,2.5,2.5v4c0,1.4-1.1,2.5-2.5,2.5
H7z"/>
<path class="st3" d="M13,2c1.1,0,2,0.9,2,2v4c0,1.1-0.9,2-2,2H7c-1.1,0-2-0.9-2-2V4c0-1.1,0.9-2,2-2H13 M13,1H7C5.3,1,4,2.3,4,4
v4c0,1.7,1.3,3,3,3h6c1.7,0,3-1.3,3-3V4C16,2.3,14.7,1,13,1L13,1z"/>
</g>
<rect x="7" y="3" class="st3" width="2" height="6"/>
<rect x="11" y="3" class="st3" width="2" height="6"/>
</g>
<g id="inactive">
</g>
<g id="running_1_">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

+82
View File
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{display:inline;fill:#FAF1F5;}
.st8{opacity:0.74;}
.st9{fill:#C91517;}
.st10{display:inline;fill:#C91517;}
.st11{display:inline;fill:#FFFFFF;}
.st12{display:none;fill:#C91517;}
.st13{display:inline;fill:#2C933D;}
.st14{display:inline;opacity:0.87;fill:#FFFFFF;stroke:#000000;stroke-width:1.75;stroke-miterlimit:10;}
.st15{fill:#2C933D;}
.st16{display:none;fill:#2C933D;}
.st17{fill:#676767;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-16" y="-16" class="st1" width="120" height="80"/>
<rect id="win2k" x="-16" y="-16" class="st2" width="120" height="80"/>
<rect id="white" x="-16" y="-16" class="st3" width="120" height="80"/>
<rect id="win7_aero" x="-16" y="-16" class="st4" width="120" height="80"/>
<rect id="win7_1_" x="-16" y="-16" class="st5" width="120" height="80"/>
<rect id="macosx" x="-16" y="-16" class="st6" width="120" height="80"/>
<rect id="macosx2" x="-16" y="-16" class="st7" width="120" height="80"/>
</g>
<g id="_x31_8x18_optimized__x28_OSX_x29_">
<g id="error_mono">
<g id="cross">
</g>
<g id="error_1_" class="st0">
</g>
</g>
<g id="paused_mono">
<g id="pause">
</g>
<g id="pause_Kopie" class="st0">
</g>
</g>
<g id="inactive_mono">
<g id="based_on" class="st0">
</g>
</g>
<g id="running_mono">
</g>
</g>
<g id="_x31_6x16_optimized__x28_Win_x29_">
<g id="error">
</g>
<g id="paused">
</g>
<g id="inactive">
</g>
<g id="running_1_">
<g id="small_1_">
<path class="st15" d="M8.5,13.5c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2h3c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H8.5z"/>
<path class="st3" d="M11.5,9c0.8,0,1.5,0.7,1.5,1.5v1c0,0.8-0.7,1.5-1.5,1.5h-3C7.7,13,7,12.3,7,11.5v-1C7,9.7,7.7,9,8.5,9H11.5
M11.5,8h-3C7.1,8,6,9.1,6,10.5v1C6,12.9,7.1,14,8.5,14h3c1.4,0,2.5-1.1,2.5-2.5v-1C14,9.1,12.9,8,11.5,8L11.5,8z"/>
</g>
<g id="middle_1_">
<path class="st15" d="M3,14.5c-1.4,0-2.5-1.1-2.5-2.5v-1c0-1.4,1.1-2.5,2.5-2.5h3c1.4,0,2.5,1.1,2.5,2.5v1c0,1.4-1.1,2.5-2.5,2.5
H3z"/>
<path class="st3" d="M6,9c1.1,0,2,0.9,2,2v1c0,1.1-0.9,2-2,2H3c-1.1,0-2-0.9-2-2v-1c0-1.1,0.9-2,2-2H6 M6,8H3c-1.7,0-3,1.3-3,3v1
c0,1.7,1.3,3,3,3h3c1.7,0,3-1.3,3-3v-1C9,9.3,7.7,8,6,8L6,8z"/>
</g>
<g id="big_1_">
<path class="st15" d="M7,10.5c-1.4,0-2.5-1.1-2.5-2.5V4c0-1.4,1.1-2.5,2.5-2.5h6c1.4,0,2.5,1.1,2.5,2.5v4c0,1.4-1.1,2.5-2.5,2.5
H7z"/>
<path class="st3" d="M13,2c1.1,0,2,0.9,2,2v4c0,1.1-0.9,2-2,2H7c-1.1,0-2-0.9-2-2V4c0-1.1,0.9-2,2-2H13 M13,1H7C5.3,1,4,2.3,4,4
v4c0,1.7,1.3,3,3,3h6c1.7,0,3-1.3,3-3V4C16,2.3,14.7,1,13,1L13,1z"/>
</g>
<polygon id="running" class="st3" points="13,6 8,9 8,3 "/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

-7105
View File
File diff suppressed because one or more lines are too long
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{fill:#2C933D;}
.st8{fill:#676767;}
.st9{fill:#C91517;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-88" y="-15" class="st1" width="120" height="45"/>
<rect id="win2k" x="-88" y="-15" class="st2" width="120" height="45"/>
<rect id="white" x="-88" y="-15" class="st3" width="120" height="45"/>
<rect id="win7_aero" x="-88" y="-15" class="st4" width="120" height="45"/>
<rect id="win7_1_" x="-88" y="-15" class="st5" width="120" height="45"/>
<rect id="macosx" x="-88" y="-15" class="st6" width="120" height="45"/>
</g>
<g id="_x31_6x16_optimized">
<g id="green">
</g>
<g id="black_1_">
</g>
<g id="grey">
</g>
<g id="red">
<g id="small_6_">
<path class="st9" d="M11,12.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h3c0.8,0,1.5,0.7,1.5,1.5v2c0,0.8-0.7,1.5-1.5,1.5
H11z"/>
<path class="st3" d="M14,8c0.6,0,1,0.4,1,1v2c0,0.6-0.4,1-1,1h-3c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H14 M14,7h-3
C9.9,7,9,7.9,9,9v2c0,1.1,0.9,2,2,2h3c1.1,0,2-0.9,2-2V9C16,7.9,15.1,7,14,7L14,7z"/>
</g>
<g id="middle_6_">
<path class="st9" d="M2,13.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h5c0.8,0,1.5,0.7,1.5,1.5v3c0,0.8-0.7,1.5-1.5,1.5H2
z"/>
<path class="st3" d="M7,8c0.6,0,1,0.4,1,1v3c0,0.6-0.4,1-1,1H2c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H7 M7,7H2C0.9,7,0,7.9,0,9v3
c0,1.1,0.9,2,2,2h5c1.1,0,2-0.9,2-2V9C9,7.9,8.1,7,7,7L7,7z"/>
</g>
<g id="big_6_">
<path class="st9" d="M6,9.5C5.2,9.5,4.5,8.8,4.5,8V3c0-0.8,0.7-1.5,1.5-1.5h7c0.8,0,1.5,0.7,1.5,1.5v5c0,0.8-0.7,1.5-1.5,1.5H6z"
/>
<path class="st3" d="M13,2c0.6,0,1,0.4,1,1v5c0,0.6-0.4,1-1,1H6C5.4,9,5,8.6,5,8V3c0-0.6,0.4-1,1-1H13 M13,1H6C4.9,1,4,1.9,4,3v5
c0,1.1,0.9,2,2,2h7c1.1,0,2-0.9,2-2V3C15,1.9,14.1,1,13,1L13,1z"/>
</g>
<rect x="9" y="2" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 12.3536 16.0459)" class="st3" width="1" height="7"/>
<rect x="9" y="2" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -1.094 8.3128)" class="st3" width="1" height="7"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

-50
View File
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{fill:#2C933D;}
.st8{fill:#676767;}
.st9{fill:#C91517;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-40" y="-15" class="st1" width="120" height="45"/>
<rect id="win2k" x="-40" y="-15" class="st2" width="120" height="45"/>
<rect id="white" x="-40" y="-15" class="st3" width="120" height="45"/>
<rect id="win7_aero" x="-40" y="-15" class="st4" width="120" height="45"/>
<rect id="win7_1_" x="-40" y="-15" class="st5" width="120" height="45"/>
<rect id="macosx" x="-40" y="-15" class="st6" width="120" height="45"/>
</g>
<g id="_x31_6x16_optimized">
<g id="green">
</g>
<g id="black_1_">
<g id="small_2_">
<path d="M11,12.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h3c0.8,0,1.5,0.7,1.5,1.5v2c0,0.8-0.7,1.5-1.5,1.5H11z"/>
<path class="st3" d="M14,8c0.6,0,1,0.4,1,1v2c0,0.6-0.4,1-1,1h-3c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H14 M14,7h-3
C9.9,7,9,7.9,9,9v2c0,1.1,0.9,2,2,2h3c1.1,0,2-0.9,2-2V9C16,7.9,15.1,7,14,7L14,7z"/>
</g>
<g id="middle_2_">
<path d="M2,13.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h5c0.8,0,1.5,0.7,1.5,1.5v3c0,0.8-0.7,1.5-1.5,1.5H2z"/>
<path class="st3" d="M7,8c0.6,0,1,0.4,1,1v3c0,0.6-0.4,1-1,1H2c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H7 M7,7H2C0.9,7,0,7.9,0,9v3
c0,1.1,0.9,2,2,2h5c1.1,0,2-0.9,2-2V9C9,7.9,8.1,7,7,7L7,7z"/>
</g>
<g id="big_2_">
<path d="M6,9.5C5.2,9.5,4.5,8.8,4.5,8V3c0-0.8,0.7-1.5,1.5-1.5h7c0.8,0,1.5,0.7,1.5,1.5v5c0,0.8-0.7,1.5-1.5,1.5H6z"/>
<path class="st3" d="M13,2c0.6,0,1,0.4,1,1v5c0,0.6-0.4,1-1,1H6C5.4,9,5,8.6,5,8V3c0-0.6,0.4-1,1-1H13 M13,1H6C4.9,1,4,1.9,4,3v5
c0,1.1,0.9,2,2,2h7c1.1,0,2-0.9,2-2V3C15,1.9,14.1,1,13,1L13,1z"/>
</g>
</g>
<g id="grey">
</g>
<g id="red">
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{fill:#2C933D;}
.st8{fill:#676767;}
.st9{fill:#C91517;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-64" y="-15" class="st1" width="120" height="45"/>
<rect id="win2k" x="-64" y="-15" class="st2" width="120" height="45"/>
<rect id="white" x="-64" y="-15" class="st3" width="120" height="45"/>
<rect id="win7_aero" x="-64" y="-15" class="st4" width="120" height="45"/>
<rect id="win7_1_" x="-64" y="-15" class="st5" width="120" height="45"/>
<rect id="macosx" x="-64" y="-15" class="st6" width="120" height="45"/>
</g>
<g id="_x31_6x16_optimized">
<g id="green">
</g>
<g id="black_1_">
</g>
<g id="grey">
<g id="small_3_">
<path class="st8" d="M11,12.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h3c0.8,0,1.5,0.7,1.5,1.5v2c0,0.8-0.7,1.5-1.5,1.5
H11z"/>
<path class="st3" d="M14,8c0.6,0,1,0.4,1,1v2c0,0.6-0.4,1-1,1h-3c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H14 M14,7h-3
C9.9,7,9,7.9,9,9v2c0,1.1,0.9,2,2,2h3c1.1,0,2-0.9,2-2V9C16,7.9,15.1,7,14,7L14,7z"/>
</g>
<g id="middle_3_">
<path class="st8" d="M2,13.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h5c0.8,0,1.5,0.7,1.5,1.5v3c0,0.8-0.7,1.5-1.5,1.5H2
z"/>
<path class="st3" d="M7,8c0.6,0,1,0.4,1,1v3c0,0.6-0.4,1-1,1H2c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H7 M7,7H2C0.9,7,0,7.9,0,9v3
c0,1.1,0.9,2,2,2h5c1.1,0,2-0.9,2-2V9C9,7.9,8.1,7,7,7L7,7z"/>
</g>
<g id="big_3_">
<path class="st8" d="M6,9.5C5.2,9.5,4.5,8.8,4.5,8V3c0-0.8,0.7-1.5,1.5-1.5h7c0.8,0,1.5,0.7,1.5,1.5v5c0,0.8-0.7,1.5-1.5,1.5H6z"
/>
<path class="st3" d="M13,2c0.6,0,1,0.4,1,1v5c0,0.6-0.4,1-1,1H6C5.4,9,5,8.6,5,8V3c0-0.6,0.4-1,1-1H13 M13,1H6C4.9,1,4,1.9,4,3v5
c0,1.1,0.9,2,2,2h7c1.1,0,2-0.9,2-2V3C15,1.9,14.1,1,13,1L13,1z"/>
</g>
<rect x="7" y="3" class="st3" width="2" height="5"/>
<rect x="10" y="3" class="st3" width="2" height="5"/>
</g>
<g id="red">
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

-54
View File
@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#D0CDC6;}
.st3{fill:#FFFFFF;}
.st4{fill:#1D4775;}
.st5{fill:#8194A9;}
.st6{fill:#EBF1F5;}
.st7{fill:#2C933D;}
.st8{fill:#676767;}
.st9{fill:#C91517;}
</style>
<g id="backgrounds" class="st0">
<rect id="black" x="-16" y="-15" class="st1" width="120" height="45"/>
<rect id="win2k" x="-16" y="-15" class="st2" width="120" height="45"/>
<rect id="white" x="-16" y="-15" class="st3" width="120" height="45"/>
<rect id="win7_aero" x="-16" y="-15" class="st4" width="120" height="45"/>
<rect id="win7_1_" x="-16" y="-15" class="st5" width="120" height="45"/>
<rect id="macosx" x="-16" y="-15" class="st6" width="120" height="45"/>
</g>
<g id="_x31_6x16_optimized">
<g id="green">
<g id="small_1_">
<path class="st7" d="M11,12.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h3c0.8,0,1.5,0.7,1.5,1.5v2c0,0.8-0.7,1.5-1.5,1.5
H11z"/>
<path class="st3" d="M14,8c0.6,0,1,0.4,1,1v2c0,0.6-0.4,1-1,1h-3c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H14 M14,7h-3
C9.9,7,9,7.9,9,9v2c0,1.1,0.9,2,2,2h3c1.1,0,2-0.9,2-2V9C16,7.9,15.1,7,14,7L14,7z"/>
</g>
<g id="middle_1_">
<path class="st7" d="M2,13.5c-0.8,0-1.5-0.7-1.5-1.5V9c0-0.8,0.7-1.5,1.5-1.5h5c0.8,0,1.5,0.7,1.5,1.5v3c0,0.8-0.7,1.5-1.5,1.5H2
z"/>
<path class="st3" d="M7,8c0.6,0,1,0.4,1,1v3c0,0.6-0.4,1-1,1H2c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1H7 M7,7H2C0.9,7,0,7.9,0,9v3
c0,1.1,0.9,2,2,2h5c1.1,0,2-0.9,2-2V9C9,7.9,8.1,7,7,7L7,7z"/>
</g>
<g id="big_1_">
<path class="st7" d="M6,9.5C5.2,9.5,4.5,8.8,4.5,8V3c0-0.8,0.7-1.5,1.5-1.5h7c0.8,0,1.5,0.7,1.5,1.5v5c0,0.8-0.7,1.5-1.5,1.5H6z"
/>
<path class="st3" d="M13,2c0.6,0,1,0.4,1,1v5c0,0.6-0.4,1-1,1H6C5.4,9,5,8.6,5,8V3c0-0.6,0.4-1,1-1H13 M13,1H6C4.9,1,4,1.9,4,3v5
c0,1.1,0.9,2,2,2h7c1.1,0,2-0.9,2-2V3C15,1.9,14.1,1,13,1L13,1z"/>
</g>
<polygon id="running" class="st3" points="12,5.5 8,8 8,3 "/>
</g>
<g id="black_1_">
</g>
<g id="grey">
</g>
<g id="red">
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{3E891818-579A-4C06-8066-4C702BFA5921}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DependencyFinder</RootNamespace>
<AssemblyName>DependencyFinder</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause>
<Commandlineparameters>../../../../Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Mono.Cecil">
<HintPath>packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Mdb">
<HintPath>packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Pdb">
<HintPath>packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Rocks">
<HintPath>packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>
@@ -0,0 +1,17 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyFinder", "DependencyFinder.csproj", "{3E891818-579A-4C06-8066-4C702BFA5921}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3E891818-579A-4C06-8066-4C702BFA5921}.Debug|x86.ActiveCfg = Debug|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Debug|x86.Build.0 = Debug|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Release|x86.ActiveCfg = Release|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Release|x86.Build.0 = Release|x86
EndGlobalSection
EndGlobal
+64
View File
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using System.IO;
using System.Linq;
namespace DependencyFinder
{
class MainClass
{
public static void Main(string[] args)
{
var lst =
Directory.EnumerateFiles(args[0], "*.exe", SearchOption.AllDirectories).Union(
Directory.EnumerateFiles(args[0], "*.dll", SearchOption.AllDirectories))
.Select(x => {
try { return AssemblyDefinition.ReadAssembly(x); }
catch { return null; }
}).Where(x => x != null)
.Distinct();
PoC(lst, Console.Out, new [] { args[0] });
}
//Adapted from: https://stackoverflow.com/questions/9262464/tool-to-show-assembly-dependencies
public static void PoC(IEnumerable<AssemblyDefinition> assemblies, TextWriter writer, IEnumerable<string> searchfolders)
{
var resolver = new DefaultAssemblyResolver();
searchfolders.ToList().ForEach(x => resolver.AddSearchDirectory(x));
//writer.WriteLine("digraph Dependencies {");
var loaded = assemblies
.SelectMany(a => a.Modules.Cast<ModuleDefinition>())
.SelectMany(m => m.AssemblyReferences.Cast<AssemblyNameReference>())
.Distinct()
.Select(asm => {
var dllname = asm.Name + ".dll";
//Console.WriteLine("Probing for {0}", dllname);
try { return AssemblyDefinition.ReadAssembly(dllname); }
catch { }
try { return resolver.Resolve(asm.FullName); }
catch { }
return null;
})
.Where(assembly => assembly != null)
.ToList();
//loaded.ForEach(a => a.MainModule.ReadSymbols());
loaded.Select(x => x.FullName).Distinct().OrderBy(x => x).ToList().ForEach(x => writer.WriteLine("{0}", x));
/*loaded.ForEach(a =>
{
foreach (var r in a.MainModule.AssemblyReferences.Cast<AssemblyNameReference>())
writer.WriteLine(@"""{0}"" -> ""{1}"";", r.Name, a.Name.Name);
} );*/
//writer.WriteLine("}");
}
}
}
@@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("DependencyFinder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("kenneth")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("2.0.0.7")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Mono.Cecil" version="0.9.6.1" targetFramework="net45" />
</packages>
@@ -1,26 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalizationTool", "LocalizationTool\LocalizationTool.csproj", "{F093C3D3-28A8-405E-96C0-97AE2C296CCC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F093C3D3-28A8-405E-96C0-97AE2C296CCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F093C3D3-28A8-405E-96C0-97AE2C296CCC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F093C3D3-28A8-405E-96C0-97AE2C296CCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F093C3D3-28A8-405E-96C0-97AE2C296CCC}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -1,122 +0,0 @@
#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LocalizationTool
{
public class CSVReader : IDisposable
{
private System.IO.StreamReader m_reader;
public CSVReader(string filename)
{
m_reader = new System.IO.StreamReader(filename, System.Text.Encoding.UTF8, true);
}
public List<string> AdvanceLine()
{
bool inQuote = false;
StringBuilder sb = new StringBuilder();
do
{
string line = m_reader.ReadLine();
if (line == null)
{
if (sb.Length == 0)
return null;
else
throw new Exception("Unexpected EOF, buffer was: " + sb.ToString());
}
sb.AppendLine(line);
foreach (char c in line)
if (c == '"')
inQuote = !inQuote;
} while (inQuote);
string txt = sb.ToString();
if (txt.EndsWith("\r\n"))
txt = txt.Substring(0, txt.Length - 2);
else if (txt.EndsWith("\r\n"))
txt = txt.Substring(0, txt.Length - 2);
else if (txt.EndsWith("\n"))
txt = txt.Substring(0, txt.Length - 1);
else if (txt.EndsWith("\r"))
txt = txt.Substring(0, txt.Length - 1);
inQuote = false;
int ix = 0;
List<string> result = new List<string>();
for(int i = 0; i < txt.Length; i++)
if (inQuote)
{
if (txt[i] == '"')
inQuote = false;
}
else
{
if (txt[i] == '"')
inQuote = true;
else if (txt[i] == ',')
{
result.Add(CleanString(txt.Substring(ix, i - ix)));
ix = i + 1;
}
}
if (inQuote)
throw new Exception("Failed to parse line: " + txt);
if (ix != txt.Length)
result.Add(CleanString(txt.Substring(ix)));
return result;
}
private string CleanString(string v)
{
//v = v.Trim();
if (v.StartsWith("\"") && v.EndsWith("\""))
return v.Substring(1, v.Length - 2).Replace("\"\"", "\"");
else
return v;
}
#region IDisposable Members
public void Dispose()
{
if (m_reader != null)
{
m_reader.Dispose();
m_reader = null;
}
}
#endregion
}
}
@@ -1,239 +0,0 @@
#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LocalizationTool
{
public static class LinqHelpers
{
//
// Summary:
// Creates a System.Collections.Generic.Dictionary<TKey,TValue> from an System.Collections.Generic.IEnumerable<T>
// according to a specified key selector function.
//
// Parameters:
// source:
// An System.Collections.Generic.IEnumerable<T> to create a System.Collections.Generic.Dictionary<TKey,TValue>
// from.
//
// keySelector:
// A function to extract a key from each element.
//
// Type parameters:
// TSource:
// The type of the elements of source.
//
// TKey:
// The type of the key returned by keySelector.
//
// Returns:
// A System.Collections.Generic.Dictionary<TKey,TValue> that contains keys and
// values.
//
// Exceptions:
// System.ArgumentNullException:
// source or keySelector is null. -or- keySelector produces a key that is null.
public static Dictionary<TKey, TSource> ToSafeDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, string locationName)
{
if (source == null)
throw new ArgumentNullException("source");
if (keySelector == null)
throw new ArgumentNullException("keySelector");
Dictionary<TKey, TSource> res = new Dictionary<TKey, TSource>();
foreach (TSource el in source)
{
TKey k = keySelector(el);
if (res.ContainsKey(k))
Console.WriteLine("*** Warning, duplicate key: " + k.ToString() + " in " + locationName);
else
res.Add(k, el);
}
return res;
}
//
// Summary:
// Creates a System.Collections.Generic.Dictionary<TKey,TValue> from an System.Collections.Generic.IEnumerable<T>
// according to specified key selector and element selector functions.
//
// Parameters:
// source:
// An System.Collections.Generic.IEnumerable<T> to create a System.Collections.Generic.Dictionary<TKey,TValue>
// from.
//
// keySelector:
// A function to extract a key from each element.
//
// elementSelector:
// A transform function to produce a result element value from each element.
//
// Type parameters:
// TSource:
// The type of the elements of source.
//
// TKey:
// The type of the key returned by keySelector.
//
// TElement:
// The type of the value returned by elementSelector.
//
// Returns:
// A System.Collections.Generic.Dictionary<TKey,TValue> that contains values
// of type TElement selected from the input sequence.
//
// Exceptions:
// System.ArgumentNullException:
// source or keySelector or elementSelector is null. -or- keySelector produces
// a key that is null.
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, string locationName)
{
if (source == null)
throw new ArgumentNullException("source");
if (keySelector == null)
throw new ArgumentNullException("keySelector");
if (elementSelector == null)
throw new ArgumentNullException("elementSelector");
Dictionary<TKey, TElement> res = new Dictionary<TKey, TElement>();
foreach (TSource el in source)
{
TKey k = keySelector(el);
if (res.ContainsKey(k))
Console.WriteLine("*** Warning, duplicate key: " + k.ToString() + " in " + locationName);
else
res.Add(k, elementSelector(el));
}
return res;
}
//
// Summary:
// Creates a System.Collections.Generic.Dictionary<TKey,TValue> from an System.Collections.Generic.IEnumerable<T>
// according to a specified key selector function and key comparer.
//
// Parameters:
// source:
// An System.Collections.Generic.IEnumerable<T> to create a System.Collections.Generic.Dictionary<TKey,TValue>
// from.
//
// keySelector:
// A function to extract a key from each element.
//
// comparer:
// An System.Collections.Generic.IEqualityComparer<T> to compare keys.
//
// Type parameters:
// TSource:
// The type of the elements of source.
//
// TKey:
// The type of the keys returned by keySelector.
//
// Returns:
// A System.Collections.Generic.Dictionary<TKey,TValue> that contains keys and
// values.
//
// Exceptions:
// System.ArgumentNullException:
// source or keySelector is null. -or- keySelector produces a key that is null.
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer, string locationName)
{
if (source == null)
throw new ArgumentNullException("source");
if (keySelector == null)
throw new ArgumentNullException("keySelector");
Dictionary<TKey, TSource> res = new Dictionary<TKey, TSource>(comparer);
foreach (TSource el in source)
{
TKey k = keySelector(el);
if (res.ContainsKey(k))
Console.WriteLine("*** Warning, duplicate key: " + k.ToString() + " in " + locationName);
else
res.Add(k, el);
}
return res;
}
//
// Summary:
// Creates a System.Collections.Generic.Dictionary<TKey,TValue> from an System.Collections.Generic.IEnumerable<T>
// according to a specified key selector function, a comparer, and an element
// selector function.
//
// Parameters:
// source:
// An System.Collections.Generic.IEnumerable<T> to create a System.Collections.Generic.Dictionary<TKey,TValue>
// from.
//
// keySelector:
// A function to extract a key from each element.
//
// elementSelector:
// A transform function to produce a result element value from each element.
//
// comparer:
// An System.Collections.Generic.IEqualityComparer<T> to compare keys.
//
// Type parameters:
// TSource:
// The type of the elements of source.
//
// TKey:
// The type of the key returned by keySelector.
//
// TElement:
// The type of the value returned by elementSelector.
//
// Returns:
// A System.Collections.Generic.Dictionary<TKey,TValue> that contains values
// of type TElement selected from the input sequence.
//
// Exceptions:
// System.ArgumentNullException:
// source or keySelector or elementSelector is null. -or- keySelector produces
// a key that is null.
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer, string locationName)
{
if (source == null)
throw new ArgumentNullException("source");
if (keySelector == null)
throw new ArgumentNullException("keySelector");
if (elementSelector == null)
throw new ArgumentNullException("elementSelector");
Dictionary<TKey, TElement> res = new Dictionary<TKey, TElement>(comparer);
foreach (TSource el in source)
{
TKey k = keySelector(el);
if (res.ContainsKey(k))
Console.WriteLine("*** Warning, duplicate key: " + k.ToString() + " in " + locationName);
else
res.Add(k, elementSelector(el));
}
return res;
}
}
}
@@ -1,155 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F093C3D3-28A8-405E-96C0-97AE2C296CCC}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LocalizationTool</RootNamespace>
<AssemblyName>LocalizationTool</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\Duplicati\Localization\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Commandlineparameters>export</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\Duplicati\Localization\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="CSVReader.cs" />
<Compile Include="LinqHelpers.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="UpdateGUI.resx">
<DependentUpon>UpdateGUI.cs</DependentUpon>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="ResXCompiler.cs" />
<Compile Include="UpdateGUI.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UpdateGUI.Designer.cs">
<DependentUpon>UpdateGUI.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Resources\Empty_resx.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Batchjob.bat.txt" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -1,999 +0,0 @@
#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Net;
namespace LocalizationTool
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
if (args.Length == 0)
{
PrintUsage();
return;
}
//All relative paths are to the app dir
System.IO.Directory.SetCurrentDirectory(Application.StartupPath);
string loc = args.Length >= 2 ? args[1] : null;
switch (args[0].ToLower())
{
case "clean":
case "cleanup":
Clean(loc);
break;
case "build":
Compile(loc);
break;
case "update":
Update(loc);
break;
case "create":
if (args.Length != 2)
{
Console.WriteLine("missing locale identifier");
PrintUsage();
return;
}
Create(loc);
break;
case "report":
Report(loc);
break;
case "export":
Export(loc);
break;
case "exportdiff":
if (args.Length != 3)
{
Console.WriteLine("missing locale identifier or input CSV file");
PrintUsage();
return;
}
ExportDiff(loc, args[2]);
break;
case "import":
if (args.Length != 3)
{
Console.WriteLine("missing locale identifier or input CSV file");
PrintUsage();
return;
}
Import(loc, args[2]);
break;
case "guiupdate":
Application.EnableVisualStyles();
Application.DoEvents();
Report(loc);
new UpdateGUI(System.IO.Path.Combine(Application.StartupPath, "report." + loc + ".xml")).ShowDialog();
break;
case "webpull":
WebPull(loc, false);
break;
case "webupdate":
WebPull(loc, true);
break;
default:
PrintUsage();
return;
}
}
private static void PrintUsage()
{
Console.WriteLine("Usage: ");
Console.WriteLine("LocalizationTool.exe CLEAN [locale identifier]");
Console.WriteLine("LocalizationTool.exe BUILD [locale identifier]");
Console.WriteLine("LocalizationTool.exe UPDATE [locale identifier]");
Console.WriteLine("LocalizationTool.exe REPORT [locale identifier]");
Console.WriteLine("LocalizationTool.exe CREATE <locale indentifier>");
Console.WriteLine("LocalizationTool.exe GUIUPDATE <locale identifier>");
Console.WriteLine("LocalizationTool.exe EXPORT [locale identifier]");
Console.WriteLine("LocalizationTool.exe IMPORT <locale identifier> <input CSV file>");
Console.WriteLine("LocalizationTool.exe EXPORTDIFF <locale identifier> <input CSV file>");
Console.WriteLine("LocalizationTool.exe WEBPULL [locale identifier]");
Console.WriteLine("LocalizationTool.exe WEBUPDATE [locale identifier]");
}
private struct CSVEntry
{
public string Filename;
public string Fieldkey;
public string Origvalue;
public string Value;
public string Status;
public string[] extraFields;
public CSVEntry(List<string> fields)
{
Filename = fields[0];
Fieldkey = fields[1];
Status = fields[2];
Origvalue = fields[3];
Value = fields[4];
if (fields.Count > 5)
{
extraFields = new string[fields.Count - 5];
fields.CopyTo(5, extraFields, 0, extraFields.Length);
}
else
extraFields = null;
}
}
private static bool IsValidCulture(string c)
{
try
{
System.Globalization.CultureInfo.GetCultureInfo(c);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Downloads updated CSV files from the web and generates diff files, and optionally updates the local CSV files
/// </summary>
/// <param name="loc">The culture to use</param>
/// <param name="update">True if the elements should be updated as well</param>
private static void WebPull(string loc, bool update)
{
var locs =
from n in Directory.GetFiles(Application.StartupPath, "report.*.url")
where IsValidCulture(Path.GetFileNameWithoutExtension(n).Substring("report.".Length))
select Path.GetFileNameWithoutExtension(n).Substring("report.".Length);
if (!string.IsNullOrEmpty(loc))
{
locs = locs.Where(c => string.Equals(c, loc, StringComparison.CurrentCultureIgnoreCase));
if (locs.Count() == 0)
{
Console.WriteLine("No URL file found for culture {0}", loc);
return;
}
}
if (locs.Count() == 0)
{
Console.WriteLine("No culture.url files found");
return;
}
foreach (var culture in locs)
{
var url = string.Format("report.{0}.url", culture);
var file = string.Format("report.{0}.new.csv", culture);
if (File.Exists(file))
File.Delete(file);
Console.Write("Downloading updated CSV for {0} ... ", culture);
try { new WebClient().DownloadFile(File.ReadAllText(url).Trim(), file); }
catch (Exception ex)
{
Console.WriteLine("Failed!");
Console.WriteLine(" -> {0}", ex.Message);
continue;
}
Console.WriteLine("Done!");
if (update)
{
Console.Write("Updating local files for {0} .", culture);
ExportDiff(culture, file);
Console.Write(".");
Import(culture, file);
Console.Write(".");
Export(culture);
Console.WriteLine(" Done!");
}
}
}
/// <summary>
/// Imports a CSV file into a dictionary format,
/// Outer key is filename, inner key is fieldname, inner value is translated text
/// </summary>
/// <param name="file">The CSV file to read from</param>
/// <param name="loc">The current culture string</param>
/// <returns>Dictionary where outer key is filename, inner key is fieldname, inner value is translated text</returns>
private static Dictionary<string, Dictionary<string, CSVEntry>> ImportCSV(string file, string loc, Func<CSVEntry, bool> filter)
{
Dictionary<string, Dictionary<string, CSVEntry>> values = new Dictionary<string, Dictionary<string, CSVEntry>>();
using (CSVReader r = new CSVReader(file))
{
List<string> fields = null;
while ((fields = r.AdvanceLine()) != null)
if (fields.Count >= 5)
{
CSVEntry e = new CSVEntry(fields);
e.Filename = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, loc), e.Filename);
if (filter != null && filter(e))
continue;
if (!values.ContainsKey(e.Filename))
values.Add(e.Filename, new Dictionary<string, CSVEntry>());
Dictionary<string, CSVEntry> l = values[e.Filename];
l[e.Fieldkey] = e;
}
}
return values;
}
private static void Import(string loc, string p)
{
//Outer key is filename, inner key is fieldname, inner value is translated text
Dictionary<string, Dictionary<string, CSVEntry>> values = ImportCSV(p, loc, e => e.Value.Trim().Length == 0 || e.Value == e.Origvalue);
if (Duplicati.Library.Utility.Utility.IsClientLinux)
{
Dictionary<string, Dictionary<string, CSVEntry>> remap = new Dictionary<string, Dictionary<string, CSVEntry>>();
foreach(string key in values.Keys)
remap[key.Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString ())] = values[key];
values = remap;
}
string folder = System.IO.Path.Combine(Application.StartupPath, loc);
if (!System.IO.Directory.Exists(folder))
Create(loc);
else
Update(loc);
XNamespace xmlns = "";
foreach (ResXFileInfo inf in GetResXList(loc))
{
if (System.IO.File.Exists(inf.TargetFile) && values.ContainsKey(inf.TargetFile))
{
XDocument targetDoc = XDocument.Load(inf.TargetFile);
XNode insertTarget = targetDoc.Element("root").LastNode;
var targetVals = targetDoc.Element("root").Elements("data").ToSafeDictionary(c => c.Attribute("name").Value, inf.TargetFile);
var sourceVals = values[inf.TargetFile];
values.Remove(inf.TargetFile);
bool updated = false;
foreach (var item in sourceVals)
if (targetVals.ContainsKey(item.Key))
{
if (targetVals[item.Key].Element("value").Value.Replace("\r\n", "\n") != item.Value.Value.Replace("\r\n", "\n"))
{
updated = true;
targetVals[item.Key].Element("value").Value = item.Value.Value;
}
}
else
{
updated = true;
insertTarget.AddAfterSelf(new XElement("data",
new XAttribute("name", item.Key),
new XAttribute(xmlns + "space", "preserve"),
new XElement("value", item.Value.Value)
));
}
if (updated)
targetDoc.Save(inf.TargetFile);
}
}
if (values.Count != 0)
Console.WriteLine("The following files were translated but did not exist: " + string.Join(Environment.NewLine, values.Keys.ToArray()));
}
public static IEnumerable<string> GetLocaleFolders(string locid)
{
if (string.IsNullOrEmpty(locid))
return System.IO.Directory.GetDirectories(Application.StartupPath).Where(c =>
{
try
{
System.Globalization.CultureInfo.GetCultureInfo(System.IO.Path.GetFileName(c));
return true;
}
catch
{
return false;
}
}).Select(c => System.IO.Path.GetFileName(c));
else
return new string[] { locid };
}
private static void Export(string cultures)
{
Update(cultures);
Report(cultures);
foreach (string culture in GetLocaleFolders(cultures))
{
XDocument doc = XDocument.Load(System.IO.Path.Combine(Application.StartupPath, "report." + culture + ".xml"));
string outfile = System.IO.Path.Combine(Application.StartupPath, "report." + culture + ".csv");
Dictionary<string, Dictionary<string, CSVEntry>> elems = new Dictionary<string, Dictionary<string, CSVEntry>>();
foreach (var file in doc.Element("root").Elements("file"))
{
string filename = file.Attribute("filename").Value.Substring(Duplicati.Library.Utility.Utility.AppendDirSeparator(Application.StartupPath).Length);
filename = filename.Substring(culture.Length + 1);
Dictionary<string, CSVEntry> e = new Dictionary<string, CSVEntry>();
elems[filename] = e;
foreach (var item in file.Element("updated").Elements("item"))
{
CSVEntry c = new CSVEntry();
c.Filename = filename;
c.Fieldkey = item.Attribute("name").Value;
c.Status = item.Parent.Name.LocalName;
c.Origvalue = item.Element("original").Value;
c.Value = item.Element("translated").Value;
e.Add(c.Fieldkey, c);
}
foreach (var item in file.Element("missing").Elements("item"))
{
CSVEntry c = new CSVEntry();
c.Filename = filename;
c.Fieldkey = item.Attribute("name").Value;
c.Status = item.Parent.Name.LocalName;
c.Origvalue = item.Value;
c.Value = "";
e.Add(c.Fieldkey, c);
}
foreach (var item in file.Element("not-updated").Elements("item"))
{
CSVEntry c = new CSVEntry();
c.Filename = filename;
c.Fieldkey = item.Attribute("name").Value;
c.Status = item.Parent.Name.LocalName;
c.Origvalue = item.Value;
c.Value = "";
e.Add(c.Fieldkey, c);
}
foreach (var item in file.Element("unused").Elements("item"))
{
CSVEntry c = new CSVEntry();
c.Filename = filename;
c.Fieldkey = item.Attribute("name").Value;
c.Status = item.Parent.Name.LocalName;
c.Origvalue = "";
c.Value = item.Value;
e.Add(c.Fieldkey, c);
}
}
WriteCSVFile(outfile, culture, elems, null);
}
}
private static void ExportDiff(string culture, string inputfile)
{
inputfile = System.IO.Path.GetFullPath(inputfile);
string currentFile = System.IO.Path.Combine(Application.StartupPath, "report." + culture + ".csv");
string diffFile = System.IO.Path.Combine(Application.StartupPath, "report." + culture + ".diff.csv");
if (currentFile.Equals(inputfile, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision))
throw new Exception("Input file will be overwritten, please use another file");
Export(culture);
//Outer key is filename, inner key is fieldname, inner value is translated text
Dictionary<string, Dictionary<string, CSVEntry>> inputValues = ImportCSV(inputfile, culture, null);
Dictionary<string, Dictionary<string, CSVEntry>> currentValues = ImportCSV(currentFile, culture, null);
Dictionary<string, Dictionary<string, CSVEntry>> added = new Dictionary<string, Dictionary<string, CSVEntry>>();
Dictionary<string, Dictionary<string, CSVEntry>> removed = new Dictionary<string, Dictionary<string, CSVEntry>>();
foreach (var f in currentValues)
{
Dictionary<string, CSVEntry> other;
inputValues.TryGetValue(f.Key, out other);
if (other == null)
{
added.Add(f.Key, f.Value);
}
else
{
Dictionary<string, CSVEntry> a = new Dictionary<string,CSVEntry>();
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
{
if (other.ContainsKey(s.Key))
other.Remove(s.Key);
else
a.Add(s.Key, s.Value);
}
if (a.Count > 0)
added.Add(f.Key, a);
if (other.Count > 0)
removed.Add(f.Key, other);
}
}
Dictionary<string, Dictionary<string, string>> overrides = new Dictionary<string, Dictionary<string, string>>();
Dictionary<string, Dictionary<string, CSVEntry>> diffElems = new Dictionary<string, Dictionary<string, CSVEntry>>();
foreach (KeyValuePair<string, Dictionary<string, CSVEntry>> f in added)
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
if (s.Value.Origvalue == s.Value.Value || s.Value.Value.Trim().Length == 0)
{
if (!overrides.ContainsKey(f.Key))
overrides.Add(f.Key, new Dictionary<string, string>());
if (!diffElems.ContainsKey(f.Key))
diffElems.Add(f.Key, new Dictionary<string, CSVEntry>());
overrides[f.Key].Add(s.Key, "not-updated");
diffElems[f.Key].Add(s.Key, s.Value);
}
foreach (KeyValuePair<string, Dictionary<string, CSVEntry>> f in removed)
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
{
if (!overrides.ContainsKey(f.Key))
overrides.Add(f.Key, new Dictionary<string, string>());
if (!diffElems.ContainsKey(f.Key))
diffElems.Add(f.Key, new Dictionary<string, CSVEntry>());
overrides[f.Key].Add(s.Key, "unused");
diffElems[f.Key].Add(s.Key, s.Value);
}
WriteCSVFile(diffFile, culture, diffElems, overrides);
//Re-read the file
inputValues = ImportCSV(inputfile, culture, null);
//Add the new entries
foreach (KeyValuePair<string, Dictionary<string, CSVEntry>> f in added)
{
if (!inputValues.ContainsKey(f.Key))
inputValues.Add(f.Key, new Dictionary<string, CSVEntry>());
Dictionary<string, CSVEntry> o = inputValues[f.Key];
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
o.Add(s.Key, s.Value);
}
foreach (KeyValuePair<string, Dictionary<string, CSVEntry>> f in currentValues)
{
Dictionary<string, CSVEntry> o = inputValues[f.Key];
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
{
CSVEntry c = o[s.Key];
if (s.Value.Status == "unused")
c.Status = "unused";
else if (c.Origvalue == c.Value)
c.Status = "not-updated";
else if (string.IsNullOrEmpty(c.Value) || c.Value.Trim().Length == 0)
c.Status = "missing";
else
c.Status = "updated";
o[s.Key] = c;
}
}
//Update the removed entries
foreach (KeyValuePair<string, Dictionary<string, CSVEntry>> f in removed)
{
Dictionary<string, CSVEntry> o = inputValues[f.Key];
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
{
CSVEntry c = o[s.Key];
c.Status = "unused";
o[s.Key] = c;
}
}
//Write the output file
diffFile = System.IO.Path.Combine(Application.StartupPath, "report." + culture + ".updated.csv");
WriteCSVFile(diffFile, culture, inputValues, null);
}
private static void WriteCSVFile(string filename, string culture, Dictionary<string, Dictionary<string, CSVEntry>> entries, Dictionary<string, Dictionary<string, string>> status_overrides)
{
if (status_overrides == null)
status_overrides = new Dictionary<string, Dictionary<string, string>>();
List<KeyValuePair<string, KeyValuePair<string, CSVEntry>>> sortlist = new List<KeyValuePair<string, KeyValuePair<string, CSVEntry>>>();
foreach (KeyValuePair<string, Dictionary<string, CSVEntry>> f in entries)
foreach (KeyValuePair<string, CSVEntry> s in f.Value)
sortlist.Add(new KeyValuePair<string, KeyValuePair<string, CSVEntry>>(f.Key, s));
var sortedlist = sortlist.OrderBy(x => x.Key + System.IO.Path.PathSeparator + x.Value.Key);
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, false, new System.Text.UTF8Encoding(false)))
{
string filenameprefix = System.IO.Path.Combine(Application.StartupPath, culture);
int pfl = filenameprefix.Length + 1;
foreach (KeyValuePair<string, KeyValuePair<string, CSVEntry>> f in sortedlist)
{
string status = f.Value.Value.Status;
if (status_overrides.ContainsKey(f.Key) && status_overrides[f.Key].ContainsKey(f.Value.Key))
status = status_overrides[f.Key][f.Value.Key];
string path = f.Key;
if (f.Key.StartsWith(filenameprefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision))
path = f.Key.Substring(Math.Min(pfl, f.Key.Length));
if (Duplicati.Library.Utility.Utility.IsClientLinux)
path = path.Replace(System.IO.Path.DirectorySeparatorChar.ToString(), "\\");
WriteCSVLine(sw, path, f.Value.Key, status, f.Value.Value.Origvalue, f.Value.Value.Value, f.Value.Value.extraFields);
}
}
}
private static string CSV_SEPARATOR = ",";
private static void WriteCSVLine(System.IO.StreamWriter sw, string filename, string key, string status, string originalText, string translatedText, string[] extraFields)
{
sw.Write(EscapeCSVString(filename));
sw.Write(CSV_SEPARATOR);
sw.Write(EscapeCSVString(key));
sw.Write(CSV_SEPARATOR);
sw.Write(EscapeCSVString(status));
sw.Write(CSV_SEPARATOR);
sw.Write(EscapeCSVString(originalText));
sw.Write(CSV_SEPARATOR);
sw.Write(EscapeCSVString(translatedText));
if (extraFields != null && extraFields.Length > 0)
foreach (string s in extraFields)
{
sw.Write(CSV_SEPARATOR);
sw.Write(EscapeCSVString(s));
}
sw.Write("\r\n");
}
private static string EscapeCSVString(string value)
{
//.Replace("\\", "\\\\").Replace("\r\n", "\\n").Replace("\r", "\\n").Replace("\n", "\\n").Replace("\t", "\\t")
return "\"" + value.Replace("\"", "\"\"") + "\"";
}
private static void Report(string cultures)
{
foreach (string culture in GetLocaleFolders(cultures))
{
Dictionary<string, string> ignores = new Dictionary<string, string>();
string ignorefile = System.IO.Path.Combine(Application.StartupPath, "ignore." + culture + ".xml");
if (System.IO.File.Exists(ignorefile))
ignores = XDocument.Load(ignorefile).Element("root").Elements("ignore").Select(c => c.Value).ToSafeDictionary(c => c.ToLower().Trim(), ignorefile);
//Make sure we ignore empty strings
ignores[""] = "";
//Ignore common leftover values
for (int i = 1; i < 20; i++)
{
string _i = i.ToString();
ignores["textbox" + _i] = "";
ignores["combobox" + _i] = "";
ignores["checkbox" + _i] = "";
ignores["label" + _i] = "";
ignores["radiobutton" + _i] = "";
ignores["button" + _i] = "";
ignores["toolstrip" + _i] = "";
ignores["toolstripbutton" + _i] = "";
ignores["statusstrip" + _i] = "";
}
XDocument report = new XDocument(
new XElement("root")
);
XElement reportRoot = report.Element("root");
IEnumerable<ResXFileInfo> files = GetResXList(culture);
var missingFiles = files.Where(c => !System.IO.File.Exists(c.TargetFile));
var existingFiles = files.Where(c => System.IO.File.Exists(c.TargetFile));
var extraFiles = from x in Duplicati.Library.Utility.Utility.EnumerateFiles(System.IO.Path.Combine(Application.StartupPath, culture))
where
x.EndsWith("." + culture + ".resx")
&&
!files.Select(c => c.TargetFile).Contains(x)
select x;
reportRoot.Add(
new XElement("files",
new XElement("missing",
from x in missingFiles
select new XElement("file", x.TargetFile)
),
new XElement("unused",
from x in extraFiles
select new XElement("file", x)
)
)
);
foreach(ResXFileInfo inf in existingFiles)
{
IEnumerable<XElement> sourceElements = XDocument.Load(inf.SourceFile).Element("root").Elements("data");
IEnumerable<XElement> targetElements = XDocument.Load(inf.TargetFile).Element("root").Elements("data");
if (inf.IsForm)
{
//Look only for strings
Func<XElement, bool> filter =
c =>
!c.Attribute("name").Value.StartsWith(">>")
&&
c.Attribute("mimetype") == null
&&
(
c.Attribute("type") == null
||
c.Attribute("type").Value == "System.String, mscorlib"
||
c.Attribute("type").Value == "System.String"
);
sourceElements = sourceElements.Where(filter);
targetElements = targetElements.Where(filter);
}
//Filter the source and target before proceeding
sourceElements = sourceElements.Where(c => !ignores.ContainsKey(c.Element("value").Value.Trim().ToLower()) && !c.Element("value").Value.Trim().ToLower().StartsWith("..\\resources\\") && !c.Element("value").Value.Trim().ToLower().StartsWith("../resources/"));
targetElements = targetElements.Where(c => !ignores.ContainsKey(c.Element("value").Value.Trim().ToLower()) && !c.Element("value").Value.Trim().ToLower().StartsWith("..\\resources\\") && !c.Element("value").Value.Trim().ToLower().StartsWith("../resources/"));
var sourceVals = sourceElements.ToSafeDictionary(c => c.Attribute("name").Value, inf.SourceFile);
var targetVals = targetElements.ToSafeDictionary(c => c.Attribute("name").Value, inf.TargetFile);
var missing = sourceVals.Where(c => !targetVals.ContainsKey(c.Key)).ToList();
var unused = targetVals.Where(c => !sourceVals.ContainsKey(c.Key)).ToList();
var notUpdated = sourceVals.Where(c =>
targetVals.ContainsKey(c.Key)
&&
targetVals[c.Key].Element("value").Value == c.Value.Element("value").Value).ToList();
var updated = sourceVals.Where(c =>
!missing.Contains(c)
&&
!unused.Contains(c)
&&
!notUpdated.Contains(c)
&&
targetVals.ContainsKey(c.Key)
);
var yy = sourceVals.Values.Where(x => x.Value.Contains("System.Draw")).Concat(targetVals.Values.Where(x => x.Value.Contains("System.Draw")));
if (yy.Count() != 0)
{
}
reportRoot.Add(
new XElement("file",
new XAttribute("filename", inf.TargetFile),
new XElement("missing",
from x in missing
select new XElement("item",
new XAttribute("name", x.Key),
x.Value.Element("value").Value
)
),
new XElement("unused",
from x in unused
select new XElement("item",
new XAttribute("name", x.Key),
x.Value.Element("value").Value
)
),
new XElement("not-updated",
from x in notUpdated
select new XElement("item",
new XAttribute("name", x.Key),
x.Value.Element("value").Value
)
),
new XElement("updated",
from x in updated
select new XElement("item",
new XAttribute("name", x.Key),
new XElement("original",
x.Value.Element("value").Value
),
new XElement("translated",
targetVals[x.Key].Element("value").Value
)
)
)
)
);
}
report.Save(System.IO.Path.Combine(Application.StartupPath, "report." + culture + ".xml"));
}
}
private static void Create(string culture)
{
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo(culture); //Validate
string folder = System.IO.Path.Combine(Application.StartupPath, culture);
if (!System.IO.Directory.Exists(folder))
System.IO.Directory.CreateDirectory(folder);
Update(culture);
}
public class ResXFileInfo
{
public string SourceFile { get; set; }
public string TargetFile { get; set; }
public string NetrualTargetFile { get; set; }
public bool IsForm { get; set; }
}
public static IEnumerable<ResXFileInfo> GetResXList(string culture)
{
List<ResXFileInfo> res = new List<ResXFileInfo>();
foreach (XElement conf in XDocument.Load(System.IO.Path.Combine(Application.StartupPath, "configuration.xml")).Element("root").Elements("configuration"))
{
string sourcefolder = conf.Element("sourcefolder").Value;
if (Duplicati.Library.Utility.Utility.IsClientLinux)
sourcefolder = sourcefolder.Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString());
string outputfolder = System.IO.Path.GetFullPath(Duplicati.Library.Utility.Utility.AppendDirSeparator(System.IO.Path.Combine(Application.StartupPath, culture)));
sourcefolder = Duplicati.Library.Utility.Utility.AppendDirSeparator(System.IO.Path.GetFullPath(sourcefolder));
foreach (XElement fn in conf.Elements("assembly"))
{
string subfolder = fn.Attribute("folder").Value;
if (Duplicati.Library.Utility.Utility.IsClientLinux)
subfolder = subfolder.Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString());
foreach (string s in Duplicati.Library.Utility.Utility.EnumerateFiles(System.IO.Path.Combine(sourcefolder, subfolder)))
{
if (s.ToLower().StartsWith(Application.StartupPath.ToLower()))
continue;
if (s.EndsWith(".resx"))
{
string targetNameNeutral = System.IO.Path.Combine(outputfolder, s.Substring(sourcefolder.Length));
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(targetNameNeutral)))
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(targetNameNeutral));
string targetFilename = targetNameNeutral.Substring(0, targetNameNeutral.Length - "resx".Length) + culture + ".resx";
if (res.Where(x => x.TargetFile == targetFilename).FirstOrDefault() == null)
res.Add(new ResXFileInfo()
{
SourceFile = s,
IsForm = System.IO.File.Exists(System.IO.Path.ChangeExtension(s, ".cs")),
NetrualTargetFile = targetNameNeutral,
TargetFile = targetFilename
});
}
}
}
}
return res;
}
private static void Update(string cultures)
{
foreach (string culture in GetLocaleFolders(cultures))
{
foreach (ResXFileInfo inf in GetResXList(culture))
{
if (inf.IsForm)
System.IO.File.Copy(inf.SourceFile, inf.NetrualTargetFile, true); //Copy the updated resx
if (System.IO.File.Exists(inf.TargetFile))
{
//Merge, forms are auto-merged, in that they depend on the neutral .resx file
if (!inf.IsForm)
{
XDocument targetDoc = XDocument.Load(inf.TargetFile);
XNode insertTarget = targetDoc.Element("root").LastNode;
var sourceVals = XDocument.Load(inf.SourceFile).Element("root").Elements("data").ToSafeDictionary(c => c.Attribute("name").Value, inf.SourceFile);
var targetVals = targetDoc.Element("root").Elements("data").ToSafeDictionary(c => c.Attribute("name").Value, inf.TargetFile);
bool updated = false;
foreach (var item in sourceVals)
if (!targetVals.ContainsKey(item.Key))
{
updated = true;
insertTarget.AddAfterSelf(new XElement(item.Value));
}
if (updated)
targetDoc.Save(inf.TargetFile);
}
}
else
{
if (inf.IsForm)
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(inf.TargetFile))
sw.Write(Properties.Resources.Empty_resx);
else
{
if (Duplicati.Library.Utility.Utility.IsClientLinux)
{
var doc = XDocument.Load(inf.SourceFile);
var entries = from x in doc.Element("root").Elements("data")
where
x.Attribute("type") != null
&&
x.Attribute("type").Value == "System.Resources.ResXFileRef, System.Windows.Forms"
select x;
foreach(var e in entries)
{
string name = e.Element("value").Value;
int ixpos = name.IndexOf(";");
string path = name.Substring(0, ixpos);
path = path.Replace ("\\", System.IO.Path.DirectorySeparatorChar.ToString());
e.Element("value").Value = path + name.Substring(ixpos);
}
doc.Save(inf.TargetFile);
} else {
System.IO.File.Copy(inf.SourceFile, inf.TargetFile);
}
}
}
foreach (var item in from y in
(from x in XDocument.Load(inf.SourceFile).Element("root").Elements("data")
where
x.Attribute("type") != null
&&
x.Attribute("type").Value == "System.Resources.ResXFileRef, System.Windows.Forms"
select x)
let relname = y.Element("value").Value.Substring(0, y.Element("value").Value.IndexOf(";"))
let sourceRes = System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(inf.SourceFile), relname)).Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString())
let targetRes = System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(inf.TargetFile), relname)).Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString())
select new { sourceRes, targetRes }
)
{
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(item.targetRes)))
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(item.targetRes));
if (!System.IO.File.Exists(item.targetRes))
{
if (Duplicati.Library.Utility.Utility.IsClientLinux && !System.IO.File.Exists(item.sourceRes))
{
string basefolder = System.IO.Path.GetDirectoryName(item.sourceRes);
string sourcefile = System.IO.Directory.GetFiles (basefolder).FirstOrDefault (x => item.sourceRes.Equals(x, StringComparison.InvariantCultureIgnoreCase));
if (sourcefile == null)
Console.WriteLine ("Source file not found: " + item.sourceRes);
else
System.IO.File.Copy (sourcefile, item.targetRes);
} else {
System.IO.File.Copy(item.sourceRes, item.targetRes);
}
}
}
}
string batchfilename = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, culture), "gui update.bat");
System.IO.File.WriteAllText(batchfilename, Properties.Resources.Batchjob_bat, System.Text.Encoding.Default);
}
}
private static void Clean(string cultureReq)
{
string root = Duplicati.Library.Utility.Utility.AppendDirSeparator(Application.StartupPath);
if (!string.IsNullOrEmpty(cultureReq))
root = System.IO.Path.Combine(root, cultureReq);
foreach (string s in Duplicati.Library.Utility.Utility.EnumerateFiles(Application.StartupPath))
if (System.IO.Path.GetDirectoryName(s) != Application.StartupPath && (System.IO.Path.GetExtension(s) == ".resources" || System.IO.Path.GetExtension(s) == ".dll"))
System.IO.File.Delete(s);
else if (System.IO.Path.GetExtension(s) == ".resx")
{
//Remove the extra files required for resgen.exe
string culture = s.Substring(root.Length);
culture = culture.Substring(0, culture.IndexOf(System.IO.Path.DirectorySeparatorChar));
if (!s.ToLower().EndsWith("." + culture.ToLower() + ".resx") && System.IO.File.Exists(s.Substring(0, s.Length - "resx".Length) + culture + ".resx"))
System.IO.File.Delete(s);
}
}
private static void Compile(string cultureReq)
{
XDocument doc = XDocument.Load(System.IO.Path.Combine(Application.StartupPath, "configuration.xml"));
foreach (XElement conf in doc.Element("root").Elements("configuration"))
{
string keyfile = conf.Element("keyfile") == null ? null : conf.Element("keyfile").Value;
string versionassembly = conf.Element("versionassembly").Value;
string outputfolder = conf.Element("outputfolder").Value;
string productname = conf.Element("productname").Value;
string fxVer = conf.Element("frameworkVersion") == null ? "4.0" : conf.Element("frameworkVersion").Value;
Console.WriteLine("Compiling for framework: " + fxVer);
foreach (XElement n in conf.Elements("assembly"))
{
string assemblyName = n.Attribute("name").Value;
string folder = n.Attribute("folder").Value;
string @namespace = n.Attribute("namespace") == null ? assemblyName : n.Attribute("namespace").Value;
foreach (string culture in GetLocaleFolders(cultureReq))
{
List<string> excludes = (from x in n.Elements("exclude")
let fullpath = System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, culture), x.Value)
select fullpath).ToList();
string outfolder = System.IO.Path.GetFullPath(System.IO.Path.Combine(outputfolder, culture));
if (!System.IO.Directory.Exists(outfolder))
System.IO.Directory.CreateDirectory(outfolder);
ResXCompiler.CompileResxFiles(System.IO.Path.Combine(System.IO.Path.Combine(Application.StartupPath, culture), folder), excludes, @namespace, System.IO.Path.Combine(outfolder, assemblyName + ".resources.dll"), System.IO.Path.GetFullPath(versionassembly), keyfile, culture, productname, fxVer);
}
}
}
}
}
}
@@ -1,52 +0,0 @@
#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LocalizationTool")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Duplicati Team")]
[assembly: AssemblyProduct("LocalizationTool")]
[assembly: AssemblyCopyright("Copyright © Duplicati Team 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6f59216b-26e5-48cc-907b-16a97c7625df")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.0.0.7")]
[assembly: AssemblyFileVersion("2.0.0.7")]
@@ -1,105 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.544
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace LocalizationTool.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LocalizationTool.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to @echo off
///
///echo Processing updates, please wait ...
///
///set FOLDERNAME=
///for /f &quot;tokens=*&quot; %%a in (&quot;%CD%&quot;) do set FOLDERNAME=%%~na
///
///..\LocalizationTool.exe update %FOLDERNAME%
///..\LocalizationTool.exe guiupdate %FOLDERNAME%.
/// </summary>
internal static string Batchjob_bat {
get {
return ResourceManager.GetString("Batchjob.bat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
///&lt;root&gt;
/// &lt;!--
/// Microsoft ResX Schema
///
/// Version 2.0
///
/// The primary goals of this format is to allow a simple XML format
/// that is mostly human readable. The generation and parsing of the
/// various data types are done through the TypeConverter classes
/// associated with the data types.
///
/// Example:
///
/// ... ado.net/XML headers &amp; schema ...
/// &lt;resheader name=&quot;resmimetype&quot;&gt;text/microsoft-resx&lt;/resheader&gt;
/// &lt;resheader n [rest of string was truncated]&quot;;.
/// </summary>
internal static string Empty_resx {
get {
return ResourceManager.GetString("Empty_resx", resourceCulture);
}
}
}
}
@@ -1,127 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Batchjob.bat" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Batchjob.bat.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="Empty_resx" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Empty_resx.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>
@@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.544
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace LocalizationTool.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}
@@ -1,5 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles />
<Settings />
</SettingsFile>
@@ -1,230 +0,0 @@
#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Configuration;
namespace LocalizationTool
{
public static class ResXCompiler
{
private static string ExecuteAndRead(string command, string arguments)
{
var psi = new System.Diagnostics.ProcessStartInfo(command, arguments);
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
var pi = System.Diagnostics.Process.Start(psi);
pi.WaitForExit(5000);
if (pi.HasExited)
return pi.StandardOutput.ReadToEnd().Trim();
return null;
}
public static void CompileResxFiles(string folder, List<string> excludeFolders, string @namespace, string assemblyname, string versionAssembly, string keyfile, string culture, string productname, string fxVer)
{
string resgenexe;
string alexe;
if (Duplicati.Library.Utility.Utility.IsClientLinux)
{
resgenexe = ExecuteAndRead("which", "resgen");
alexe = ExecuteAndRead("which", "al");
}
else //Windows
{
//Order of these paths is also the search order
string[] known_sdk_paths = null;
if (fxVer == "2.0")
{
known_sdk_paths = new string[]
{
Environment.ExpandEnvironmentVariables("%WINDIR%\\Microsoft.Net\\Framework\\v2.0.50727\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES%\\Microsoft.NET\\SDK\\v2.0\\bin\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\\Microsoft.NET\\SDK\\v2.0\\bin\\"),
};
}
else if (fxVer == "3.0")
{
known_sdk_paths = new string[]
{
Environment.ExpandEnvironmentVariables("%WINDIR%\\Microsoft.Net\\Framework\\v3.0\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES%\\Microsoft SDKs\\Windows\\v6.0A\\bin\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\\Microsoft SDKs\\Windows\\v6.0A\\bin\\"),
};
}
else if (fxVer == "3.5")
{
known_sdk_paths = new string[]
{
Environment.ExpandEnvironmentVariables("%WINDIR%\\Microsoft.Net\\Framework\\v3.5\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES%\\Microsoft SDKs\\Windows\\v7.0A\\bin\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\\Microsoft SDKs\\Windows\\v7.0A\\bin\\"),
};
}
else
{
known_sdk_paths = new string[]
{
Environment.ExpandEnvironmentVariables("%WINDIR%\\Microsoft.Net\\Framework\\v4.0\\"),
Environment.ExpandEnvironmentVariables("%WINDIR%\\Microsoft.Net\\Framework\\v4.0.30319\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES%\\Microsoft SDKs\\Windows\\v8.0A\\bin\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES%\\Microsoft SDKs\\Windows\\v8.0A\\bin\\NETFX 4.0 Tools\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES%\\Microsoft SDKs\\Windows\\v7.1\\Bin\\NETFX 4.0 Tools\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\\Microsoft SDKs\\Windows\\v8.0A\\bin\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\\Microsoft SDKs\\Windows\\v8.0A\\bin\\NETFX 4.0 Tools\\"),
Environment.ExpandEnvironmentVariables("%PROGRAMFILES(X86)%\\Microsoft SDKs\\Windows\\v7.1\\Bin\\NETFX 4.0 Tools\\"),
};
}
resgenexe = "resgen.exe";
alexe = "al.exe";
foreach(var p in known_sdk_paths)
if (System.IO.File.Exists(System.IO.Path.Combine(p, resgenexe)))
{
resgenexe = System.IO.Path.Combine(p, resgenexe);
break;
}
foreach (var p in known_sdk_paths)
if (System.IO.File.Exists(System.IO.Path.Combine(p, alexe)))
{
alexe = System.IO.Path.Combine(p, alexe);
break;
}
}
if (!System.IO.File.Exists(resgenexe))
{
Console.WriteLine("Unable to locate file: {0}", resgenexe);
Console.WriteLine("This can be fixed by installing a microsoft platform SDK, or visual studio (express is fine)");
return;
}
if (!System.IO.File.Exists(alexe))
{
Console.WriteLine("Unable to locate file: {0}", alexe);
Console.WriteLine("This can be fixed by installing the .Net framework version 2.0");
return;
}
if (!string.IsNullOrEmpty(keyfile) && Duplicati.Library.Utility.Utility.IsClientLinux)
keyfile = keyfile.Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString());
List<string> resources = new List<string>();
folder = Duplicati.Library.Utility.Utility.AppendDirSeparator(folder);
foreach (string s in Duplicati.Library.Utility.Utility.EnumerateFiles(folder))
{
if (s.ToLower().EndsWith("." + culture.ToLower() + ".resx"))
{
if (excludeFolders.Any(xf => s.ToLower().StartsWith(Duplicati.Library.Utility.Utility.AppendDirSeparator(xf).ToLower())))
continue;
string resname = System.IO.Path.ChangeExtension(s, ".resources");
if (!System.IO.File.Exists(resname) || System.IO.File.GetLastWriteTime(resname) < System.IO.File.GetLastWriteTime(s))
{
Console.WriteLine("Compiling: " + s);
System.Diagnostics.ProcessStartInfo pi = new System.Diagnostics.ProcessStartInfo(resgenexe, "\"" + s + "\"");
pi.CreateNoWindow = true;
pi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
pi.RedirectStandardOutput = true;
pi.RedirectStandardError = true;
pi.UseShellExecute = false;
pi.WorkingDirectory = System.IO.Path.GetDirectoryName(s);
System.Diagnostics.Process pr = System.Diagnostics.Process.Start(pi);
pr.WaitForExit();
if (pr.ExitCode != 0)
{
Console.WriteLine("Error");
Console.WriteLine(pr.StandardOutput.ReadToEnd());
Console.WriteLine(pr.StandardError.ReadToEnd());
throw new Exception("Resgen failure: " + s);
}
}
else
Console.WriteLine("Not modified: " + s);
resources.Add(resname);
}
}
if (resources.Count == 0)
return;
if (!System.IO.File.Exists(versionAssembly) && Duplicati.Library.Utility.Utility.IsClientLinux)
versionAssembly = versionAssembly.Replace("\\", System.IO.Path.DirectorySeparatorChar.ToString());
if (!System.IO.File.Exists(versionAssembly))
{
Console.WriteLine("Unable to locate file: {0}", versionAssembly);
Console.WriteLine("This can be fixed by compiling the application or modifying the file configuration.xml");
return;
}
using (Duplicati.Library.Utility.TempFile tf = new Duplicati.Library.Utility.TempFile())
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(tf))
{
System.Reflection.Assembly asm = System.Reflection.Assembly.ReflectionOnlyLoadFrom(versionAssembly);
sw.WriteLine("/t:lib");
sw.WriteLine("/out:\"" + assemblyname + "\"");
sw.WriteLine("/product:\"" + productname + "\"");
sw.WriteLine("/title:\"" + productname + "\"");
sw.WriteLine("/version:" + asm.GetName().Version.ToString());
if (!string.IsNullOrEmpty(keyfile))
sw.WriteLine("/keyfile:\"" + keyfile + "\"");
sw.WriteLine("/culture:" + culture);
foreach (string s in resources)
{
string resname = s.Substring(folder.Length);
resname = resname.Replace("\\", ".");
resname = resname.Replace(" ", "_");
resname = @namespace + "." + resname;
sw.WriteLine("/embed:\"" + s + "\"," + resname);
}
}
Console.WriteLine("Linking ...");
System.Diagnostics.ProcessStartInfo pi = new System.Diagnostics.ProcessStartInfo(alexe, "@\"" + tf + "\"");
pi.CreateNoWindow = true;
pi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process pr = System.Diagnostics.Process.Start(pi);
pr.WaitForExit();
if (pr.ExitCode != 0)
throw new Exception("Linker failure");
}
}
}
}
@@ -1,9 +0,0 @@
@echo off
echo Processing updates, please wait ...
set FOLDERNAME=
for /f "tokens=*" %%a in ("%CD%") do set FOLDERNAME=%%~na
..\LocalizationTool.exe update %FOLDERNAME%
..\LocalizationTool.exe guiupdate %FOLDERNAME%
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,311 +0,0 @@
namespace LocalizationTool
{
partial class UpdateGUI
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.treeView1 = new System.Windows.Forms.TreeView();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.textBox2 = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.panel3 = new System.Windows.Forms.Panel();
this.label7 = new System.Windows.Forms.Label();
this.panel4 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.label8 = new System.Windows.Forms.Label();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.panel3.SuspendLayout();
this.panel4.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.Controls.Add(this.button3);
this.panel1.Controls.Add(this.button2);
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 264);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(459, 45);
this.panel1.TabIndex = 0;
//
// panel2
//
this.panel2.Controls.Add(this.label6);
this.panel2.Controls.Add(this.label5);
this.panel2.Controls.Add(this.label4);
this.panel2.Controls.Add(this.label3);
this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
this.panel2.Location = new System.Drawing.Point(0, 0);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(459, 32);
this.panel2.TabIndex = 1;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 32);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.treeView1);
this.splitContainer1.Panel1.Controls.Add(this.panel4);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.panel3);
this.splitContainer1.Panel2.Controls.Add(this.label7);
this.splitContainer1.Size = new System.Drawing.Size(459, 232);
this.splitContainer1.SplitterDistance = 227;
this.splitContainer1.TabIndex = 2;
//
// treeView1
//
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeView1.HideSelection = false;
this.treeView1.Location = new System.Drawing.Point(0, 0);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(227, 200);
this.treeView1.TabIndex = 0;
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(16, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(25, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Key";
//
// textBox1
//
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox1.Location = new System.Drawing.Point(56, 8);
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(42, 20);
this.textBox1.TabIndex = 1;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(16, 40);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(34, 13);
this.label2.TabIndex = 2;
this.label2.Text = "Value";
//
// textBox2
//
this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox2.Location = new System.Drawing.Point(16, 56);
this.textBox2.Multiline = true;
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(82, 136);
this.textBox2.TabIndex = 3;
this.textBox2.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(8, 8);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(83, 13);
this.label3.TabIndex = 0;
this.label3.Text = "Items remaining:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(96, 8);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(37, 13);
this.label4.TabIndex = 1;
this.label4.Text = "12345";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(152, 8);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(36, 13);
this.label5.TabIndex = 2;
this.label5.Text = "Folder";
//
// label6
//
this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label6.AutoEllipsis = true;
this.label6.Location = new System.Drawing.Point(200, 8);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(256, 16);
this.label6.TabIndex = 3;
this.label6.Text = "label6";
//
// panel3
//
this.panel3.Controls.Add(this.textBox2);
this.panel3.Controls.Add(this.label2);
this.panel3.Controls.Add(this.label1);
this.panel3.Controls.Add(this.textBox1);
this.panel3.Location = new System.Drawing.Point(8, 0);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(104, 208);
this.panel3.TabIndex = 4;
this.panel3.Visible = false;
//
// label7
//
this.label7.Anchor = System.Windows.Forms.AnchorStyles.None;
this.label7.Location = new System.Drawing.Point(67, 92);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(100, 16);
this.label7.TabIndex = 5;
this.label7.Text = "Click on an entry";
this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel4
//
this.panel4.Controls.Add(this.label8);
this.panel4.Controls.Add(this.button1);
this.panel4.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel4.Location = new System.Drawing.Point(0, 200);
this.panel4.Name = "panel4";
this.panel4.Size = new System.Drawing.Size(227, 32);
this.panel4.TabIndex = 6;
//
// button1
//
this.button1.Location = new System.Drawing.Point(5, 8);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 6;
this.button1.Text = "&Next";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.button2.Location = new System.Drawing.Point(144, 8);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 0;
this.button2.Text = "&OK";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.button3.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button3.Location = new System.Drawing.Point(240, 8);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(75, 23);
this.button3.TabIndex = 1;
this.button3.Text = "&Cancel";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(96, 16);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(134, 13);
this.label8.TabIndex = 2;
this.label8.Text = "Press ALT+N for next entry";
//
// UpdateGUI
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.button3;
this.ClientSize = new System.Drawing.Size(459, 309);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel1);
this.Name = "UpdateGUI";
this.Text = "Localization updater";
this.Load += new System.EventHandler(this.UpdateGUI_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.UpdateGUI_FormClosing);
this.panel1.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
this.panel3.ResumeLayout(false);
this.panel3.PerformLayout();
this.panel4.ResumeLayout(false);
this.panel4.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Panel panel4;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label8;
}
}
@@ -1,233 +0,0 @@
#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace LocalizationTool
{
public partial class UpdateGUI : Form
{
private string m_reportfile;
private int m_totalcount;
private Dictionary<string, XElement> m_updates = new Dictionary<string, XElement>();
public UpdateGUI(string reportfile)
{
InitializeComponent();
m_reportfile = reportfile;
}
private void UpdateGUI_Load(object sender, EventArgs e)
{
panel3.Dock = DockStyle.Fill;
string culturename = System.IO.Path.GetExtension(System.IO.Path.GetFileNameWithoutExtension(m_reportfile)).Substring(1);
this.Text = "Localizing culture " + culturename;
var files = XDocument.Load(m_reportfile).Element("root").Elements("file").Where(n =>
(n.Element("missing") != null && n.Element("missing").Elements().Count() > 0)
||
(n.Element("not-updated") != null && n.Element("not-updated").Elements().Count() > 0)
);
string rootfolder = Duplicati.Library.Utility.Utility.AppendDirSeparator(System.IO.Path.Combine(Application.StartupPath, culturename));
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
foreach (XElement x in files)
{
TreeNodeCollection cl = treeView1.Nodes;
string relpath = x.Attribute("filename").Value.Substring(rootfolder.Length);
foreach (string s in relpath.Split(System.IO.Path.DirectorySeparatorChar))
{
bool found = false;
foreach (TreeNode n in cl)
if (n.Text == s)
{
cl = n.Nodes;
found = true;
break;
}
if (!found)
{
TreeNode nn = new TreeNode(s);
nn.ForeColor = Color.DarkBlue;
cl.Add(nn);
cl = nn.Nodes;
}
}
foreach (XElement el in x.Element("missing").Elements("item").Union(x.Element("not-updated").Elements("item")))
{
//These show up occasionally, but mut not be translated
if (
el.Attribute("name").Value.EndsWith(".Name")
||
el.Attribute("name").Value.EndsWith(".MappingName")
)
continue;
string val = el.Value;
if (val.Length > 100)
val = val.Substring(0, 97) + "...";
TreeNode tn = new TreeNode(el.Attribute("name").Value + ": " + val);
tn.ForeColor = Color.DarkRed;
tn.Tag = el;
cl.Add(tn);
m_totalcount++;
}
}
treeView1.EndUpdate();
treeView1.ExpandAll();
if (treeView1.Nodes.Count > 0)
{
TreeNode top = treeView1.Nodes[0];
while (top.Nodes.Count > 0)
top = top.Nodes[0];
treeView1.SelectedNode = top;
}
label4.Text = m_totalcount.ToString();
label6.Text = System.IO.Path.Combine(Application.StartupPath, culturename);
this.WindowState = FormWindowState.Maximized;
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (treeView1.SelectedNode == null || treeView1.SelectedNode.Tag as XElement == null)
panel3.Visible = false;
else
{
panel3.Visible = true;
XElement el = treeView1.SelectedNode.Tag as XElement;
panel3.Tag = null;
textBox1.Text = el.Attribute("name").Value;
textBox2.Text = el.Value.Replace(Environment.NewLine, "\n").Replace("\n", Environment.NewLine);
try
{
textBox2.Focus();
textBox2.SelectAll();
}
catch { }
panel3.Tag = el;
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
if (panel3.Tag as XElement == null)
return;
XElement el = panel3.Tag as XElement;
el.Value = textBox2.Text;
string dictkey = el.Parent.Parent.Attribute("filename").Value + "@" + el.Attribute("name").Value;
m_updates[dictkey] = el;
label4.Text = (m_totalcount - m_updates.Count).ToString();
if (treeView1.SelectedNode != null && treeView1.SelectedNode.Tag == el)
treeView1.SelectedNode.ForeColor = Color.DarkGreen;
}
private void button3_Click(object sender, EventArgs e)
{
if (m_updates.Count > 0)
if (MessageBox.Show(this, "Close and loose all changes?", Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3) != DialogResult.Yes)
return;
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
TreeNode t = treeView1.SelectedNode;
if (t == null)
return;
List<TreeNode> visited = new List<TreeNode>();
while (t != null)
{
if (t.Nodes.Count > 0 && !visited.Contains(t))
t = t.Nodes[0];
else if (t.NextNode != null)
t = t.NextNode;
else
{
if (t.Parent != null && !visited.Contains(t.Parent))
visited.Add(t.Parent);
t = t.Parent;
}
if (t != null && t.ForeColor == Color.DarkRed)
{
treeView1.SelectedNode = t;
return;
}
}
MessageBox.Show(this, "No more items", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void button2_Click(object sender, EventArgs e)
{
foreach (XElement el in m_updates.Values)
{
XDocument file = XDocument.Load(el.Parent.Parent.Attribute("filename").Value);
var insertEl = file.Element("root").Elements("data").Where(c => c.Attribute("name").Value == el.Attribute("name").Value).FirstOrDefault();
if (insertEl != null)
insertEl.Element("value").Value = el.Value;
else
file.Element("root").Elements().Last().AddAfterSelf(
new XElement("data",
new XAttribute("name", el.Attribute("name").Value),
new XAttribute(XNamespace.Xml + "space", "preserve"),
new XElement("value", el.Value)
)
);
file.Save(el.Parent.Parent.Attribute("filename").Value);
}
m_updates.Clear();
this.DialogResult = DialogResult.OK;
this.Close();
}
private void UpdateGUI_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing || e.CloseReason == CloseReason.FormOwnerClosing)
if (m_updates.Count > 0)
if (MessageBox.Show(this, "Close and loose all changes?", Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3) != DialogResult.Yes)
{
e.Cancel = true;
return;
}
}
}
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,5 +0,0 @@
<?xml version="1.0"?>
<configuration>
<configSections>
</configSections>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
+349 -446
View File
@@ -1,446 +1,349 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Main", "Duplicati\Library\Main\Duplicati.Library.Main.csproj", "{10D2D1B7-C664-41D8-9B3A-00040C3D421B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.File", "Duplicati\Library\Backend\File\Duplicati.Library.Backend.File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.FTP", "Duplicati\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj", "{F61679A9-E5DE-468A-B5A4-05F92D0143D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Compression", "Duplicati\Library\Compression\Duplicati.Library.Compression.csproj", "{19ECCE09-B5EB-406C-8C57-BAC66997D469}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Logging", "Duplicati\Library\Logging\Duplicati.Library.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.S3", "Duplicati\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj", "{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine", "Duplicati\CommandLine\Duplicati.CommandLine.csproj", "{81765A64-3661-4E3E-B850-2F6F87A51F74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.WEBDAV", "Duplicati\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj", "{BAE27510-8B5D-44B2-B33E-372A98908041}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.CloudFiles", "Duplicati\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj", "{1BFAE226-8364-4086-825C-BB83F6F3EE4C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTester", "Duplicati\CommandLine\BackendTester\Duplicati.CommandLine.BackendTester.csproj", "{E7280DCA-7776-4A73-B9B5-41FD77FC8799}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.DynamicLoader", "Duplicati\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Snapshots", "Duplicati\Library\Snapshots\Duplicati.Library.Snapshots.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.License", "Duplicati\License\Duplicati.License.csproj", "{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Modules.Builtin", "Duplicati\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj", "{52826615-7964-47FE-B4B3-1B2DBDF605B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.TahoeLAFS", "Duplicati\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj", "{C0270709-2A40-43B5-8CF1-69581B9FA2A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OneDrive", "Duplicati\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj", "{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SSHv2", "Duplicati\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj", "{FF2BF37C-E502-4C98-BEA0-701671DDFA08}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server", "Duplicati\Server\Duplicati.Server.csproj", "{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.GUI.TrayIcon", "Duplicati\GUI\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj", "{17566860-3D98-4604-AA5B-47661F75609F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server.Serialization", "Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj", "{33FD1D24-C28F-4C71-933F-98F1586EA76C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTool", "Duplicati\CommandLine\BackendTool\Duplicati.CommandLine.BackendTool.csproj", "{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.SQLiteHelper", "Duplicati\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj", "{2C838169-B187-4B09-8768-1C24C2521C8D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Localization", "Duplicati\Library\Localization\Duplicati.Library.Localization.csproj", "{B68F2214-951F-4F78-8488-66E1ED3F50BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.AutoUpdater", "Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj", "{7E119745-1F62-43F0-936C-F312A1912C0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Service", "Duplicati\Service\Duplicati.Service.csproj", "{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AzureBlob", "Duplicati\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj", "{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.UnitTest", "Duplicati\UnitTest\Duplicati.UnitTest.csproj", "{ECB63D1C-1724-442D-9228-DEABF14F2EA3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.OAuthHelper", "Duplicati\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj", "{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.GoogleServices", "Duplicati\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj", "{5489181D-950C-44AF-873C-45EB0A3B6BD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OpenStack", "Duplicati\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj", "{D9E4E686-423C-48EC-A392-404E7C00860C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.HubiC", "Duplicati\Library\Backend\HubiC\Duplicati.Library.Backend.HubiC.csproj", "{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.RecoveryTool", "Duplicati\CommandLine\RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj", "{4A010589-76E6-4F05-A5C4-4598D5DF11F8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AmazonCloudDrive", "Duplicati\Library\Backend\AmazonCloudDrive\Duplicati.Library.Backend.AmazonCloudDrive.csproj", "{08D7E42D-285C-4010-9881-986125FE2F3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Backblaze", "Duplicati\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj", "{61C43D61-4368-4942-84A3-1EB623F4EF2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Mega", "Duplicati\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj", "{6643A5AE-AB38-453F-ADCE-408E35A81A83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Box", "Duplicati\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj", "{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.UsageReporter", "Duplicati\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj", "{BB014EA5-CE2C-4444-8D30-38983A0E8553}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SharePoint", "Duplicati\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj", "{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{08D7E42D-285C-4010-9881-986125FE2F3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08D7E42D-285C-4010-9881-986125FE2F3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08D7E42D-285C-4010-9881-986125FE2F3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08D7E42D-285C-4010-9881-986125FE2F3E}.Release|Any CPU.Build.0 = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.Build.0 = Release|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Release|Any CPU.Build.0 = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.Build.0 = Release|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Release|Any CPU.Build.0 = Release|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Release|Any CPU.Build.0 = Release|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|Any CPU.Build.0 = Release|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Release|Any CPU.Build.0 = Release|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Release|Any CPU.Build.0 = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.Build.0 = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.Build.0 = Release|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Release|Any CPU.Build.0 = Release|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Release|Any CPU.Build.0 = Release|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Release|Any CPU.Build.0 = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.Build.0 = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.Build.0 = Release|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Release|Any CPU.Build.0 = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.Build.0 = Release|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Release|Any CPU.Build.0 = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.Build.0 = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.Build.0 = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Release|Any CPU.Build.0 = Release|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.Build.0 = Release|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.Build.0 = Release|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Release|Any CPU.Build.0 = Release|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Release|Any CPU.Build.0 = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.Build.0 = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.Build.0 = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.StandardHeader = $1
$1.Text = @ Copyright (C) 2015, The Duplicati Team\n http://www.duplicati.com, info@duplicati.com\n \n This library is free software; you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as\n published by the Free Software Foundation; either version 2.1 of the\n License, or (at your option) any later version.\n\n This library is distributed in the hope that it will be useful, but\n WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public\n License along with this library; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$1.IncludeInNewFiles = True
$0.DotNetNamingPolicy = $2
$2.DirectoryNamespaceAssociation = PrefixedHierarchical
$2.ResourceNamePolicy = FileFormatDefault
$0.TextStylePolicy = $3
$3.inheritsSet = null
$3.scope = text/x-csharp
$0.CSharpFormattingPolicy = $4
$4.IndentSwitchBody = True
$4.AnonymousMethodBraceStyle = NextLine
$4.PropertyBraceStyle = NextLine
$4.PropertyGetBraceStyle = NextLine
$4.PropertySetBraceStyle = NextLine
$4.EventBraceStyle = NextLine
$4.EventAddBraceStyle = NextLine
$4.EventRemoveBraceStyle = NextLine
$4.StatementBraceStyle = NextLine
$4.ElseNewLinePlacement = NewLine
$4.CatchNewLinePlacement = NewLine
$4.FinallyNewLinePlacement = NewLine
$4.BeforeMethodDeclarationParentheses = False
$4.BeforeMethodCallParentheses = False
$4.BeforeConstructorDeclarationParentheses = False
$4.BeforeIndexerDeclarationBracket = False
$4.BeforeDelegateDeclarationParentheses = False
$4.NewParentheses = False
$4.ForParentheses = False
$4.ForeachParentheses = False
$4.LockParentheses = False
$4.UsingParentheses = False
$4.SpacesBeforeBrackets = False
$4.inheritsSet = Mono
$4.inheritsScope = text/x-csharp
$4.scope = text/x-csharp
$0.TextStylePolicy = $5
$5.FileWidth = 120
$5.EolMarker = Windows
$5.inheritsSet = VisualStudio
$5.inheritsScope = text/plain
$5.scope = text/plain
$0.NameConventionPolicy = $6
$6.Rules = $7
$7.NamingRule = $8
$8.Name = Namespaces
$8.AffectedEntity = Namespace
$8.VisibilityMask = VisibilityMask
$8.NamingStyle = PascalCase
$8.IncludeInstanceMembers = True
$8.IncludeStaticEntities = True
$7.NamingRule = $9
$9.Name = Types
$9.AffectedEntity = Class, Struct, Enum, Delegate
$9.VisibilityMask = Public
$9.NamingStyle = PascalCase
$9.IncludeInstanceMembers = True
$9.IncludeStaticEntities = True
$7.NamingRule = $10
$10.Name = Interfaces
$10.RequiredPrefixes = $11
$11.String = I
$10.AffectedEntity = Interface
$10.VisibilityMask = Public
$10.NamingStyle = PascalCase
$10.IncludeInstanceMembers = True
$10.IncludeStaticEntities = True
$7.NamingRule = $12
$12.Name = Attributes
$12.RequiredSuffixes = $13
$13.String = Attribute
$12.AffectedEntity = CustomAttributes
$12.VisibilityMask = Public
$12.NamingStyle = PascalCase
$12.IncludeInstanceMembers = True
$12.IncludeStaticEntities = True
$7.NamingRule = $14
$14.Name = Event Arguments
$14.RequiredSuffixes = $15
$15.String = EventArgs
$14.AffectedEntity = CustomEventArgs
$14.VisibilityMask = Public
$14.NamingStyle = PascalCase
$14.IncludeInstanceMembers = True
$14.IncludeStaticEntities = True
$7.NamingRule = $16
$16.Name = Exceptions
$16.RequiredSuffixes = $17
$17.String = Exception
$16.AffectedEntity = CustomExceptions
$16.VisibilityMask = VisibilityMask
$16.NamingStyle = PascalCase
$16.IncludeInstanceMembers = True
$16.IncludeStaticEntities = True
$7.NamingRule = $18
$18.Name = Methods
$18.AffectedEntity = Methods
$18.VisibilityMask = Protected, Public
$18.NamingStyle = PascalCase
$18.IncludeInstanceMembers = True
$18.IncludeStaticEntities = True
$7.NamingRule = $19
$19.Name = Static Readonly Fields
$19.AffectedEntity = ReadonlyField
$19.VisibilityMask = Protected, Public
$19.NamingStyle = PascalCase
$19.IncludeInstanceMembers = False
$19.IncludeStaticEntities = True
$7.NamingRule = $20
$20.Name = Fields
$20.AffectedEntity = Field
$20.VisibilityMask = Protected, Public
$20.NamingStyle = PascalCase
$20.IncludeInstanceMembers = True
$20.IncludeStaticEntities = True
$7.NamingRule = $21
$21.Name = ReadOnly Fields
$21.AffectedEntity = ReadonlyField
$21.VisibilityMask = Protected, Public
$21.NamingStyle = PascalCase
$21.IncludeInstanceMembers = True
$21.IncludeStaticEntities = False
$7.NamingRule = $22
$22.Name = Constant Fields
$22.AffectedEntity = ConstantField
$22.VisibilityMask = Protected, Public
$22.NamingStyle = PascalCase
$22.IncludeInstanceMembers = True
$22.IncludeStaticEntities = True
$7.NamingRule = $23
$23.Name = Properties
$23.AffectedEntity = Property
$23.VisibilityMask = Protected, Public
$23.NamingStyle = PascalCase
$23.IncludeInstanceMembers = True
$23.IncludeStaticEntities = True
$7.NamingRule = $24
$24.Name = Events
$24.AffectedEntity = Event
$24.VisibilityMask = Protected, Public
$24.NamingStyle = PascalCase
$24.IncludeInstanceMembers = True
$24.IncludeStaticEntities = True
$7.NamingRule = $25
$25.Name = Enum Members
$25.AffectedEntity = EnumMember
$25.VisibilityMask = VisibilityMask
$25.NamingStyle = PascalCase
$25.IncludeInstanceMembers = True
$25.IncludeStaticEntities = True
$7.NamingRule = $26
$26.Name = Parameters
$26.AffectedEntity = Parameter
$26.VisibilityMask = VisibilityMask
$26.NamingStyle = CamelCase
$26.IncludeInstanceMembers = True
$26.IncludeStaticEntities = True
$7.NamingRule = $27
$27.Name = Type Parameters
$27.RequiredPrefixes = $28
$28.String = T
$27.AffectedEntity = TypeParameter
$27.VisibilityMask = VisibilityMask
$27.NamingStyle = PascalCase
$27.IncludeInstanceMembers = True
$27.IncludeStaticEntities = True
$0.TextStylePolicy = $29
$29.inheritsSet = null
$29.scope = application/config+xml
$0.XmlFormattingPolicy = $30
$30.inheritsSet = null
$30.scope = application/config+xml
$0.VersionControlPolicy = $31
$31.inheritsSet = Mono
$0.ChangeLogPolicy = $32
$32.UpdateMode = None
$32.MessageStyle = $33
$33.LineAlign = 0
$32.inheritsSet = Mono
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
EndGlobal
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Main", "Duplicati\Library\Main\Duplicati.Library.Main.csproj", "{10D2D1B7-C664-41D8-9B3A-00040C3D421B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.File", "Duplicati\Library\Backend\File\Duplicati.Library.Backend.File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.FTP", "Duplicati\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj", "{F61679A9-E5DE-468A-B5A4-05F92D0143D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Compression", "Duplicati\Library\Compression\Duplicati.Library.Compression.csproj", "{19ECCE09-B5EB-406C-8C57-BAC66997D469}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Logging", "Duplicati\Library\Logging\Duplicati.Library.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.S3", "Duplicati\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj", "{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine", "Duplicati\CommandLine\Duplicati.CommandLine.csproj", "{81765A64-3661-4E3E-B850-2F6F87A51F74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.WEBDAV", "Duplicati\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj", "{BAE27510-8B5D-44B2-B33E-372A98908041}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.CloudFiles", "Duplicati\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj", "{1BFAE226-8364-4086-825C-BB83F6F3EE4C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTester", "Duplicati\CommandLine\BackendTester\Duplicati.CommandLine.BackendTester.csproj", "{E7280DCA-7776-4A73-B9B5-41FD77FC8799}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.DynamicLoader", "Duplicati\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Snapshots", "Duplicati\Library\Snapshots\Duplicati.Library.Snapshots.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.License", "Duplicati\License\Duplicati.License.csproj", "{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Modules.Builtin", "Duplicati\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj", "{52826615-7964-47FE-B4B3-1B2DBDF605B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.TahoeLAFS", "Duplicati\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj", "{C0270709-2A40-43B5-8CF1-69581B9FA2A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OneDrive", "Duplicati\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj", "{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SSHv2", "Duplicati\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj", "{FF2BF37C-E502-4C98-BEA0-701671DDFA08}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server", "Duplicati\Server\Duplicati.Server.csproj", "{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.GUI.TrayIcon", "Duplicati\GUI\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj", "{17566860-3D98-4604-AA5B-47661F75609F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Server.Serialization", "Duplicati\Server\Duplicati.Server.Serialization\Duplicati.Server.Serialization.csproj", "{33FD1D24-C28F-4C71-933F-98F1586EA76C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.BackendTool", "Duplicati\CommandLine\BackendTool\Duplicati.CommandLine.BackendTool.csproj", "{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.SQLiteHelper", "Duplicati\Library\SQLiteHelper\Duplicati.Library.SQLiteHelper.csproj", "{2C838169-B187-4B09-8768-1C24C2521C8D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Localization", "Duplicati\Library\Localization\Duplicati.Library.Localization.csproj", "{B68F2214-951F-4F78-8488-66E1ED3F50BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.AutoUpdater", "Duplicati\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj", "{7E119745-1F62-43F0-936C-F312A1912C0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Service", "Duplicati\Service\Duplicati.Service.csproj", "{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AzureBlob", "Duplicati\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj", "{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.UnitTest", "Duplicati\UnitTest\Duplicati.UnitTest.csproj", "{ECB63D1C-1724-442D-9228-DEABF14F2EA3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.OAuthHelper", "Duplicati\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj", "{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.GoogleServices", "Duplicati\Library\Backend\GoogleServices\Duplicati.Library.Backend.GoogleServices.csproj", "{5489181D-950C-44AF-873C-45EB0A3B6BD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.OpenStack", "Duplicati\Library\Backend\OpenStack\Duplicati.Library.Backend.OpenStack.csproj", "{D9E4E686-423C-48EC-A392-404E7C00860C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.HubiC", "Duplicati\Library\Backend\HubiC\Duplicati.Library.Backend.HubiC.csproj", "{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine.RecoveryTool", "Duplicati\CommandLine\RecoveryTool\Duplicati.CommandLine.RecoveryTool.csproj", "{4A010589-76E6-4F05-A5C4-4598D5DF11F8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AmazonCloudDrive", "Duplicati\Library\Backend\AmazonCloudDrive\Duplicati.Library.Backend.AmazonCloudDrive.csproj", "{08D7E42D-285C-4010-9881-986125FE2F3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Backblaze", "Duplicati\Library\Backend\Backblaze\Duplicati.Library.Backend.Backblaze.csproj", "{61C43D61-4368-4942-84A3-1EB623F4EF2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Mega", "Duplicati\Library\Backend\Mega\Duplicati.Library.Backend.Mega.csproj", "{6643A5AE-AB38-453F-ADCE-408E35A81A83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Box", "Duplicati\Library\Backend\Box\Duplicati.Library.Backend.Box.csproj", "{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.UsageReporter", "Duplicati\Library\UsageReporter\Duplicati.Library.UsageReporter.csproj", "{BB014EA5-CE2C-4444-8D30-38983A0E8553}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.SharePoint", "Duplicati\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj", "{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsService", "Duplicati\WindowsService\WindowsService.csproj", "{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.AlternativeFTP", "Duplicati\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj", "{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Dropbox", "Duplicati\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj", "{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Tools", "Duplicati\Tools\Duplicati.Tools.csproj", "{0797AA22-C5DD-4950-BB60-34765AB8C6DD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{08D7E42D-285C-4010-9881-986125FE2F3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08D7E42D-285C-4010-9881-986125FE2F3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08D7E42D-285C-4010-9881-986125FE2F3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08D7E42D-285C-4010-9881-986125FE2F3E}.Release|Any CPU.Build.0 = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.Build.0 = Release|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17566860-3D98-4604-AA5B-47661F75609F}.Release|Any CPU.Build.0 = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|Any CPU.Build.0 = Release|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}.Release|Any CPU.Build.0 = Release|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C838169-B187-4B09-8768-1C24C2521C8D}.Release|Any CPU.Build.0 = Release|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|Any CPU.Build.0 = Release|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}.Release|Any CPU.Build.0 = Release|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}.Release|Any CPU.Build.0 = Release|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A010589-76E6-4F05-A5C4-4598D5DF11F8}.Release|Any CPU.Build.0 = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|Any CPU.Build.0 = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|Any CPU.Build.0 = Release|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5489181D-950C-44AF-873C-45EB0A3B6BD2}.Release|Any CPU.Build.0 = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}.Release|Any CPU.Build.0 = Release|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61C43D61-4368-4942-84A3-1EB623F4EF2A}.Release|Any CPU.Build.0 = Release|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6643A5AE-AB38-453F-ADCE-408E35A81A83}.Release|Any CPU.Build.0 = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E119745-1F62-43F0-936C-F312A1912C0B}.Release|Any CPU.Build.0 = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|Any CPU.Build.0 = Release|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}.Release|Any CPU.Build.0 = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B68F2214-951F-4F78-8488-66E1ED3F50BF}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|Any CPU.Build.0 = Release|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB014EA5-CE2C-4444-8D30-38983A0E8553}.Release|Any CPU.Build.0 = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|Any CPU.Build.0 = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|Any CPU.Build.0 = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}.Release|Any CPU.Build.0 = Release|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|Any CPU.Build.0 = Release|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9E4E686-423C-48EC-A392-404E7C00860C}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|Any CPU.Build.0 = Release|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}.Release|Any CPU.Build.0 = Release|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECB63D1C-1724-442D-9228-DEABF14F2EA3}.Release|Any CPU.Build.0 = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.Build.0 = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|Any CPU.Build.0 = Release|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}.Release|Any CPU.Build.0 = Release|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}.Release|Any CPU.Build.0 = Release|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0797AA22-C5DD-4950-BB60-34765AB8C6DD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.StandardHeader = $1
$1.Text = @ Copyright (C) ${Year}, The Duplicati Team\n http://www.duplicati.com, info@duplicati.com\n \n This library is free software; you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as\n published by the Free Software Foundation; either version 2.1 of the\n License, or (at your option) any later version.\n\n This library is distributed in the hope that it will be useful, but\n WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public\n License along with this library; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$1.IncludeInNewFiles = True
$0.DotNetNamingPolicy = $2
$2.DirectoryNamespaceAssociation = PrefixedHierarchical
$2.ResourceNamePolicy = FileFormatDefault
$0.TextStylePolicy = $3
$3.FileWidth = 120
$3.inheritsSet = null
$3.inheritsScope = text/plain
$3.EolMarker = Windows
$3.scope = text/microsoft-resx
$0.TextStylePolicy = $4
$4.FileWidth = 120
$4.TabsToSpaces = True
$4.EolMarker = Windows
$4.inheritsSet = VisualStudio
$4.inheritsScope = text/plain
$4.scope = text/plain
$0.CSharpFormattingPolicy = $5
$5.NewLinesForBracesInProperties = True
$5.NewLinesForBracesInAccessors = True
$5.NewLinesForBracesInAnonymousMethods = True
$5.NewLinesForBracesInControlBlocks = True
$5.NewLinesForBracesInAnonymousTypes = True
$5.NewLinesForBracesInObjectCollectionArrayInitializers = True
$5.NewLinesForBracesInLambdaExpressionBody = True
$5.NewLineForElse = True
$5.NewLineForCatch = True
$5.NewLineForFinally = True
$5.NewLineForMembersInObjectInit = True
$5.NewLineForMembersInAnonymousTypes = True
$5.NewLineForClausesInQuery = True
$5.SpacingAfterMethodDeclarationName = False
$5.SpaceAfterMethodCallName = False
$5.SpaceBeforeOpenSquareBracket = False
$5.inheritsSet = Mono
$5.inheritsScope = text/x-csharp
$5.scope = text/x-csharp
$0.XmlFormattingPolicy = $6
$6.inheritsSet = null
$6.inheritsScope = application/xml
$6.scope = image/svg+xml
$0.NameConventionPolicy = $7
$7.Rules = $8
$8.NamingRule = $9
$9.Name = Type Parameters
$9.AffectedEntity = TypeParameter
$9.VisibilityMask = VisibilityMask
$9.NamingStyle = PascalCase
$9.IncludeInstanceMembers = True
$9.IncludeStaticEntities = True
$9.RequiredPrefixes = $10
$10.String = T
$9.RequiredSuffixes = $11
$11.String = Exception
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
EndGlobal
@@ -3,8 +3,6 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E7280DCA-7776-4A73-B9B5-41FD77FC8799}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
@@ -15,7 +13,7 @@
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<SignAssembly>true</SignAssembly>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
@@ -47,7 +45,6 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="NonSeekableStream.cs" />
@@ -58,15 +55,21 @@
<None Include="Duplicati.snk" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="app.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Backend\AzureBlob\Duplicati.Library.Backend.AzureBlob.csproj">
<Project>{8E4CECFB-0413-4B00-AB93-78D1C3902BD5}</Project>
<Name>Duplicati.Library.Backend.AzureBlob</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{b20a7cee-9c5b-47b9-8b76-bc85adfe8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59c8bbc5-6e42-46fb-ab3e-6c183a82459a}</Project>
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
@@ -165,6 +168,10 @@
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -3,13 +3,11 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Duplicati.CommandLine.BackendTool</RootNamespace>
<AssemblyName>Duplicati.CommandLine.BackendTool</AssemblyName>
<SignAssembly>true</SignAssembly>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>..\Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
@@ -41,9 +39,6 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\thirdparty\Json.NET\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@@ -72,7 +67,7 @@
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59c8bbc5-6e42-46fb-ab3e-6c183a82459a}</Project>
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
@@ -139,6 +134,14 @@
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
+34 -26
View File
@@ -123,6 +123,12 @@ namespace Duplicati.CommandLine
}
}
}
public static int Examples(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
Duplicati.CommandLine.Help.PrintUsage("example", options);
return 0;
}
public static int Help(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
@@ -349,34 +355,34 @@ namespace Duplicati.CommandLine
}
public static int Delete(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
var requiredOptions = new string[] { "keep-time", "keep-versions", "version" };
{
var requiredOptions = new string[] { "keep-time", "keep-versions", "version" };
if (!options.Keys.Where(x => requiredOptions.Contains(x, StringComparer.InvariantCultureIgnoreCase)).Any())
{
Console.WriteLine(Strings.Program.DeleteCommandNeedsOptions("delete", requiredOptions));
return 200;
}
if (!options.Keys.Where(x => requiredOptions.Contains(x, StringComparer.InvariantCultureIgnoreCase)).Any())
{
Console.WriteLine(Strings.Program.DeleteCommandNeedsOptions("delete", requiredOptions));
return 200;
}
using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
{
args.RemoveAt(0);
var res = i.Delete();
using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
{
args.RemoveAt(0);
var res = i.Delete();
if (res.DeletedSets.Count() == 0)
{
Console.WriteLine(Strings.Program.NoFilesetsMatching);
}
else
{
if (res.Dryrun)
Console.WriteLine(Strings.Program.WouldDeleteBackups);
else
Console.WriteLine(Strings.Program.DeletedBackups);
foreach(var f in res.DeletedSets)
Console.WriteLine(string.Format("{0}: {1}", f.Item1, f.Item2));
}
if (res.DeletedSets.Count() == 0)
{
Console.WriteLine(Strings.Program.NoFilesetsMatching);
}
else
{
if (res.Dryrun)
Console.WriteLine(Strings.Program.WouldDeleteBackups);
else
Console.WriteLine(Strings.Program.DeletedBackups);
foreach(var f in res.DeletedSets)
Console.WriteLine(string.Format("{0}: {1}", f.Item1, f.Item2));
}
}
return 0;
@@ -828,9 +834,11 @@ namespace Duplicati.CommandLine
foreach(var line in i.SystemInfo().Lines)
Console.WriteLine(line);
Console.WriteLine("Know locales: {0}", string.Join(", ", Library.Localization.LocalizationService.AllLocales));
Console.WriteLine("Translated locales: {0}", string.Join(", ", Library.Localization.LocalizationService.SupportedCultures));
return 0;
}
}
}
@@ -3,14 +3,12 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{81765A64-3661-4E3E-B850-2F6F87A51F74}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.CommandLine</RootNamespace>
<AssemblyName>Duplicati.CommandLine</AssemblyName>
<SignAssembly>true</SignAssembly>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<ApplicationIcon>TrayWarning.ico</ApplicationIcon>
<FileUpgradeFlags>
@@ -45,12 +43,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\thirdparty\Json.NET\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Help.cs" />
@@ -189,44 +182,20 @@
<Project>{BB014EA5-CE2C-4444-8D30-38983A0E8553}</Project>
<Name>Duplicati.Library.UsageReporter</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
<ProjectReference Include="..\Tools\Duplicati.Tools.csproj">
<Project>{0797AA22-C5DD-4950-BB60-34765AB8C6DD}</Project>
<Name>Duplicati.Tools</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Duplicati.snk" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<Content Include="..\..\thirdparty\gpg\gpg2.exe">
<Link>win-tools\gpg2.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\gpg\gpg.exe">
<Link>win-tools\gpg\gpg.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\iconv.dll">
<Link>win-tools\iconv.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\libadns-1.dll">
<Link>win-tools\libadns-1.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\libassuan-0.dll">
<Link>win-tools\libassuan-0.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\libgcrypt-11.dll">
<Link>win-tools\libgcrypt-11.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\libgpg-error-0.dll">
<Link>win-tools\libgpg-error-0.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\thirdparty\gpg\zlib1.dll">
<Link>win-tools\zlib1.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<EmbeddedResource Include="help.txt" />
<Content Include="TrayWarning.ico" />
</ItemGroup>
+1 -1
View File
@@ -158,7 +158,7 @@ namespace Duplicati.CommandLine
tp = tp.Replace("%ALLOPTIONS%", string.Join(Environment.NewLine, lines.ToArray()));
}
if (tp.Contains("%MODULEOPTIONS%"))
{
//Figure out which module we are in
+31 -25
View File
@@ -44,18 +44,18 @@ namespace Duplicati.CommandLine
bool verbose = false;
try
{
List<string> cargs = new List<string>(args);
List<string> cargs = new List<string>(args);
var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(cargs);
var options = tmpparsed.Item1;
var filter = tmpparsed.Item2;
var options = tmpparsed.Item1;
var filter = tmpparsed.Item2;
verboseErrors = Library.Utility.Utility.ParseBoolOption(options, "debug-output");
verbose = Library.Utility.Utility.ParseBoolOption(options, "verbose");
//If we are on Windows, append the bundled "win-tools" programs to the search path
//We add it last, to allow the user to override with other versions
if (!Library.Utility.Utility.IsClientLinux)
if (Library.Utility.Utility.IsClientWindows)
{
string wintools = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "win-tools");
Environment.SetEnvironmentVariable("PATH",
@@ -136,8 +136,12 @@ namespace Duplicati.CommandLine
var knownCommands = new Dictionary<string, Func<List<string>, Dictionary<string, string>, Library.Utility.IFilter, int>>(StringComparer.InvariantCultureIgnoreCase);
knownCommands["help"] = Commands.Help;
knownCommands["example"] = Commands.Examples;
knownCommands["examples"] = Commands.Examples;
knownCommands["find"] = Commands.List;
knownCommands["list"] = Commands.List;
knownCommands["delete"] = Commands.Delete;
knownCommands["backup"] = Commands.Backup;
knownCommands["restore"] = Commands.Restore;
@@ -152,7 +156,9 @@ namespace Duplicati.CommandLine
knownCommands["test-filters"] = Commands.TestFilters;
knownCommands["test-filter"] = Commands.TestFilters;
knownCommands["affected"] = Commands.Affected;
knownCommands["system-info"] = Commands.SystemInfo;
knownCommands["systeminfo"] = Commands.SystemInfo;
if (!isHelp && verbose)
{
@@ -271,15 +277,15 @@ namespace Duplicati.CommandLine
var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(fargs, (key, value) => {
if (key.Equals("source", StringComparison.OrdinalIgnoreCase))
{
newsource.Add(value);
return false;
}
{
newsource.Add(value);
return false;
}
else if (key.Equals("target", StringComparison.OrdinalIgnoreCase))
{
newtarget = value;
return false;
}
{
newtarget = value;
return false;
}
else if (key.Equals("append-filter", StringComparison.OrdinalIgnoreCase))
{
appendfilter = value;
@@ -296,9 +302,9 @@ namespace Duplicati.CommandLine
return false;
}
return true;
});
return true;
});
var opt = tmpparsed.Item1;
var newfilter = tmpparsed.Item2;
@@ -307,8 +313,8 @@ namespace Duplicati.CommandLine
if (!filter.Empty && !newfilter.Empty)
throw new Exception(Strings.Program.FiltersCannotBeUsedWithFileError2);
if (!newfilter.Empty)
filter = newfilter;
if (!newfilter.Empty)
filter = newfilter;
if (!string.IsNullOrWhiteSpace(prependfilter))
filter = Library.Utility.FilterExpression.Combine(Library.Utility.FilterExpression.Deserialize(prependfilter.Split(new string[] {System.IO.Path.PathSeparator.ToString()}, StringSplitOptions.RemoveEmptyEntries)), filter);
@@ -323,15 +329,15 @@ namespace Duplicati.CommandLine
options[keyvalue.Key] = keyvalue.Value;
if (!string.IsNullOrEmpty(newtarget))
{
if (cargs.Count <= 1)
cargs.Add(newtarget);
else
cargs[1] = newtarget;
}
{
if (cargs.Count <= 1)
cargs.Add(newtarget);
else
cargs[1] = newtarget;
}
if (cargs.Count >= 1 && cargs[0].Equals("backup", StringComparison.InvariantCultureIgnoreCase))
cargs.AddRange(newsource);
cargs.AddRange(newsource);
else if (newsource.Count > 0 && Library.Utility.Utility.ParseBoolOption(options, "verbose"))
Console.WriteLine(Strings.Program.SkippingSourceArgumentsOnNonBackupOperation);
@@ -3,13 +3,11 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4A010589-76E6-4F05-A5C4-4598D5DF11F8}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Duplicati.CommandLine.RecoveryTool</RootNamespace>
<AssemblyName>Duplicati.CommandLine.RecoveryTool</AssemblyName>
<SignAssembly>true</SignAssembly>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
@@ -39,6 +37,9 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@@ -47,6 +48,7 @@
<Compile Include="Help.cs" />
<Compile Include="Index.cs" />
<Compile Include="List.cs" />
<Compile Include="Recompress.cs" />
<Compile Include="Restore.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
@@ -92,7 +94,7 @@
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59c8bbc5-6e42-46fb-ab3e-6c183a82459a}</Project>
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
@@ -147,8 +149,19 @@
<Project>{3FF7DD0B-5284-4BF9-97D9-1E4417FDABB2}</Project>
<Name>Duplicati.Library.Backend.Box</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="help.txt" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>
@@ -77,6 +77,7 @@ namespace Duplicati.CommandLine.RecoveryTool
var actions = new Dictionary<string, CommandRunner>(StringComparer.InvariantCultureIgnoreCase);
actions["download"] = Download.Run;
actions["recompress"] = Recompress.Run;
actions["index"] = Index.Run;
actions["list"] = List.Run;
actions["restore"] = Restore.Run;
@@ -0,0 +1,301 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Duplicati.Library.Main;
using Duplicati.Library.Main.Volumes;
using Duplicati.Library.Utility;
using Newtonsoft.Json.Linq;
namespace Duplicati.CommandLine.RecoveryTool
{
public static class Recompress
{
public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args.Count != 4)
{
Console.WriteLine("Invalid argument count ({0} expected 4): {1}{2}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args));
return 100;
}
string target_compr_module = args[1];
if (!Library.DynamicLoader.CompressionLoader.Keys.Contains(target_compr_module))
{
Console.WriteLine("Target compression module not found: {0}{1}Modules supported: {2}", args[1], Environment.NewLine, string.Join(", ", Library.DynamicLoader.CompressionLoader.Keys));
return 100;
}
var m_Options = new Options(options);
using (var backend = Library.DynamicLoader.BackendLoader.GetBackend(args[2], options))
{
if (backend == null)
{
Console.WriteLine("Backend not found: {0}{1}Backends supported: {2}", args[2], Environment.NewLine, string.Join(", ", Library.DynamicLoader.BackendLoader.Keys));
return 100;
}
var targetfolder = Path.GetFullPath(args[3]);
if (!Directory.Exists(args[3]))
{
Console.WriteLine("Creating target folder: {0}", targetfolder);
Directory.CreateDirectory(targetfolder);
}
Console.WriteLine("Listing files on backend: {0} ...", backend.ProtocolKey);
var rawlist = backend.List();
Console.WriteLine("Found {0} files at remote storage", rawlist.Count);
var i = 0;
var downloaded = 0;
var errors = 0;
var needspass = 0;
var remotefiles =
(from x in rawlist
let n = VolumeBase.ParseFilename(x)
where n != null && n.Prefix == m_Options.Prefix
select n).ToArray(); //ToArray() ensures that we do not remote-request it multiple times
if (remotefiles.Length == 0)
{
if (rawlist.Count == 0)
Console.WriteLine("No files were found at the remote location, perhaps the target url is incorrect?");
else
{
var tmp =
(from x in rawlist
let n = VolumeBase.ParseFilename(x)
where
n != null
select n.Prefix).ToArray();
var types = tmp.Distinct().ToArray();
if (tmp.Length == 0)
Console.WriteLine("Found {0} files at the remote storage, but none that could be parsed", rawlist.Count);
else if (types.Length == 1)
Console.WriteLine("Found {0} parse-able files with the prefix {1}, did you forget to set the backup-prefix?", tmp.Length, types[0]);
else
Console.WriteLine("Found {0} parse-able files (of {1} files) with different prefixes: {2}, did you forget to set the backup-prefix?", tmp.Length, rawlist.Count, string.Join(", ", types));
}
return 100;
}
bool reencrypt = Library.Utility.Utility.ParseBoolOption(options, "reencrypt");
bool reupload = Library.Utility.Utility.ParseBoolOption(options, "reupload");
// Needs order (Files or Blocks) and Indexes as last because indexes content will be adjusted based on recompressed blocks
var files = remotefiles.Where(a => a.FileType == RemoteVolumeType.Files).ToArray();
var blocks = remotefiles.Where(a => a.FileType == RemoteVolumeType.Blocks).ToArray();
var indexes = remotefiles.Where(a => a.FileType == RemoteVolumeType.Index).ToArray();
remotefiles = files.Concat(blocks).ToArray().Concat(indexes).ToArray();
Console.WriteLine("Found {0} files which belongs to backup with prefix {1}", remotefiles.Count(), m_Options.Prefix);
foreach (var remoteFile in remotefiles)
{
try
{
Console.Write("{0}/{1}: {2}", ++i, remotefiles.Count(), remoteFile.File.Name);
var localFileSource = Path.Combine(targetfolder, remoteFile.File.Name);
string localFileTarget;
string localFileSourceEncryption = "";
if (remoteFile.EncryptionModule != null)
{
if (string.IsNullOrWhiteSpace(m_Options.Passphrase))
{
needspass++;
Console.WriteLine(" - No passphrase supplied, skipping");
continue;
}
using (var m = Library.DynamicLoader.EncryptionLoader.GetModule(remoteFile.EncryptionModule, m_Options.Passphrase, options))
localFileSourceEncryption = m.FilenameExtension;
localFileSource = localFileSource.Substring(0, localFileSource.Length - localFileSourceEncryption.Length - 1);
}
if (remoteFile.CompressionModule != null)
localFileTarget = localFileSource.Substring(0, localFileSource.Length - remoteFile.CompressionModule.Length - 1) + "." + target_compr_module;
else
{
Console.WriteLine(" - cannot detect compression type");
continue;
}
if ((!reencrypt && File.Exists(localFileTarget)) || (reencrypt && File.Exists(localFileTarget + "." + localFileSourceEncryption)))
{
Console.WriteLine(" - target file already exist");
continue;
}
if (File.Exists(localFileSource))
File.Delete(localFileSource);
Console.Write(" - downloading ({0})...", Library.Utility.Utility.FormatSizeString(remoteFile.File.Size));
DateTime originLastWriteTime;
FileInfo destinationFileInfo;
using (var tf = new TempFile())
{
backend.Get(remoteFile.File.Name, tf);
originLastWriteTime = new FileInfo(tf).LastWriteTime;
downloaded++;
if (remoteFile.EncryptionModule != null)
{
Console.Write(" decrypting ...");
using (var m = Library.DynamicLoader.EncryptionLoader.GetModule(remoteFile.EncryptionModule, m_Options.Passphrase, options))
using (var tf2 = new TempFile())
{
m.Decrypt(tf, tf2);
File.Copy(tf2, localFileSource);
File.Delete(tf2);
}
}
else
File.Copy(tf, localFileSource);
File.Delete(tf);
destinationFileInfo = new FileInfo(localFileSource);
destinationFileInfo.LastWriteTime = originLastWriteTime;
}
if (remoteFile.CompressionModule != null)
{
Console.Write(" recompressing ...");
//Recompressing from eg. zip to zip
if (localFileSource == localFileTarget)
{
File.Move(localFileSource, localFileSource + ".same");
localFileSource = localFileSource + ".same";
}
using (var cmOld = Library.DynamicLoader.CompressionLoader.GetModule(remoteFile.CompressionModule, localFileSource, options))
using (var cmNew = Library.DynamicLoader.CompressionLoader.GetModule(target_compr_module, localFileTarget, options))
foreach (var cmfile in cmOld.ListFiles(""))
{
string cmfileNew = cmfile;
var cmFileVolume = VolumeBase.ParseFilename(cmfileNew);
if (remoteFile.FileType == RemoteVolumeType.Index && cmFileVolume != null && cmFileVolume.FileType == RemoteVolumeType.Blocks)
{
// Correct inner filename extension to target compression type
cmfileNew = cmfileNew.Replace("." + cmFileVolume.CompressionModule, "." + target_compr_module);
if (!reencrypt)
cmfileNew = cmfileNew.Replace("." + cmFileVolume.EncryptionModule, "");
//Because compression changes blocks file sizes - needs to be updated
string textJSON;
using (var sourceStream = cmOld.OpenRead(cmfile))
using (var sourceStreamReader = new StreamReader(sourceStream))
{
textJSON = sourceStreamReader.ReadToEnd();
JToken token = JObject.Parse(textJSON);
var fileInfoBlocks = new FileInfo(Path.Combine(targetfolder, cmfileNew.Replace("vol/", "")));
var filehasher = System.Security.Cryptography.HashAlgorithm.Create(m_Options.FileHashAlgorithm);
using (var fileStream = fileInfoBlocks.Open(FileMode.Open))
{
fileStream.Position = 0;
token["volumehash"] = Convert.ToBase64String(filehasher.ComputeHash(fileStream));
fileStream.Close();
}
token["volumesize"] = fileInfoBlocks.Length;
textJSON = token.ToString();
}
using (var sourceStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(textJSON)))
using (var cs = cmNew.CreateFile(cmfileNew, Library.Interface.CompressionHint.Compressible, cmOld.GetLastWriteTime(cmfile)))
Library.Utility.Utility.CopyStream(sourceStream, cs);
}
else
{
using (var sourceStream = cmOld.OpenRead(cmfile))
using (var cs = cmNew.CreateFile(cmfileNew, Library.Interface.CompressionHint.Compressible, cmOld.GetLastWriteTime(cmfile)))
Library.Utility.Utility.CopyStream(sourceStream, cs);
}
}
File.Delete(localFileSource);
destinationFileInfo = new FileInfo(localFileTarget);
destinationFileInfo.LastWriteTime = originLastWriteTime;
}
if (reencrypt && remoteFile.EncryptionModule != null)
{
Console.Write(" reencrypting ...");
using (var m = Library.DynamicLoader.EncryptionLoader.GetModule(remoteFile.EncryptionModule, m_Options.Passphrase, options))
{
m.Encrypt(localFileTarget, localFileTarget + "." + localFileSourceEncryption);
File.Delete(localFileTarget);
localFileTarget = localFileTarget + "." + localFileSourceEncryption;
}
destinationFileInfo = new FileInfo(localFileTarget);
destinationFileInfo.LastWriteTime = originLastWriteTime;
}
if (reupload)
{
Console.Write(" reuploading ...");
backend.Put((new FileInfo(localFileTarget)).Name, localFileTarget);
backend.Delete(remoteFile.File.Name);
File.Delete(localFileTarget);
}
Console.WriteLine(" done!");
}
catch (Exception ex)
{
Console.WriteLine(" error: {0}", ex.ToString());
errors++;
}
}
if (reupload)
{
var remoteverificationfileexist = rawlist.Any(x => x.Name == (m_Options.Prefix + "-verification.json"));
if (remoteverificationfileexist)
{
Console.WriteLine("Found verification file {0} - deleting", m_Options.Prefix + "-verification.json");
backend.Delete(m_Options.Prefix + "-verification.json");
}
}
if (needspass > 0 && downloaded == 0)
{
Console.WriteLine("No files downloaded, try adding --passphrase to decrypt files");
return 100;
}
Console.WriteLine("Download complete, of {0} remote files, {1} were downloaded with {2} errors", remotefiles.Count(), downloaded, errors);
if (needspass > 0)
Console.WriteLine("Additonally {0} remote files were skipped because of encryption, supply --passphrase to download those");
if (errors > 0)
{
Console.WriteLine("There were errors during recompress of remote backend files!");
return 200;
}
return 0;
}
}
}
}
+12 -1
View File
@@ -245,9 +245,20 @@ namespace Duplicati.CommandLine.RecoveryTool
private static string MapToRestorePath(string path, string prefixpath, string restorepath)
{
if (string.IsNullOrWhiteSpace(restorepath) || string.IsNullOrWhiteSpace(prefixpath))
if (string.IsNullOrWhiteSpace(restorepath))
return path;
if (string.IsNullOrWhiteSpace(prefixpath))
{
//Special case, restoring to new folder, but files are from different drives
// So we use the format <restore path> / <drive letter> / <source path>
// To avoid generating paths with a colon
if (path.Substring(1, 1) == ":")
prefixpath = path.Substring(0, 1) + path.Substring(2);
return Path.Combine(restorepath, prefixpath);
}
return Path.Combine(restorepath, path.Substring(prefixpath.Length));
}
@@ -24,6 +24,10 @@ Optionally you can also run:
4: List
Shows what files are available and tests filters
5: Recompress
Ability to change compression type of files on remote backend eg. from 7z to zip
Command descriptions:
@@ -72,6 +76,22 @@ If [version] is omitted a list of backup versions are shown, if [version] is sup
Use the filters, --exclude, to show a subset of files.
Recompress
----
Duplicati.RecoveryTool.exe recompress <targetcompression> <remoteurl> <localfolder> --reupload --reencrypt [options]
1) Downloads whole remote storage to <localfolder>.
2) Recompress from existing compression type to <targetcompression>
3) If --reencrypt is supplied, again reencrypts using same passphrase (needs to be decrypted for compression type change)
4) If --reupload is supplied, files with old compression are deleted and recompressed files are uploaded back to remote storage (it is recommended to take at least temporary copy of remote storage before enabling this switch)
If --reupload is supplied it is advisable to specify --reencrypt for perfect security.
Warning: Before recompress delete local database and after recompress recreate local database before executing any operation on backup. This allows Duplicati to read new file names from remote storage.
Supported Options
-----------------
The backend modules support all their normal options.
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
</packages>
+10 -8
View File
@@ -11,7 +11,7 @@
See duplicati.commandline.exe help <topic> for more information.
General: example, changelog
Commands: backup, find, restore, delete, compact, test, compare, repair
Commands: backup, find, restore, delete, compact, test, compare, repair, affected
Debugging: debug, logging, create-report, test-filters, system-info
Targets: %BACKENDS%
Modules: %ENCRYPTIONMODULES%, %COMPRESSIONMODULES%, %GENERICMODULES%
@@ -33,13 +33,15 @@ Show the last changes to Duplicati
# =============================================================================
> duplicati.commandline.exe help system-info
> duplicati.commandline.exe help systeminfo
Show system information as seen by Duplicati
==================================
============================================
Issue the following command to see a variety of system information relevant to Duplicati.
%MONO%"%APP_PATH%" system-info
# =============================================================================
> duplicati.commandline.exe help example
> duplicati.commandline.exe help examples
@@ -196,7 +198,7 @@ Usage: repair <storage-URL> [<options>]
> duplicati.commandline.exe help test
> duplicati.commandline.exe help verify
Usage: test <storage-URL> [<samples>] [<options>]
Usage: test <storage-URL> <samples> [<options>]
Verifies integrity of a backup. A random sample of dlist, dindex, dblock files is downloaded, decrypted and the content is checked against recorded size values and data hashes. <samples> specifies the number of samples to be tested. If "all” is specified, all files in the backup will be tested. This is a rolling check, i.e. when executed another time different samples are verified than in the first run. A sample consists of 1 dlist, 1 dindex, 1 dblock.
@@ -204,6 +206,8 @@ Usage: test <storage-URL> [<samples>] [<options>]
Checks samples from a specific time.
--version=<int>
Checks samples from specific versions. Delimiters are , -
--full-remote-verification
Checks the internal structure of each file instead of just verifying the file hash
@@ -221,7 +225,7 @@ Usage: test-filters <source-path> [<options>]
Usage: affected <storage-URL> <remote-filename> [<remote-filenames>] [<options>]
Returns a report explaning what backup sets and files are affected by a remote file. You
Returns a report explaning what backup sets and files are affected by a remote file. You can use this option to see what source files are affected if one or more remote files are damaged or deleted.
# =============================================================================
@@ -238,8 +242,6 @@ Duplicati provides information for debugging and logging purposes. By default, a
The path to the log file e.g. "D:\duplicati\log.txt".
--log-level = Profiling | Information | Warning | Error
Specifies the log level.
--backend-log-database = <path>
Duplicati can log all actions related to storing, deleting files on the backend. <path> specifies where this log is written e.g. "D:\duplicati\backend.xml".
# =============================================================================
@@ -437,8 +439,8 @@ Duplicati offers more options than listed in the other topics. Those additional
Duplicati reports the following return/exit codes:
0 - Success
1 - Successful backup, but no files were changed
2 - Successful backup, with warnings
1 - Successful operation, but no files were changed
2 - Successful operation, but with warnings
50 - Backup uploaded some files, but did not finish
100 - An error occurred
200 - Invalid commandline arguments found
@@ -124,7 +124,7 @@ namespace Duplicati.GUI.TrayIcon
var dp = new CGDataProvider(b, 0, b.Length);
var img2 = CGImage.FromPNG(dp, null, false, CGColorRenderingIntent.Default);
return new NSImage(img2, new System.Drawing.SizeF(21, 21));
return new NSImage(img2, new System.Drawing.SizeF(18, 18));
}
}
@@ -3,8 +3,6 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{17566860-3D98-4604-AA5B-47661F75609F}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
@@ -66,13 +64,8 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="appindicator-sharp">
<HintPath>..\..\..\thirdparty\appindicator-sharp\appindicator-sharp.dll</HintPath>
<Private>False</Private>
@@ -92,6 +85,13 @@
<HintPath>..\..\..\thirdparty\notify-sharp\notify-sharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="CoCoL">
<HintPath>..\..\..\packages\CoCoL.1.5.0\lib\net45\CoCoL.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="IBrowserWindow.cs" />
@@ -135,10 +135,12 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<Compile Include="WinFormsRunner.cs" />
<EmbeddedResource Include="Resources\CloseMenuIcon.png" />
<EmbeddedResource Include="Resources\Pause.png" />
<EmbeddedResource Include="Resources\Play.png" />
<EmbeddedResource Include="Resources\StatusMenuIcon.png" />
<Compile Include="RumpsRunner.cs" />
<None Include="packages.config" />
<EmbeddedResource Include="Resources\context_menu_open.ico" />
<EmbeddedResource Include="Resources\context_menu_pause.ico" />
<EmbeddedResource Include="Resources\context_menu_play.ico" />
<EmbeddedResource Include="Resources\context_menu_quit.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
@@ -157,12 +159,16 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj">
<Project>{d4c37c33-5e73-4b56-b2c3-dc4a6baa36bb}</Project>
<Name>Duplicati.Library.OAuthHelper</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj">
<Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
<Name>Duplicati.Library.Backend.S3</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59c8bbc5-6e42-46fb-ab3e-6c183a82459a}</Project>
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
@@ -293,6 +299,22 @@
<Project>{BB014EA5-CE2C-4444-8D30-38983A0E8553}</Project>
<Name>Duplicati.Library.UsageReporter</Name>
</ProjectReference>
<ProjectReference Include="..\..\WindowsService\WindowsService.csproj">
<Project>{bef7af9a-3978-4f90-8592-198bf6ea6c6b}</Project>
<Name>WindowsService</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\AlternativeFTP\Duplicati.Library.Backend.AlternativeFTP.csproj">
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
<ProjectReference Include="..\..\Tools\Duplicati.Tools.csproj">
<Project>{0797AA22-C5DD-4950-BB60-34765AB8C6DD}</Project>
<Name>Duplicati.Tools</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
@@ -343,5 +365,12 @@
<Content Include="SVGIcons\dark\normal.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="OSXTrayHost\osx-trayicon-rumps.py">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\thirdparty\rumps\rumps.py">
<Link>OSXTrayHost\rumps.py</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 84 KiB

@@ -341,7 +341,7 @@ namespace Duplicati.GUI.TrayIcon
string query = EncodeQueryString(queryparams);
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new Uri(m_apiUri + endpoint + '?' + query));
var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new Uri(m_apiUri + endpoint + '?' + query));
req.Method = method;
req.Headers.Add("Accept-Charset", ENCODING.BodyName);
if (m_xsrftoken != null)
@@ -356,14 +356,14 @@ namespace Duplicati.GUI.TrayIcon
req.CookieContainer.Add(new System.Net.Cookie(XSRF_COOKIE, m_xsrftoken, "/", req.RequestUri.Host));
//Wrap it all in async stuff
Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
var areq = new Library.Utility.AsyncHttpRequest(req);
//Assign the timeout, and add a little processing time as well
if (endpoint.Equals("/serverstate", StringComparison.InvariantCultureIgnoreCase) && queryparams.ContainsKey("duration"))
areq.Timeout = (int)(Duplicati.Library.Utility.Timeparser.ParseTimeSpan(queryparams["duration"]) + TimeSpan.FromSeconds(5)).TotalMilliseconds;
using(System.Net.HttpWebResponse r = (System.Net.HttpWebResponse)areq.GetResponse())
using (System.IO.Stream s = areq.GetResponseStream())
using(var r = (System.Net.HttpWebResponse)areq.GetResponse())
using (var s = areq.GetResponseStream())
if (typeof(T) == typeof(string))
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
@@ -81,10 +81,10 @@ namespace Duplicati.GUI.TrayIcon
public const string PauseIcon = "Resources.TrayNormalPause.ico";
public const string WorkingIcon = "Resources.TrayWorking.ico";
public static Bitmap Pause { get { return LoadImage("Resources.Pause.png"); } }
public static Bitmap Play { get { return LoadImage("Resources.Play.png"); } }
public static Bitmap CloseMenuIcon { get { return LoadImage("Resources.CloseMenuIcon.png"); } }
public static Bitmap StatusMenuIcon { get { return LoadImage("Resources.StatusMenuIcon.png"); } }
public static Bitmap Pause { get { return LoadImage("Resources.context_menu_pause.ico"); } }
public static Bitmap Play { get { return LoadImage("Resources.context_menu_play.ico"); } }
public static Bitmap CloseMenuIcon { get { return LoadImage("Resources.context_menu_quit.ico"); } }
public static Bitmap StatusMenuIcon { get { return LoadImage("Resources.context_menu_open.ico"); } }
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

After

Width:  |  Height:  |  Size: 626 B

@@ -0,0 +1,202 @@
import sys
import json
import rumps
import base64
import traceback
from threading import Thread
from Foundation import NSData
from AppKit import NSImage, NSApplication
from ctypes import CDLL, Structure, POINTER, c_uint32, byref
from ctypes.util import find_library
class ProcessSerialNumber(Structure):
_fields_ = [('highLongOfPSN', c_uint32),
('lowLongOfPSN', c_uint32)]
lookup = {}
app = None
def transform_app_type(toForeground):
kCurrentProcess = 2
kProcessTransformToForegroundApplication = 1
kProcessTransformToBackgroundApplication = 2
kProcessTransformToUIElementAppication = 4
apptype = kProcessTransformToBackgroundApplication
if toForeground:
apptype = kProcessTransformToForegroundApplication
ApplicationServices = CDLL(find_library('ApplicationServices'))
TransformProcessType = ApplicationServices.TransformProcessType
TransformProcessType.argtypes = [POINTER(ProcessSerialNumber), c_uint32]
psn = ProcessSerialNumber(0, kCurrentProcess)
ApplicationServices.TransformProcessType(psn, apptype)
def item_clicked(sender):
for k in lookup:
if lookup[k].title == sender.title:
print "click:%s" % k
sys.stdout.flush()
def parsemenus(cfg):
menuitems = []
for n in cfg["Menus"]:
mn = rumps.MenuItem(n["Text"])
if n.has_key("Enabled") and not n["Enabled"]:
mn.set_callback(None)
else:
mn.set_callback(item_clicked)
lookup[n["Key"]] = mn
menuitems.append(mn)
return menuitems
def get_input():
try:
while True:
line = sys.stdin.readline()
if not line:
break
if line == '':
continue
print "info:Read %s" % line
sys.stdout.flush()
cfg = None
try:
cfg = json.loads(line)
except:
pass
if cfg == None:
print "info:Unable to parse line"
sys.stdout.flush()
continue
if cfg.has_key("Action"):
print "info:Running %s" % cfg["Action"]
sys.stdout.flush()
if cfg["Action"] == "setmenu":
menu = cfg["Menu"]
if lookup.has_key(menu["Key"]):
lookup[menu["Key"]].title = menu["Text"]
if menu.has_key("Enabled") and not menu["Enabled"]:
lookup[menu["Key"]].set_callback(None)
else:
lookup[menu["Key"]].set_callback(item_clicked)
app.menu.update([])
else:
print "warn:Key not found %s" % cfg["Action"]
sys.stdout.flush()
elif cfg["Action"] == "setmenus":
app.menu.clear()
app.menu = parsemenus(cfg)
print "info:Updated menus"
sys.stdout.flush()
elif cfg["Action"] == "seticon":
try:
raw = base64.b64decode(cfg["Image"])
data = NSData.dataWithBytes_length_(raw, len(raw))
img = NSImage.alloc().initWithData_(data)
img.setScalesWhenResized_(True)
img.setSize_((18, 18))
app.icon = img
print "info:Image updated"
sys.stdout.flush()
except:
print "warn:Failed to set image"
sys.stdout.flush()
elif cfg["Action"] == "setappicon":
try:
raw = base64.b64decode(cfg["Image"])
data = NSData.dataWithBytes_length_(raw, len(raw))
img = NSImage.alloc().initWithData_(data)
#img.setScalesWhenResized_(True)
#img.setSize_((21, 21))
NSApplication.sharedApplication().setApplicationIconImage_(img)
print "info:AppImage updated"
sys.stdout.flush()
except:
print "warn:Failed to set image"
sys.stdout.flush()
elif cfg["Action"] == "shutdown":
break
elif cfg["Action"] == "foreground":
transform_app_type(True)
elif cfg["Action"] == "background":
transform_app_type(False)
elif cfg["Action"] == "notification":
if rumps._NOTIFICATIONS:
title = cfg["Title"]
message = cfg["Message"]
subtitle = ''
playSound = True
image = None
if cfg.has_key("SubTitle"):
subtitle = cfg["SubTitle"]
if cfg.has_key("PlaySound"):
playSound = cfg["PlaySound"]
if cfg.has_key("Image"):
try:
raw = base64.b64decode(cfg["Image"])
data = NSData.dataWithBytes_length_(raw, len(raw))
image = NSImage.alloc().initWithData_(data)
except:
print "warn:Failed to decode image"
sys.stdout.flush()
rumps.notification(cfg["Title"], subtitle, cfg["Message"], sound=playSound, image=image)
finally:
try:
traceback.print_exc()
except:
pass
rumps.quit_application()
print "info:Shutdown"
sys.stdout.flush()
print "info:Stdin close"
sys.stdout.flush()
sys.stdin.close()
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "TEST":
sys.exit(0)
app = rumps.App('', quit_button=None)
transform_app_type(False)
t = Thread(target=get_input)
t.start()
app.run()
@@ -15,6 +15,7 @@ namespace Duplicati.GUI.TrayIcon
private const string TOOLKIT_GTK = "gtk";
private const string TOOLKIT_GTK_APP_INDICATOR = "gtk-appindicator";
private const string TOOLKIT_COCOA = "cocoa";
private const string TOOLKIT_RUMPS = "rumps";
private const string HOSTURL_OPTION = "hosturl";
private const string NOHOSTEDSERVER_OPTION = "no-hosted-server";
@@ -29,15 +30,9 @@ namespace Duplicati.GUI.TrayIcon
private static string GetDefaultToolKit(bool printwarnings)
{
// No longer using Cocoa directly as it fails on 32bit as well
if (Duplicati.Library.Utility.Utility.IsClientOSX)
{
if (!Environment.Is64BitProcess)
return TOOLKIT_COCOA;
if (printwarnings)
Console.WriteLine("64bit runtime detected which is known to crash the Cocoa interface, choosing GTK as the default instead");
}
return TOOLKIT_RUMPS;
#if __MonoCS__ || __WindowsGTK__
if (Duplicati.Library.Utility.Utility.IsClientLinux)
@@ -112,6 +107,8 @@ namespace Duplicati.GUI.TrayIcon
#endif
else if (TOOLKIT_COCOA.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
toolkit = TOOLKIT_COCOA;
else if (TOOLKIT_RUMPS.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
toolkit = TOOLKIT_RUMPS;
else
toolkit = GetDefaultToolKit(true);
}
@@ -215,6 +212,8 @@ namespace Duplicati.GUI.TrayIcon
#endif
else if (toolkit == TOOLKIT_COCOA)
return GetCocoaRunnerInstance();
else if (toolkit == TOOLKIT_RUMPS)
return GetRumpsRunnerInstance();
else
throw new Exception(string.Format("The selected toolkit '{0}' is invalid", toolkit));
}
@@ -237,12 +236,15 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static TrayIconBase GetCocoaRunnerInstance() { return new CocoaRunner(); }
private static TrayIconBase GetRumpsRunnerInstance() { return new RumpsRunner(); }
//The functions below simply load the requested type,
// and if the type is not present, calling the function will result in an exception.
//This seems to be more reliable than attempting to load the assembly,
// as there are too many complex rules for when an updated assembly is also
// acceptable. This is fairly error proof, as it is just asks the runtime
// to load the required types
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetGtk()
{
#if __MonoCS__ || __WindowsGTK__
@@ -252,11 +254,13 @@ namespace Duplicati.GUI.TrayIcon
#endif
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetWinforms()
{
return typeof(System.Windows.Forms.NotifyIcon) != null;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetAppIndicator()
{
#if __MonoCS__ || __WindowsGTK__
@@ -266,6 +270,7 @@ namespace Duplicati.GUI.TrayIcon
#endif
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetMonoMac()
{
return !Environment.Is64BitProcess && typeof(MonoMac.AppKit.NSApplication) != null;
@@ -307,6 +312,18 @@ namespace Duplicati.GUI.TrayIcon
}
}
private static bool SupportsRumps
{
get
{
try { return RumpsRunner.CanRun(); }
catch {}
return false;
}
}
private static bool SupportsWinForms
{
get
@@ -331,6 +348,8 @@ namespace Duplicati.GUI.TrayIcon
toolkits.Add(TOOLKIT_GTK_APP_INDICATOR);
if (SupportsCocoa)
toolkits.Add(TOOLKIT_COCOA);
if (SupportsRumps)
toolkits.Add(TOOLKIT_RUMPS);
return new Duplicati.Library.Interface.ICommandLineArgument[]
{
Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show More