Initial version of the new block-based storage format.
Still needs a work over in terms of error handling, progress reporting, warning output, refactoring etc. Also misses the volume reuse/reclaim algorithms. But it passes the unit tests now, with and without a local database. git-svn-id: https://duplicati.googlecode.com/svn/sandboxes/Kenneth/ForestHash@1526 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
|
||||
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
|
||||
@@ -0,0 +1,122 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?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.0</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>
|
||||
@@ -0,0 +1,999 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("HexaD")]
|
||||
[assembly: AssemblyProduct("LocalizationTool")]
|
||||
[assembly: AssemblyCopyright("Copyright © HexaD 2009")]
|
||||
[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("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <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 "tokens=*" %%a in ("%CD%") 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 <?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 n [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string Empty_resx {
|
||||
get {
|
||||
return ResourceManager.GetString("Empty_resx", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?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>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles />
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,230 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@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%
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,311 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
</configSections>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
@@ -0,0 +1,54 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace UpdateVersionNumber
|
||||
{
|
||||
public class DisplayItem
|
||||
{
|
||||
public DisplayItem(string file, Version version)
|
||||
{
|
||||
m_file = file;
|
||||
m_version = version;
|
||||
}
|
||||
|
||||
private string m_file;
|
||||
|
||||
public string File
|
||||
{
|
||||
get { return m_file; }
|
||||
set { m_file = value; }
|
||||
}
|
||||
private Version m_version;
|
||||
|
||||
public Version Version
|
||||
{
|
||||
get { return m_version; }
|
||||
set { m_version = value; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_file + " (" + m_version.ToString() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
namespace UpdateVersionNumber
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <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.label1 = new System.Windows.Forms.Label();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.checkedListBox1 = new System.Windows.Forms.CheckedListBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.textBox2 = new System.Windows.Forms.TextBox();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.button3 = new System.Windows.Forms.Button();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(16, 32);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(66, 13);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "New version";
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.Location = new System.Drawing.Point(96, 32);
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(100, 20);
|
||||
this.textBox1.TabIndex = 1;
|
||||
//
|
||||
// checkedListBox1
|
||||
//
|
||||
this.checkedListBox1.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.checkedListBox1.CheckOnClick = true;
|
||||
this.checkedListBox1.FormattingEnabled = true;
|
||||
this.checkedListBox1.IntegralHeight = false;
|
||||
this.checkedListBox1.Location = new System.Drawing.Point(16, 64);
|
||||
this.checkedListBox1.Name = "checkedListBox1";
|
||||
this.checkedListBox1.SelectionMode = System.Windows.Forms.SelectionMode.None;
|
||||
this.checkedListBox1.Size = new System.Drawing.Size(212, 98);
|
||||
this.checkedListBox1.Sorted = true;
|
||||
this.checkedListBox1.TabIndex = 2;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(16, 8);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(36, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "Folder";
|
||||
//
|
||||
// textBox2
|
||||
//
|
||||
this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textBox2.Location = new System.Drawing.Point(96, 8);
|
||||
this.textBox2.Name = "textBox2";
|
||||
this.textBox2.ReadOnly = true;
|
||||
this.textBox2.Size = new System.Drawing.Size(92, 20);
|
||||
this.textBox2.TabIndex = 4;
|
||||
this.textBox2.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.button1.Location = new System.Drawing.Point(196, 8);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(24, 20);
|
||||
this.button1.TabIndex = 5;
|
||||
this.button1.Text = "...";
|
||||
this.button1.UseVisualStyleBackColor = true;
|
||||
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
|
||||
this.button2.Location = new System.Drawing.Point(86, 176);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(75, 23);
|
||||
this.button2.TabIndex = 6;
|
||||
this.button2.Text = "Update";
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// folderBrowserDialog1
|
||||
//
|
||||
this.folderBrowserDialog1.Description = "Select project folder";
|
||||
this.folderBrowserDialog1.ShowNewFolderButton = false;
|
||||
//
|
||||
// backgroundWorker1
|
||||
//
|
||||
this.backgroundWorker1.WorkerSupportsCancellation = true;
|
||||
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
|
||||
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.button2);
|
||||
this.panel1.Controls.Add(this.checkedListBox1);
|
||||
this.panel1.Controls.Add(this.button1);
|
||||
this.panel1.Controls.Add(this.label1);
|
||||
this.panel1.Controls.Add(this.textBox2);
|
||||
this.panel1.Controls.Add(this.textBox1);
|
||||
this.panel1.Controls.Add(this.label2);
|
||||
this.panel1.Location = new System.Drawing.Point(16, 24);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(240, 216);
|
||||
this.panel1.TabIndex = 7;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.button3);
|
||||
this.panel2.Controls.Add(this.groupBox1);
|
||||
this.panel2.Location = new System.Drawing.Point(272, 24);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(256, 216);
|
||||
this.panel2.TabIndex = 8;
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.progressBar1.Location = new System.Drawing.Point(16, 32);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(200, 23);
|
||||
this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
|
||||
this.progressBar1.TabIndex = 0;
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.groupBox1.Controls.Add(this.progressBar1);
|
||||
this.groupBox1.Location = new System.Drawing.Point(16, 72);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(224, 72);
|
||||
this.groupBox1.TabIndex = 1;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Loading, please wait";
|
||||
//
|
||||
// button3
|
||||
//
|
||||
this.button3.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
|
||||
this.button3.Location = new System.Drawing.Point(91, 176);
|
||||
this.button3.Name = "button3";
|
||||
this.button3.Size = new System.Drawing.Size(75, 23);
|
||||
this.button3.TabIndex = 7;
|
||||
this.button3.Text = "Stop";
|
||||
this.button3.UseVisualStyleBackColor = true;
|
||||
this.button3.Click += new System.EventHandler(this.button3_Click);
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(564, 272);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Name = "Form1";
|
||||
this.Text = "Form1";
|
||||
this.Load += new System.EventHandler(this.Form1_Load);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
private System.Windows.Forms.CheckedListBox checkedListBox1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox textBox2;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
|
||||
private System.ComponentModel.BackgroundWorker backgroundWorker1;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.ProgressBar progressBar1;
|
||||
private System.Windows.Forms.Button button3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UpdateVersionNumber
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
private readonly System.Text.RegularExpressions.Regex RXP = new System.Text.RegularExpressions.Regex(@"\[assembly\: AssemblyVersion\(\""(?<version>\d+\.\d+\.\d+\.\d+)\""\)\]");
|
||||
private readonly System.Text.RegularExpressions.Regex RXP2 = new System.Text.RegularExpressions.Regex(@"\[assembly\: AssemblyFileVersion\(\""(?<version>\d+\.\d+\.\d+\.\d+)\""\)\]");
|
||||
private readonly System.Text.RegularExpressions.Regex RXP3 = new System.Text.RegularExpressions.Regex(@"\[assembly\: AssemblyFileVersionAttribute\(\""(?<version>\d+\.\d+\.\d+\.\d+)\""\)\]");
|
||||
|
||||
private readonly System.Text.RegularExpressions.Regex RXP4 = new System.Text.RegularExpressions.Regex(@"\<\?define ProductVersion\=\""(?<version>\d+\.\d+\.\d+\.\d+)\"" \?\>");
|
||||
|
||||
private readonly System.Text.RegularExpressions.Regex RXP5 = new System.Text.RegularExpressions.Regex(@"newVersion\=\""(?<version>\d+\.\d+\.\d+\.\d+)\""");
|
||||
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel2.Dock = DockStyle.Fill;
|
||||
}
|
||||
|
||||
private void textBox2_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
panel1.Visible = false;
|
||||
panel2.Visible = true;
|
||||
|
||||
backgroundWorker1.RunWorkerAsync(textBox2.Text);
|
||||
}
|
||||
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
textBox2.Text = Application.StartupPath;
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (folderBrowserDialog1.ShowDialog(this) == DialogResult.OK)
|
||||
if (textBox2.Text == folderBrowserDialog1.SelectedPath)
|
||||
textBox2_TextChanged(sender, e);
|
||||
else
|
||||
textBox2.Text = folderBrowserDialog1.SelectedPath;
|
||||
}
|
||||
|
||||
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
List<DisplayItem> results = new List<DisplayItem>();
|
||||
e.Result = results;
|
||||
Queue<string> folders = new Queue<string>();
|
||||
string startfolder = e.Argument as string;
|
||||
if (string.IsNullOrEmpty(startfolder))
|
||||
return;
|
||||
|
||||
folders.Enqueue(startfolder);
|
||||
|
||||
while (folders.Count > 0)
|
||||
{
|
||||
string folder = folders.Dequeue();
|
||||
|
||||
foreach (string f in System.IO.Directory.GetDirectories(folder))
|
||||
folders.Enqueue(f);
|
||||
|
||||
if (backgroundWorker1.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
|
||||
string file = System.IO.Path.Combine(folder, "AssemblyInfo.cs");
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
string content = System.IO.File.ReadAllText(file);
|
||||
System.Text.RegularExpressions.Match m = RXP.Match(content);
|
||||
if (!m.Success)
|
||||
m = RXP2.Match(content);
|
||||
if (!m.Success)
|
||||
m = RXP3.Match(content);
|
||||
|
||||
if (m.Success)
|
||||
{
|
||||
string v = m.Groups["version"].Value;
|
||||
results.Add(new DisplayItem(file, new Version(v)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
file = System.IO.Path.Combine(folder, "UpgradeData.wxi");
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
string content = System.IO.File.ReadAllText(file);
|
||||
System.Text.RegularExpressions.Match m = RXP4.Match(content);
|
||||
|
||||
if (m.Success)
|
||||
{
|
||||
string v = m.Groups["version"].Value;
|
||||
results.Add(new DisplayItem(file, new Version(v)));
|
||||
}
|
||||
}
|
||||
|
||||
file = System.IO.Path.Combine(folder, "AssemblyRedirects.xml");
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
string content = System.IO.File.ReadAllText(file);
|
||||
System.Text.RegularExpressions.Match m = RXP5.Match(content);
|
||||
|
||||
if (m.Success)
|
||||
{
|
||||
string v = m.Groups["version"].Value;
|
||||
results.Add(new DisplayItem(file, new Version(v)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
panel1.Visible =true;
|
||||
panel2.Visible = false;
|
||||
|
||||
if (e.Error != null)
|
||||
MessageBox.Show(this, "An error occured: " + e.Error.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
if (e.Cancelled || e.Error != null)
|
||||
{
|
||||
checkedListBox1.Items.Clear();
|
||||
button2.Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, bool> overrideDefault = new Dictionary<string, bool>(System.Environment.OSVersion.Platform == PlatformID.MacOSX || System.Environment.OSVersion.Platform == PlatformID.Unix ? StringComparer.InvariantCulture : StringComparer.InvariantCultureIgnoreCase );
|
||||
string configfile = null;
|
||||
bool updateDefault = true;
|
||||
try
|
||||
{
|
||||
configfile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "UpdateVersionNumber.config");
|
||||
if (System.IO.File.Exists(configfile))
|
||||
{
|
||||
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
|
||||
doc.Load(configfile);
|
||||
|
||||
System.Xml.XmlNode root = doc["root"];
|
||||
if (root.Attributes["update_as_default"] != null)
|
||||
updateDefault = bool.Parse(root.Attributes["update_as_default"].Value);
|
||||
|
||||
foreach (System.Xml.XmlNode file in root.SelectNodes("file"))
|
||||
{
|
||||
string filename = file.InnerText;
|
||||
if (!System.IO.Path.IsPathRooted(filename))
|
||||
filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), filename);
|
||||
|
||||
overrideDefault[filename] = bool.Parse(file.Attributes["update"].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, string.Format("An error occured while reading config file \"{0}\": {1}", configfile, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
button2.Enabled = true;
|
||||
List<DisplayItem> files = (List<DisplayItem>)e.Result;
|
||||
checkedListBox1.Items.Clear();
|
||||
Version vmax = new Version();
|
||||
foreach (DisplayItem d in files)
|
||||
{
|
||||
checkedListBox1.Items.Add(d, overrideDefault.ContainsKey(d.File) ? overrideDefault[d.File] : updateDefault);
|
||||
vmax = d.Version > vmax ? d.Version : vmax;
|
||||
}
|
||||
|
||||
textBox1.Text = vmax.ToString();
|
||||
|
||||
}
|
||||
|
||||
private void button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!backgroundWorker1.CancellationPending && backgroundWorker1.IsBusy)
|
||||
backgroundWorker1.CancelAsync();
|
||||
}
|
||||
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (checkedListBox1.CheckedItems.Count == 0)
|
||||
{
|
||||
MessageBox.Show(this, "No files selected", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
Version v;
|
||||
|
||||
try
|
||||
{
|
||||
v = new Version(textBox1.Text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, "Invalid version number: " + ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
string replacement = "[assembly: AssemblyVersion(\"" + v.ToString() + "\")]";
|
||||
string replacement2 = "[assembly: AssemblyFileVersion(\"" + v.ToString() + "\")]";
|
||||
string replacement3 = "[assembly: AssemblyFileVersionAttribute(\"" + v.ToString() + "\")]";
|
||||
string replacement4 = "<?define ProductVersion=\"" + v.ToString() + "\" ?>";
|
||||
string replacement5 = "newVersion=\"" + v.ToString() + "\"";
|
||||
bool errors = false;
|
||||
|
||||
foreach (DisplayItem d in checkedListBox1.CheckedItems)
|
||||
{
|
||||
try
|
||||
{
|
||||
string content = System.IO.File.ReadAllText(d.File);
|
||||
if (d.File.ToLower().EndsWith(".wxi"))
|
||||
content = RXP4.Replace(content, replacement4);
|
||||
else if (System.IO.Path.GetFileName(d.File).Equals("AssemblyRedirects.xml", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
content = RXP5.Replace(content, replacement5);
|
||||
}
|
||||
else
|
||||
{
|
||||
content = RXP.Replace(content, replacement);
|
||||
content = RXP2.Replace(content, replacement2);
|
||||
content = RXP3.Replace(content, replacement3);
|
||||
}
|
||||
System.IO.File.WriteAllText(d.File, content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors = true;
|
||||
MessageBox.Show(this, "Failed to update file: " + d.File + "\r\nError: " + ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errors)
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?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>
|
||||
<metadata name="folderBrowserDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="backgroundWorker1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>175, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,39 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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.Windows.Forms;
|
||||
|
||||
namespace UpdateVersionNumber
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Form1());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("UpdateVersionNumber")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("UpdateVersionNumber")]
|
||||
[assembly: AssemblyCopyright("Copyright © HexaD 2009")]
|
||||
[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("9118bb59-ad2d-4660-81ad-cc23f12ce450")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.237
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace UpdateVersionNumber.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("UpdateVersionNumber.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?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.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: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" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>
|
||||
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.237
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace UpdateVersionNumber.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2CD0151C-C091-4F98-B7B7-144DF02EF2E7}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>UpdateVersionNumber</RootNamespace>
|
||||
<AssemblyName>UpdateVersionNumber</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DisplayItem.cs" />
|
||||
<Compile Include="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</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>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\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>
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateVersionNumber", "UpdateVersionNumber.csproj", "{2CD0151C-C091-4F98-B7B7-144DF02EF2E7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2CD0151C-C091-4F98-B7B7-144DF02EF2E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2CD0151C-C091-4F98-B7B7-144DF02EF2E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2CD0151C-C091-4F98-B7B7-144DF02EF2E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2CD0151C-C091-4F98-B7B7-144DF02EF2E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -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("WixIncludeMake")]
|
||||
[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("1.0.*")]
|
||||
|
||||
// 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,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WixIncludeMake
|
||||
{
|
||||
public static class LinqHelpers
|
||||
{
|
||||
public static Dictionary<TKey, TValue> ToSafeDictionary<TSource, TKey, TValue>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector, string locationName)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
if (keySelector == null)
|
||||
throw new ArgumentNullException("keySelector");
|
||||
if (valueSelector == null)
|
||||
throw new ArgumentNullException("valueSelector");
|
||||
|
||||
Dictionary<TKey, TValue> res = new Dictionary<TKey, TValue>();
|
||||
foreach (TSource el in source)
|
||||
{
|
||||
TKey k = keySelector(el);
|
||||
TValue v = valueSelector(el);
|
||||
|
||||
if (res.ContainsKey(k))
|
||||
Console.WriteLine("*** Warning, duplicate key: " + k.ToString() + " in " + locationName);
|
||||
else
|
||||
res.Add(k, v);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace WixIncludeMake
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private const string DB_FILE = "generated-keys.xml";
|
||||
private const string USER_FILE = "fixed-keys.xml";
|
||||
private static readonly string DIR_SEP = System.IO.Path.DirectorySeparatorChar.ToString();
|
||||
private static readonly string basedir = System.IO.Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
public static readonly XNamespace XWIX = "http://schemas.microsoft.com/wix/2006/wi";
|
||||
|
||||
private interface IFolder
|
||||
{
|
||||
Dictionary<string, FolderInfo> Folders { get; }
|
||||
Dictionary<string, FileInfo> Files { get; }
|
||||
}
|
||||
|
||||
private class FolderInfo : IFolder
|
||||
{
|
||||
public Dictionary<string, FolderInfo> Folders { get; private set; }
|
||||
public Dictionary<string, FileInfo> Files { get; private set; }
|
||||
public string Name { get; set; }
|
||||
private string m_id;
|
||||
public string ID { get { return m_id.Replace(" ", "").Replace("-", "").ToUpperInvariant(); } set { m_id = value; } }
|
||||
public Guid GUID { get; set; }
|
||||
|
||||
private FolderInfo()
|
||||
{
|
||||
Folders = new Dictionary<string, FolderInfo>();
|
||||
Files = new Dictionary<string, FileInfo>();
|
||||
}
|
||||
|
||||
public FolderInfo(string name, string id, Guid guid)
|
||||
: this()
|
||||
{
|
||||
this.Name = name;
|
||||
this.ID = id;
|
||||
this.GUID = guid;
|
||||
}
|
||||
|
||||
public IEnumerable<XElement> FileNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
from x in Files
|
||||
orderby x.Key
|
||||
select
|
||||
new XElement(XWIX + "File",
|
||||
new XAttribute("Id", "file_" + x.Value.ID),
|
||||
new XAttribute("Checksum", "yes"),
|
||||
new XAttribute("Source", x.Value.SourceFile)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public XElement FolderNode
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
new XElement(XWIX + "Directory",
|
||||
new XAttribute("Id", "dir_" + this.ID),
|
||||
new XAttribute("Name", this.Name),
|
||||
new XElement(XWIX + "Component",
|
||||
new XAttribute("Id", "comp_" + this.ID),
|
||||
new XAttribute("DiskId", 1),
|
||||
new XAttribute("KeyPath", "yes"),
|
||||
new XAttribute("Guid", this.GUID.ToString()),
|
||||
new XAttribute("Win64", "$(var.Win64)"),
|
||||
FileNodes
|
||||
),
|
||||
from x in Folders
|
||||
orderby x.Key
|
||||
select x.Value.FolderNode
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<FolderInfo> Subfolders
|
||||
{
|
||||
get
|
||||
{
|
||||
List<FolderInfo> res = new List<FolderInfo>();
|
||||
res.Add (this);
|
||||
foreach(var f in this.Folders.Values)
|
||||
res.AddRange(f.Subfolders);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FileInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
private string m_id;
|
||||
public string ID { get { return m_id.Replace(" ", "").Replace("-", "").ToUpperInvariant(); } set { m_id = value; } }
|
||||
public string SourceFile { get; set; }
|
||||
|
||||
public FileInfo(string name, string id, string sourcefile)
|
||||
{
|
||||
this.Name = name;
|
||||
this.ID = id;
|
||||
this.SourceFile = sourcefile;
|
||||
}
|
||||
}
|
||||
|
||||
private class RootFolderInfo : FolderInfo
|
||||
{
|
||||
public Dictionary<string, string> GeneratedKeys { get; private set; }
|
||||
public Dictionary<string, string> UserKeys { get; private set; }
|
||||
public string ComponentID { get; set; }
|
||||
private readonly Options m_opt;
|
||||
|
||||
public RootFolderInfo(Options opt, IEnumerable<string> paths = null)
|
||||
: base("", "", Guid.NewGuid())
|
||||
{
|
||||
GeneratedKeys = ReadKeyDatabase(opt.dbfilename);
|
||||
UserKeys = ReadKeyDatabase(opt.userfilename);
|
||||
ComponentID = opt.componentid;
|
||||
m_opt = opt;
|
||||
|
||||
string id;
|
||||
if (!GeneratedKeys.TryGetValue(DIR_SEP, out id))
|
||||
id = Guid.NewGuid().ToString();
|
||||
|
||||
if (UserKeys.ContainsKey(DIR_SEP))
|
||||
id = UserKeys[DIR_SEP];
|
||||
|
||||
this.ID = id;
|
||||
|
||||
Add (paths);
|
||||
}
|
||||
|
||||
public void Add(IEnumerable<string> paths)
|
||||
{
|
||||
if (paths == null)
|
||||
return;
|
||||
|
||||
foreach(var p in paths)
|
||||
Add (p);
|
||||
}
|
||||
|
||||
public void Add(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return;
|
||||
|
||||
bool isDir = false;
|
||||
if (path.EndsWith(DIR_SEP))
|
||||
{
|
||||
isDir = true;
|
||||
path = path.Substring(0, path.Length - 1);
|
||||
}
|
||||
|
||||
List<string> folders = new List<string>();
|
||||
string filename = null;
|
||||
|
||||
while(!string.IsNullOrEmpty(path))
|
||||
{
|
||||
string sourcepath = System.IO.Path.GetDirectoryName(path);
|
||||
string elname = System.IO.Path.GetFileName(path);
|
||||
folders.Add(elname);
|
||||
|
||||
path = sourcepath;
|
||||
if (path.EndsWith(DIR_SEP))
|
||||
path = path.Substring(0, path.Length - 1);
|
||||
|
||||
}
|
||||
|
||||
if (!isDir)
|
||||
{
|
||||
filename = folders[0];
|
||||
folders.RemoveAt (0);
|
||||
}
|
||||
|
||||
IFolder cur = this;
|
||||
folders.Reverse();
|
||||
|
||||
StringBuilder sbp = new StringBuilder();
|
||||
|
||||
foreach(var f in folders)
|
||||
{
|
||||
sbp.Append(f);
|
||||
sbp.Append(DIR_SEP);
|
||||
|
||||
FolderInfo next;
|
||||
if (!cur.Folders.TryGetValue(f, out next))
|
||||
{
|
||||
//We have a new folder
|
||||
string id;
|
||||
if (!GeneratedKeys.TryGetValue(sbp.ToString(), out id))
|
||||
{
|
||||
id = Guid.NewGuid().ToString();
|
||||
GeneratedKeys.Add(sbp.ToString(), id);
|
||||
}
|
||||
|
||||
Guid g;
|
||||
try { g = new Guid(id); }
|
||||
catch
|
||||
{
|
||||
g = Guid.NewGuid();
|
||||
GeneratedKeys[sbp.ToString()] = g.ToString();
|
||||
Console.Error.WriteLine ("Unable to parse {0} into a GUID, I told you not to edit the file!!!{1}A new GUID will be used: {2}", id, Environment.NewLine, g);
|
||||
}
|
||||
|
||||
string userkey;
|
||||
if (!UserKeys.TryGetValue(sbp.ToString(), out userkey))
|
||||
userkey = g.ToString();
|
||||
|
||||
next = new FolderInfo(f, userkey, g);
|
||||
cur.Folders.Add(f, next);
|
||||
}
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(filename))
|
||||
{
|
||||
sbp.Append(filename);
|
||||
|
||||
string id;
|
||||
if (!GeneratedKeys.TryGetValue(sbp.ToString(), out id))
|
||||
GeneratedKeys.Add(sbp.ToString(), id = Guid.NewGuid().ToString());
|
||||
if (UserKeys.ContainsKey(sbp.ToString()))
|
||||
id = UserKeys[sbp.ToString()];
|
||||
|
||||
string fullpath = System.IO.Path.Combine(m_opt.fileprefix, sbp.ToString()).Replace(DIR_SEP, "\\");
|
||||
|
||||
cur.Files.Add(filename, new FileInfo(filename, id, fullpath));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<XElement> Node
|
||||
{
|
||||
get
|
||||
{
|
||||
List<XElement> res = new List<XElement>();
|
||||
res.Add(new XElement(XWIX + "Component",
|
||||
new XAttribute("Id", "comp_" + this.ID),
|
||||
new XAttribute("DiskId", 1),
|
||||
new XAttribute("KeyPath", "yes"),
|
||||
new XAttribute("Guid", this.GUID.ToString()),
|
||||
new XAttribute("Win64", "$(var.Win64)"),
|
||||
FileNodes
|
||||
));
|
||||
|
||||
res.AddRange(
|
||||
from x in Folders
|
||||
orderby x.Key
|
||||
select x.Value.FolderNode
|
||||
);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public XElement GroupNode
|
||||
{
|
||||
get
|
||||
{
|
||||
return new XElement(XWIX + "ComponentGroup",
|
||||
new XAttribute("Id", this.ComponentID),
|
||||
from x in this.Subfolders
|
||||
where x != this
|
||||
select new XElement(XWIX + "ComponentRef",
|
||||
new XAttribute("Id", "comp_" + x.ID)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GuidToString(Guid g)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(var b in g.ToByteArray())
|
||||
sb.Append(string.Format("{0:x2}", b));
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private class Options
|
||||
{
|
||||
public string dbfilename = System.IO.Path.Combine(basedir, DB_FILE);
|
||||
public string userfilename = System.IO.Path.Combine(basedir, USER_FILE);
|
||||
public string sourcefolder = System.IO.Path.GetFullPath(Environment.CurrentDirectory);
|
||||
public string outputfile = System.IO.Path.GetFullPath("binfiles.wxs");
|
||||
public string ignorefilter = null;
|
||||
public string dirref = "INSTALLLOCATION";
|
||||
public string componentid = "FILES_COMPONENT";
|
||||
public string fileprefix = "";
|
||||
|
||||
public void Fixup()
|
||||
{
|
||||
sourcefolder = System.IO.Path.GetFullPath(sourcefolder);
|
||||
outputfile = System.IO.Path.GetFullPath(outputfile);
|
||||
sourcefolder = Duplicati.Library.Utility.Utility.AppendDirSeparator(sourcefolder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Main (string[] _args)
|
||||
{
|
||||
List<string> args = new List<string>(_args);
|
||||
Dictionary<string, string> options = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
|
||||
Options opt = new Options();
|
||||
|
||||
|
||||
foreach(FieldInfo fi in opt.GetType().GetFields())
|
||||
if (options.ContainsKey(fi.Name))
|
||||
fi.SetValue(opt, options[fi.Name]);
|
||||
|
||||
opt.Fixup();
|
||||
|
||||
Duplicati.Library.Utility.FilenameFilter filter = null;
|
||||
if (!string.IsNullOrEmpty(opt.ignorefilter))
|
||||
filter = new Duplicati.Library.Utility.FilenameFilter(
|
||||
new List<Duplicati.Library.Utility.IFilenameFilter>(
|
||||
new Duplicati.Library.Utility.IFilenameFilter[] {
|
||||
new Duplicati.Library.Utility.RegularExpressionFilter(false, opt.ignorefilter)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
var paths = Duplicati.Library.Utility.Utility.EnumerateFileSystemEntries(opt.sourcefolder, filter).ConvertAll(x => x.Substring(opt.sourcefolder.Length));
|
||||
|
||||
//A bit backwards, but we have flattend the file list, and now we re-construct the tree,
|
||||
// but we do not care much about performance here
|
||||
RootFolderInfo rootfolder = new RootFolderInfo(opt, paths);
|
||||
|
||||
new XDocument(
|
||||
new XElement(XWIX + "Wix",
|
||||
new XElement(XWIX + "Fragment",
|
||||
rootfolder.GroupNode,
|
||||
new XElement(XWIX + "DirectoryRef",
|
||||
new XAttribute("Id", opt.dirref),
|
||||
rootfolder.Node
|
||||
)
|
||||
)
|
||||
)
|
||||
).Save(opt.outputfile);
|
||||
|
||||
WriteKeyDatabase(rootfolder.GeneratedKeys, opt.dbfilename, true);
|
||||
|
||||
Console.WriteLine("Generated wxs: {0}", opt.outputfile);
|
||||
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> ReadKeyDatabase(string filename)
|
||||
{
|
||||
if (!System.IO.File.Exists(filename))
|
||||
return new Dictionary<string, string>();
|
||||
|
||||
return XDocument.Load(filename).Element("root").Elements("entry").ToSafeDictionary(
|
||||
c => c.Attribute("name").Value.Replace("\\", DIR_SEP), c => c.Attribute("key").Value, filename);
|
||||
}
|
||||
|
||||
private static void WriteKeyDatabase(Dictionary<string, string> keys, string filename, bool isKeyDb)
|
||||
{
|
||||
new XDocument(
|
||||
new XComment(isKeyDb ? "This file is autogenerated, do not edit! EVER!" : "format is <entry name=\"name\" key=\"key\" />"),
|
||||
new XElement("root",
|
||||
from x in keys
|
||||
select new XElement("entry",
|
||||
new XAttribute("name", x.Key.Replace(DIR_SEP, "\\")),
|
||||
new XAttribute("key", x.Value)
|
||||
)
|
||||
)
|
||||
).Save(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?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)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{34426731-7BAD-4B28-BD80-FD117EC082E5}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>WixIncludeMake</RootNamespace>
|
||||
<AssemblyName>WixIncludeMake</AssemblyName>
|
||||
<StartupObject>WixIncludeMake.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Installer</OutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<Commandlineparameters>--sourcefolder=../Duplicati/GUI/bin/Release --fileprefix=bin/Release/ --ignorefilter=(.*/\.svn/)|(.*\.config)</Commandlineparameters>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Installer</OutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="LinqHelpers.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj">
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Library.Utility</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixIncludeMake", "WixIncludeMake.csproj", "{34426731-7BAD-4B28-BD80-FD117EC082E5}"
|
||||
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
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{34426731-7BAD-4B28-BD80-FD117EC082E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{34426731-7BAD-4B28-BD80-FD117EC082E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{34426731-7BAD-4B28-BD80-FD117EC082E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{34426731-7BAD-4B28-BD80-FD117EC082E5}.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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = WixIncludeMake.csproj
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,256 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace WixProjBuilder
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] _args)
|
||||
{
|
||||
List<string> args = new List<string>(_args);
|
||||
Dictionary<string, string> options = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
|
||||
|
||||
if (args.Count != 1)
|
||||
{
|
||||
Console.WriteLine("Usage: ");
|
||||
Console.WriteLine(" WixProjBuilder.exe <projfile> [option=value]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists(args[0]))
|
||||
{
|
||||
Console.WriteLine(string.Format("File not found: {0}", args[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
string wixpath;
|
||||
if (options.ContainsKey("wixpath"))
|
||||
wixpath = options["wixpath"];
|
||||
else
|
||||
wixpath = System.Environment.GetEnvironmentVariable("WIXPATH");
|
||||
|
||||
if (string.IsNullOrEmpty(wixpath))
|
||||
{
|
||||
string[] known_wix_names = new string[]
|
||||
{
|
||||
"Windows Installer XML v3",
|
||||
"Windows Installer XML v3.1",
|
||||
"Windows Installer XML v3.2",
|
||||
"Windows Installer XML v3.3",
|
||||
"Windows Installer XML v3.4",
|
||||
"Windows Installer XML v3.5",
|
||||
"Windows Installer XML v3.6",
|
||||
"Windows Installer XML v3.7"
|
||||
};
|
||||
|
||||
foreach(var p in known_wix_names)
|
||||
{
|
||||
foreach(var p2 in new string[] {"%ProgramFiles(x86)%", "%programfiles%"})
|
||||
{
|
||||
wixpath = System.IO.Path.Combine(System.IO.Path.Combine(Environment.ExpandEnvironmentVariables(p2), p), "bin");
|
||||
if (System.IO.Directory.Exists(wixpath))
|
||||
{
|
||||
Console.WriteLine(string.Format("*** wixpath not specified, using: {0}", wixpath));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (System.IO.Directory.Exists(wixpath))
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!System.IO.Directory.Exists(wixpath))
|
||||
{
|
||||
Console.WriteLine(string.Format("WiX not found, please install Windows Installer XML 3 or greater"));
|
||||
Console.WriteLine(string.Format(" supply path to WiX bin folder with option --wixpath=...path..."));
|
||||
return;
|
||||
}
|
||||
|
||||
args[0] = System.IO.Path.GetFullPath(args[0]);
|
||||
|
||||
Console.WriteLine(string.Format("Parsing wixproj file: {0}", args[0]));
|
||||
|
||||
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
|
||||
doc.Load(args[0]);
|
||||
|
||||
string config = "Release";
|
||||
if (options.ContainsKey("configuration"))
|
||||
config = options["configuration"];
|
||||
|
||||
string projdir = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(args[0]));
|
||||
|
||||
List<string> includes = new List<string>();
|
||||
List<string> refs = new List<string>();
|
||||
List<string> content = new List<string>();
|
||||
|
||||
System.Xml.XmlNamespaceManager nm = new System.Xml.XmlNamespaceManager(doc.NameTable);
|
||||
nm.AddNamespace("ms", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
|
||||
foreach (System.Xml.XmlNode n in doc.SelectNodes("ms:Project/ms:ItemGroup/ms:Compile", nm))
|
||||
includes.Add(n.Attributes["Include"].Value);
|
||||
|
||||
foreach (System.Xml.XmlNode n in doc.SelectNodes("ms:Project/ms:ItemGroup/ms:Content", nm))
|
||||
content.Add(n.Attributes["Include"].Value);
|
||||
|
||||
foreach (System.Xml.XmlNode n in doc.SelectNodes("ms:Project/ms:ItemGroup/ms:WixExtension", nm))
|
||||
refs.Add(n.Attributes["Include"].Value);
|
||||
|
||||
|
||||
string objdir = System.IO.Path.Combine(System.IO.Path.Combine(projdir, "obj"), config);
|
||||
string packagename = "output";
|
||||
string outdir = System.IO.Path.Combine("bin", config);
|
||||
string outtype = "Package";
|
||||
|
||||
//TODO: Support multiconfiguration system correctly
|
||||
foreach (System.Xml.XmlNode n in doc.SelectNodes("ms:Project/ms:PropertyGroup/ms:Configuration", nm))
|
||||
if (true) //if (string.Compare(n.InnerText, config, true) == 0)
|
||||
{
|
||||
System.Xml.XmlNode p = n.ParentNode;
|
||||
if (p["OutputName"] != null)
|
||||
packagename = p["OutputName"].InnerText;
|
||||
if (p["OutputType"] != null)
|
||||
outtype = p["OutputType"].InnerText;
|
||||
if (p["OutputPath"] != null)
|
||||
outdir = p["OutputPath"].InnerText.Replace("$(Configuration)", config);
|
||||
if (p["IntermediateOutputPath"] != null)
|
||||
objdir = p["IntermediateOutputPath"].InnerText.Replace("$(Configuration)", config);
|
||||
}
|
||||
|
||||
if (!objdir.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
|
||||
objdir += System.IO.Path.DirectorySeparatorChar;
|
||||
|
||||
string msiname = System.IO.Path.Combine(outdir, packagename + ".msi");
|
||||
|
||||
Console.WriteLine(" Compiling ... ");
|
||||
if (includes.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No files found to compile in project file");
|
||||
return;
|
||||
}
|
||||
|
||||
string compile_args = "\"" + string.Join("\" \"", includes.ToArray()) + "\"";
|
||||
compile_args += " -out \"" + objdir.Replace("\\", "\\\\") + "\"";
|
||||
|
||||
if (options.ContainsKey("platform") && options["platform"] == "x64")
|
||||
compile_args += " -dPlatform=x64 -dWin64=yes";
|
||||
else
|
||||
compile_args += " -dPlatform=x86 -dWin64=no";
|
||||
|
||||
int res = Execute(
|
||||
System.IO.Path.Combine(wixpath, "candle.exe"),
|
||||
projdir,
|
||||
compile_args);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
Console.WriteLine("Compilation failed, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine(" Linking ...");
|
||||
|
||||
for (int i = 0; i < includes.Count; i++)
|
||||
includes[i] = System.IO.Path.Combine(objdir, System.IO.Path.GetFileNameWithoutExtension(includes[i]) + ".wixobj");
|
||||
|
||||
for (int i = 0; i < refs.Count; i++)
|
||||
if (!System.IO.Path.IsPathRooted(refs[i]))
|
||||
{
|
||||
refs[i] = FindDll(refs[i] + ".dll", new string[] { projdir, wixpath });
|
||||
if (!System.IO.Path.IsPathRooted(refs[i]))
|
||||
refs[i] = FindDll(refs[i]);
|
||||
}
|
||||
|
||||
string link_args = "\"" + string.Join("\" \"", includes.ToArray()) + "\"";
|
||||
|
||||
if (refs.Count > 0)
|
||||
link_args += " -ext \"" + string.Join("\" -ext \"", refs.ToArray()) + "\"";
|
||||
|
||||
link_args += " -out \"" + msiname + "\"";
|
||||
|
||||
res = Execute(
|
||||
System.IO.Path.Combine(wixpath, "light.exe"),
|
||||
projdir,
|
||||
link_args);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
Console.WriteLine("Link failed, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!System.IO.Path.IsPathRooted(msiname))
|
||||
msiname = System.IO.Path.GetFullPath(System.IO.Path.Combine(projdir, msiname));
|
||||
|
||||
Console.WriteLine(string.Format("Done: {0}", msiname));
|
||||
}
|
||||
|
||||
private static int Execute(string app, string workdir, string args)
|
||||
{
|
||||
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(app, args);
|
||||
psi.CreateNoWindow = true;
|
||||
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
|
||||
psi.WorkingDirectory = workdir;
|
||||
psi.RedirectStandardOutput = true;
|
||||
psi.RedirectStandardError = true;
|
||||
psi.UseShellExecute = false;
|
||||
|
||||
System.Diagnostics.Process p = System.Diagnostics.Process.Start(psi);
|
||||
p.WaitForExit(5 * 60 * 1000); //Wait up to five minutes
|
||||
if (!p.HasExited)
|
||||
{
|
||||
try { p.Kill(); }
|
||||
catch { }
|
||||
|
||||
Console.WriteLine("Stdout: " + p.StandardOutput.ReadToEnd());
|
||||
Console.WriteLine("Stderr: " + p.StandardError.ReadToEnd());
|
||||
|
||||
throw new Exception(string.Format("Application {0} hung", app));
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(p.StandardOutput.ReadToEnd());
|
||||
Console.WriteLine(p.StandardError.ReadToEnd());
|
||||
Console.WriteLine();
|
||||
|
||||
|
||||
return p.ExitCode;
|
||||
}
|
||||
|
||||
private static string FindDll(string filename)
|
||||
{
|
||||
return FindDll(filename, System.Environment.GetEnvironmentVariable("path").Split(System.IO.Path.PathSeparator));
|
||||
}
|
||||
|
||||
private static string FindDll(string filename, IEnumerable<string> paths)
|
||||
{
|
||||
foreach (string p in paths)
|
||||
if (System.IO.File.Exists(System.IO.Path.Combine(p, filename)))
|
||||
return System.IO.Path.Combine(p, filename);
|
||||
|
||||
return filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("WixProjBuilder")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("WixProjBuilder")]
|
||||
[assembly: AssemblyCopyright("Copyright © HexaD 2009")]
|
||||
[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("aec90a98-c777-46f0-ba4f-1f81dc9fda11")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{794CD060-AB3B-4885-B23B-6B26272C84E0}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>WixProjBuilder</RootNamespace>
|
||||
<AssemblyName>WixProjBuilder</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</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>
|
||||
<Import Project="$(MSBuildToolsPath)\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>
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixProjBuilder", "WixProjBuilder.csproj", "{794CD060-AB3B-4885-B23B-6B26272C84E0}"
|
||||
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
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{794CD060-AB3B-4885-B23B-6B26272C84E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{794CD060-AB3B-4885-B23B-6B26272C84E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{794CD060-AB3B-4885-B23B-6B26272C84E0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{794CD060-AB3B-4885-B23B-6B26272C84E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{794CD060-AB3B-4885-B23B-6B26272C84E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{794CD060-AB3B-4885-B23B-6B26272C84E0}.Release|x86.ActiveCfg = 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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
@@ -0,0 +1,491 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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
|
||||
|
||||
|
||||
Copyright 2008, http://www.hexad.dk, opensource@hexad.dk
|
||||
@@ -0,0 +1,234 @@
|
||||
|
||||
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.SharpRSync", "Duplicati\Library\SharpRSync\Duplicati.Library.SharpRSync.csproj", "{47FE73E1-0832-44F7-96B9-2580273206C3}"
|
||||
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.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.Winforms.Controls", "Duplicati\Winforms\Controls\Duplicati.Winforms.Controls.csproj", "{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}"
|
||||
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.Scheduler", "Duplicati\Scheduler\Duplicati.Scheduler.csproj", "{D1D503E8-5CF7-413B-81FB-403D65B43AAB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Scheduler.Data", "Duplicati\Scheduler\Data\Duplicati.Scheduler.Data.csproj", "{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Scheduler.Monitor.SQL", "Duplicati\Scheduler\Monitor.SQL\Duplicati.Scheduler.Monitor.SQL.csproj", "{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Scheduler.RunBackup", "Duplicati\Scheduler\RunBackup\Duplicati.Scheduler.RunBackup.csproj", "{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Scheduler.Utility", "Duplicati\Scheduler\Utility\Duplicati.Scheduler.Utility.csproj", "{0E3DF716-5657-4B51-9BF2-3791880930E1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectListView2010", "thirdparty\ObjectListView\ObjectListView\ObjectListView2010.csproj", "{18FEDA0C-D147-4286-B39A-01204808106A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SubversionScc) = preSolution
|
||||
Svn-Managed = True
|
||||
Manager = AnkhSVN - Subversion Support for Visual Studio
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.ActiveCfg = Release|x86
|
||||
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|x86.ActiveCfg = Release|x86
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.ActiveCfg = Release|x86
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.ActiveCfg = Release|x86
|
||||
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.ActiveCfg = Release|x86
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.Build.0 = Release|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.Build.0 = Debug|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.ActiveCfg = Release|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.ActiveCfg = Release|x86
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.ActiveCfg = Release|x86
|
||||
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.ActiveCfg = Release|x86
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.ActiveCfg = Release|x86
|
||||
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.ActiveCfg = Release|x86
|
||||
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.Build.0 = Release|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.Build.0 = Debug|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.ActiveCfg = Release|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.ActiveCfg = Release|x86
|
||||
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.Build.0 = Release|x86
|
||||
{D1D503E8-5CF7-413B-81FB-403D65B43AAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1D503E8-5CF7-413B-81FB-403D65B43AAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1D503E8-5CF7-413B-81FB-403D65B43AAB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D1D503E8-5CF7-413B-81FB-403D65B43AAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1D503E8-5CF7-413B-81FB-403D65B43AAB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1D503E8-5CF7-413B-81FB-403D65B43AAB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C8F0DD19-E242-4E9C-A707-2FFADE8D7970}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ECA674A3-CC59-4C75-90E3-5AACA591EC5D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{520FA2BD-1C59-40D9-BCB5-EDA11327B7F0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0E3DF716-5657-4B51-9BF2-3791880930E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E3DF716-5657-4B51-9BF2-3791880930E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E3DF716-5657-4B51-9BF2-3791880930E1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0E3DF716-5657-4B51-9BF2-3791880930E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E3DF716-5657-4B51-9BF2-3791880930E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0E3DF716-5657-4B51-9BF2-3791880930E1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{18FEDA0C-D147-4286-B39A-01204808106A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{18FEDA0C-D147-4286-B39A-01204808106A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{18FEDA0C-D147-4286-B39A-01204808106A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{18FEDA0C-D147-4286-B39A-01204808106A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{18FEDA0C-D147-4286-B39A-01204808106A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{18FEDA0C-D147-4286-B39A-01204808106A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = Duplicati\GUI\Duplicati.GUI.TrayIcon\Duplicati.GUI.TrayIcon.csproj
|
||||
Policies = $0
|
||||
$0.StandardHeader = $1
|
||||
$1.Text = @ Copyright (C) 2011, Kenneth Skovhede\r\n http://www.hexad.dk, opensource@hexad.dk\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 = None
|
||||
$2.ResourceNamePolicy = FileFormatDefault
|
||||
$0.TextStylePolicy = $3
|
||||
$3.FileWidth = 120
|
||||
$3.EolMarker = Windows
|
||||
$3.inheritsSet = VisualStudio
|
||||
$3.inheritsScope = text/plain
|
||||
$3.scope = text/x-csharp
|
||||
$0.CSharpFormattingPolicy = $4
|
||||
$4.BeforeMethodCallParentheses = False
|
||||
$4.BeforeConstructorDeclarationParentheses = False
|
||||
$4.BeforeIndexerDeclarationBracket = False
|
||||
$4.BeforeDelegateDeclarationParentheses = False
|
||||
$4.NewParentheses = False
|
||||
$4.SpacesBeforeBrackets = False
|
||||
$4.inheritsSet = Mono
|
||||
$4.inheritsScope = text/x-csharp
|
||||
$4.scope = text/x-csharp
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+360
@@ -0,0 +1,360 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati", "Duplicati\GUI\Duplicati.csproj", "{1470F75F-D364-4010-91D0-FD4DDA1C5159}"
|
||||
EndProject
|
||||
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.SharpRSync", "Duplicati\Library\SharpRSync\Duplicati.Library.SharpRSync.csproj", "{47FE73E1-0832-44F7-96B9-2580273206C3}"
|
||||
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.CommandLine.Decrypter", "Duplicati\CommandLine\Decrypter\Duplicati.CommandLine.Decrypter.csproj", "{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}"
|
||||
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}") = "Datamodel", "Duplicati\GUI\Datamodel\Datamodel.csproj", "{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WizardForm", "WizardForm\WizardForm.csproj", "{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}"
|
||||
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.Winforms.Controls", "Duplicati\Winforms\Controls\Duplicati.Winforms.Controls.csproj", "{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}"
|
||||
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.SkyDrive", "Duplicati\Library\Backend\SkyDrive\Duplicati.Library.Backend.SkyDrive.csproj", "{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.GoogleDocs", "Duplicati\Library\Backend\GoogleDocs\Duplicati.Library.Backend.GoogleDocs.csproj", "{42C91180-11EB-4590-82EA-80FE9D4DEBEC}"
|
||||
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.GUI.MacTrayIcon", "Duplicati\GUI\Duplicati.GUI.MacTrayIcon\Duplicati.GUI.MacTrayIcon.csproj", "{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
Debug|X86 = Debug|X86
|
||||
Release|X86 = Release|X86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.ActiveCfg = Release|x86
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.ActiveCfg = Release|x86
|
||||
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|x86.Build.0 = Release|x86
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|x86.Build.0 = Debug|x86
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|x86.ActiveCfg = Release|x86
|
||||
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{17566860-3D98-4604-AA5B-47661F75609F}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{17566860-3D98-4604-AA5B-47661F75609F}.Release|x86.ActiveCfg = Release|x86
|
||||
{17566860-3D98-4604-AA5B-47661F75609F}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|x86.ActiveCfg = Release|x86
|
||||
{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.ActiveCfg = Release|x86
|
||||
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|x86.ActiveCfg = Release|x86
|
||||
{1BFAE226-8364-4086-825C-BB83F6F3EE4C}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|x86.ActiveCfg = Release|x86
|
||||
{33FD1D24-C28F-4C71-933F-98F1586EA76C}.Release|x86.Build.0 = Release|x86
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{42C91180-11EB-4590-82EA-80FE9D4DEBEC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|x86.Build.0 = Debug|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.ActiveCfg = Release|x86
|
||||
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.ActiveCfg = Release|x86
|
||||
{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.ActiveCfg = Release|x86
|
||||
{52826615-7964-47FE-B4B3-1B2DBDF605B9}.Release|x86.Build.0 = Release|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Debug|x86.Build.0 = Debug|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.ActiveCfg = Release|x86
|
||||
{7886BA79-A38A-4288-8B8A-9F29D0E15AC0}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|x86.ActiveCfg = Release|x86
|
||||
{81765A64-3661-4E3E-B850-2F6F87A51F74}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.ActiveCfg = Release|x86
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|x86.Build.0 = Release|x86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Debug|X86.ActiveCfg = Debug|X86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Debug|x86.Build.0 = Debug|x86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Debug|X86.Build.0 = Debug|X86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Release|X86.ActiveCfg = Release|X86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Release|x86.ActiveCfg = Release|x86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Release|X86.Build.0 = Release|X86
|
||||
{9E9675C7-1198-44CD-85E0-FD582E9EEAFF}.Release|x86.Build.0 = Release|x86
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|x86.Build.0 = Debug|x86
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|x86.ActiveCfg = Release|x86
|
||||
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{BAE27510-8B5D-44B2-B33E-372A98908041}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|x86.ActiveCfg = Release|x86
|
||||
{BAE27510-8B5D-44B2-B33E-372A98908041}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|x86.ActiveCfg = Release|x86
|
||||
{C0270709-2A40-43B5-8CF1-69581B9FA2A1}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|x86.ActiveCfg = Release|x86
|
||||
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.ActiveCfg = Release|x86
|
||||
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Debug|x86.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
|
||||
{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}.Release|x86.ActiveCfg = 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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.ActiveCfg = Release|x86
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.ActiveCfg = Release|x86
|
||||
{D63E53E4-A458-4C2F-914D-92F715F58ACE}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|x86
|
||||
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|x86
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Debug|x86.Build.0 = Debug|x86
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|x86.ActiveCfg = Release|x86
|
||||
{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|x86.ActiveCfg = Release|x86
|
||||
{E7280DCA-7776-4A73-B9B5-41FD77FC8799}.Release|x86.Build.0 = Release|x86
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|x86.Build.0 = Debug|x86
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|x86.ActiveCfg = Release|x86
|
||||
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.ActiveCfg = Release|x86
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|x86.ActiveCfg = Release|x86
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|x86.Build.0 = Release|x86
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|x86.ActiveCfg = Release|x86
|
||||
{FF2BF37C-E502-4C98-BEA0-701671DDFA08}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = Duplicati\CommandLine\Duplicati.CommandLine.csproj
|
||||
Policies = $0
|
||||
$0.StandardHeader = $1
|
||||
$1.Text = @ Copyright (C) 2011, Kenneth Skovhede\r\n http://www.hexad.dk, opensource@hexad.dk\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 = None
|
||||
$2.ResourceNamePolicy = FileFormatDefault
|
||||
$0.TextStylePolicy = $3
|
||||
$3.FileWidth = 120
|
||||
$3.EolMarker = Windows
|
||||
$3.inheritsSet = VisualStudio
|
||||
$3.inheritsScope = text/plain
|
||||
$3.scope = text/x-csharp
|
||||
$0.CSharpFormattingPolicy = $4
|
||||
$4.BeforeMethodCallParentheses = False
|
||||
$4.BeforeConstructorDeclarationParentheses = False
|
||||
$4.BeforeIndexerDeclarationBracket = False
|
||||
$4.BeforeDelegateDeclarationParentheses = False
|
||||
$4.NewParentheses = False
|
||||
$4.SpacesBeforeBrackets = False
|
||||
$4.inheritsSet = Mono
|
||||
$4.inheritsScope = text/x-csharp
|
||||
$4.scope = text/x-csharp
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(SubversionScc) = preSolution
|
||||
Svn-Managed = True
|
||||
Manager = AnkhSVN - Subversion Support for Visual Studio
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{E7280DCA-7776-4A73-B9B5-41FD77FC8799}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Duplicati.CommandLine.BackendTester</RootNamespace>
|
||||
<AssemblyName>Duplicati.CommandLine.BackendTester</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="NonSeekableStream.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Duplicati.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
|
||||
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
|
||||
<Name>Duplicati.Library.Backend.CloudFiles</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Backend\File\Duplicati.Library.Backend.File.csproj">
|
||||
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
|
||||
<Name>Duplicati.Library.Backend.File</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj">
|
||||
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
|
||||
<Name>Duplicati.Library.Backend.FTP</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Backend\GoogleDocs\Duplicati.Library.Backend.GoogleDocs.csproj">
|
||||
<Project>{42C91180-11EB-4590-82EA-80FE9D4DEBEC}</Project>
|
||||
<Name>Duplicati.Library.Backend.GoogleDocs</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\SkyDrive\Duplicati.Library.Backend.SkyDrive.csproj">
|
||||
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
|
||||
<Name>Duplicati.Library.Backend.SkyDrive</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
|
||||
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
|
||||
<Name>Duplicati.Library.Backend.SSHv2</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj">
|
||||
<Project>{C0270709-2A40-43B5-8CF1-69581B9FA2A1}</Project>
|
||||
<Name>Duplicati.Library.Backend.TahoeLAFS</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj">
|
||||
<Project>{BAE27510-8B5D-44B2-B33E-372A98908041}</Project>
|
||||
<Name>Duplicati.Library.Backend.WEBDAV</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Library.Utility</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj">
|
||||
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
|
||||
<Name>Duplicati.Library.DynamicLoader</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Interface\Duplicati.Library.Interface.csproj">
|
||||
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
|
||||
<Name>Duplicati.Library.Interface</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Duplicati.CommandLine.csproj">
|
||||
<Project>{81765A64-3661-4E3E-B850-2F6F87A51F74}</Project>
|
||||
<Name>Duplicati.CommandLine</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.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
Binary file not shown.
@@ -0,0 +1,55 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Duplicati.CommandLine.BackendTester
|
||||
{
|
||||
/// <summary>
|
||||
/// This class prevents the base stream from being seekable to
|
||||
/// ensure that all operations work correctly on streams that
|
||||
/// are not seekable.
|
||||
/// </summary>
|
||||
public class NonSeekableStream : Library.Utility.OverrideableStream
|
||||
{
|
||||
public NonSeekableStream(System.IO.Stream stream)
|
||||
: base(stream)
|
||||
{ }
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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 Duplicati.Library.Interface;
|
||||
|
||||
namespace Duplicati.CommandLine.BackendTester
|
||||
{
|
||||
class Program
|
||||
{
|
||||
class TempFile
|
||||
{
|
||||
public readonly string remotefilename;
|
||||
public readonly string localfilename;
|
||||
public readonly byte[] hash;
|
||||
public readonly long length;
|
||||
public bool found = false;
|
||||
|
||||
public TempFile(string remotefilename, string localfilename, byte[] hash, long length)
|
||||
{
|
||||
this.remotefilename = remotefilename;
|
||||
this.localfilename = localfilename;
|
||||
this.hash = hash;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
|
||||
private const string ValidFilenameChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
|
||||
private const string ExtendedChars = "-_',=)(&%$#@! +";
|
||||
|
||||
static void Main(string[] _args)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<string> args = new List<string>(_args);
|
||||
Dictionary<string, string> options = Library.Utility.CommandLineParser.ExtractOptions(args);
|
||||
|
||||
if (!options.ContainsKey("ftp_password") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("FTP_PASSWORD")))
|
||||
options["ftp_password"] = System.Environment.GetEnvironmentVariable("FTP_PASSWORD");
|
||||
|
||||
if (!options.ContainsKey("ftp_username") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("FTP_USERNAME")))
|
||||
options["ftp_username"] = System.Environment.GetEnvironmentVariable("FTP_USERNAME");
|
||||
|
||||
if (options.ContainsKey("tempdir") && !string.IsNullOrEmpty(options["tempdir"]))
|
||||
Library.Utility.TempFolder.SystemTempPath = options["tempdir"];
|
||||
|
||||
|
||||
if (args.Count != 1 || args[0].ToLower() == "help" || args[0] == "?")
|
||||
{
|
||||
Console.WriteLine("Usage: <protocol>://<username>:<password>@<path>");
|
||||
Console.WriteLine("Example: ftp://user:pass@server/folder");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Supported backends: " + string.Join(",", Duplicati.Library.DynamicLoader.BackendLoader.Keys));
|
||||
|
||||
Console.WriteLine();
|
||||
List<string> lines = new List<string>();
|
||||
foreach (Library.Interface.ICommandLineArgument arg in SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg);
|
||||
|
||||
foreach (string s in lines)
|
||||
Console.WriteLine(s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int reruns = 5;
|
||||
if (options.ContainsKey("reruns"))
|
||||
reruns = int.Parse(options["reruns"]);
|
||||
|
||||
for (int i = 0; i < reruns; i++)
|
||||
{
|
||||
Console.WriteLine("Starting run no {0}", i);
|
||||
if (!Run(args, options, i == 0))
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("Unittest complete!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Unittest failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Run(List<string> args, Dictionary<string, string> options, bool first)
|
||||
{
|
||||
string allowedChars = ValidFilenameChars;
|
||||
if (options.ContainsKey("extended-chars"))
|
||||
allowedChars += options["extended-chars"];
|
||||
else
|
||||
allowedChars += ExtendedChars;
|
||||
|
||||
bool autoCreateFolders = Library.Utility.Utility.ParseBoolOption(options, "auto-create-folder");
|
||||
|
||||
Library.Interface.IBackend backend = Library.DynamicLoader.BackendLoader.GetBackend(args[0], options);
|
||||
if (backend == null)
|
||||
{
|
||||
Console.WriteLine("Unsupported backend");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Supported backends: " + string.Join(",", Duplicati.Library.DynamicLoader.BackendLoader.Keys));
|
||||
return false;
|
||||
}
|
||||
|
||||
string disabledModulesValue;
|
||||
string enabledModulesValue;
|
||||
options.TryGetValue("enable-module", out enabledModulesValue);
|
||||
options.TryGetValue("disable-module", out disabledModulesValue);
|
||||
string[] enabledModules = enabledModulesValue == null ? new string[0] : enabledModulesValue.Trim().ToLower().Split(',');
|
||||
string[] disabledModules = disabledModulesValue == null ? new string[0] : disabledModulesValue.Trim().ToLower().Split(',');
|
||||
|
||||
List<Library.Interface.IGenericModule> loadedModules = new List<IGenericModule>();
|
||||
foreach (Library.Interface.IGenericModule m in Library.DynamicLoader.GenericLoader.Modules)
|
||||
if (Array.IndexOf<string>(disabledModules, m.Key.ToLower()) < 0 && (m.LoadAsDefault || Array.IndexOf<string>(enabledModules, m.Key.ToLower()) >= 0))
|
||||
{
|
||||
m.Configure(options);
|
||||
loadedModules.Add(m);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
List<Library.Interface.IFileEntry> curlist = null;
|
||||
try
|
||||
{
|
||||
curlist = backend.List();
|
||||
}
|
||||
catch (FolderMissingException fex)
|
||||
{
|
||||
if (autoCreateFolders)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (backend is IBackend_v2)
|
||||
((IBackend_v2)backend).CreateFolder();
|
||||
|
||||
curlist = backend.List();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Autocreate folder failed with message: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
if (curlist == null)
|
||||
throw fex;
|
||||
}
|
||||
|
||||
foreach (Library.Interface.IFileEntry fe in curlist)
|
||||
if (!fe.IsFolder)
|
||||
{
|
||||
if (Library.Utility.Utility.ParseBoolOption(options, "auto-clean") && first)
|
||||
if (Library.Utility.Utility.ParseBoolOption(options, "force"))
|
||||
{
|
||||
Console.WriteLine("Auto clean, removing file: {0}", fe.Name);
|
||||
backend.Delete(fe.Name);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Specify the --force flag to actually delete files");
|
||||
|
||||
Console.WriteLine("*** Remote folder is not empty, aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int number_of_files = 10;
|
||||
int min_file_size = 1024;
|
||||
int max_file_size = 1024 * 1024 * 50;
|
||||
int min_filename_size = 5;
|
||||
int max_filename_size = 80;
|
||||
bool disableStreaming = Library.Utility.Utility.ParseBoolOption(options, "disable-streaming-transfers");
|
||||
bool skipOverwriteTest = Library.Utility.Utility.ParseBoolOption(options, "skip-overwrite-test");
|
||||
|
||||
if (options.ContainsKey("number-of-files"))
|
||||
number_of_files = int.Parse(options["number-of-files"]);
|
||||
if (options.ContainsKey("min-file-size"))
|
||||
min_file_size = (int)Duplicati.Library.Utility.Sizeparser.ParseSize(options["min-file-size"], "mb");
|
||||
if (options.ContainsKey("max-file-size"))
|
||||
max_file_size = (int)Duplicati.Library.Utility.Sizeparser.ParseSize(options["max-file-size"]);
|
||||
|
||||
if (options.ContainsKey("min-filename-length"))
|
||||
min_filename_size = int.Parse(options["min-filename-length"]);
|
||||
if (options.ContainsKey("max-filename-length"))
|
||||
max_filename_size = int.Parse(options["max-filename-length"]);
|
||||
|
||||
Random rnd = new Random();
|
||||
System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create();
|
||||
|
||||
//Create random files
|
||||
using (Library.Utility.TempFolder tf = new Duplicati.Library.Utility.TempFolder())
|
||||
{
|
||||
List<TempFile> files = new List<TempFile>();
|
||||
for (int i = 0; i < number_of_files; i++)
|
||||
{
|
||||
|
||||
StringBuilder filename = new StringBuilder();
|
||||
int filenamelen = rnd.Next(min_filename_size, max_filename_size);
|
||||
for (int j = 0; j < filenamelen; j++)
|
||||
filename.Append(allowedChars[rnd.Next(0, allowedChars.Length)]);
|
||||
|
||||
string localfilename = CreateRandomFile(tf, i, min_file_size, max_file_size, rnd);
|
||||
|
||||
//Calculate local hash and length
|
||||
using (System.IO.FileStream fs = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||||
files.Add(new TempFile(filename.ToString(), localfilename, sha.ComputeHash(fs), fs.Length));
|
||||
}
|
||||
|
||||
byte[] dummyFileHash = null;
|
||||
if (!skipOverwriteTest)
|
||||
{
|
||||
Console.WriteLine("Uploading wrong files ...");
|
||||
using (Library.Utility.TempFile dummy = new Library.Utility.TempFile(CreateRandomFile(tf, files.Count, 1024, 2048, rnd)))
|
||||
{
|
||||
using (System.IO.FileStream fs = new System.IO.FileStream(dummy, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||||
dummyFileHash = sha.ComputeHash(fs);
|
||||
|
||||
//Upload a dummy file for entry 0 and the last one, they will be replaced by the real files afterwards
|
||||
//We upload entry 0 twice just to try to freak any internal cache list
|
||||
Uploadfile(dummy, 0, files[0].remotefilename, backend, disableStreaming);
|
||||
Uploadfile(dummy, 0, files[0].remotefilename, backend, disableStreaming);
|
||||
Uploadfile(dummy, files.Count - 1, files[files.Count - 1].remotefilename, backend, disableStreaming);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Console.WriteLine("Uploading files ...");
|
||||
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
Uploadfile(files[i].localfilename, i, files[i].remotefilename, backend, disableStreaming);
|
||||
|
||||
Console.WriteLine("Verifying file list ...");
|
||||
|
||||
curlist = backend.List();
|
||||
foreach (Library.Interface.IFileEntry fe in curlist)
|
||||
if (!fe.IsFolder)
|
||||
{
|
||||
bool found = false;
|
||||
foreach (TempFile tx in files)
|
||||
if (tx.remotefilename == fe.Name)
|
||||
{
|
||||
if (tx.found)
|
||||
Console.WriteLine("*** File with name {0} was found more than once", tx.remotefilename);
|
||||
found = true;
|
||||
tx.found = true;
|
||||
|
||||
if (fe.Size > 0 && tx.length != fe.Size)
|
||||
Console.WriteLine("*** File with name {0} has size {1} but the size was reported as {2}", tx.remotefilename, tx.length, fe.Size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
Console.WriteLine("*** File with name {0} was found on server but not uploaded!", fe.Name);
|
||||
}
|
||||
|
||||
foreach (TempFile tx in files)
|
||||
if (!tx.found)
|
||||
Console.WriteLine("*** File with name {0} was uploaded but not found afterwards", tx.remotefilename);
|
||||
|
||||
Console.WriteLine("Downloading files");
|
||||
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
using (Duplicati.Library.Utility.TempFile cf = new Duplicati.Library.Utility.TempFile())
|
||||
{
|
||||
Exception e = null;
|
||||
Console.Write("Downloading file {0} ... ", i);
|
||||
|
||||
try
|
||||
{
|
||||
if (backend is Library.Interface.IStreamingBackend && !disableStreaming)
|
||||
{
|
||||
using (System.IO.FileStream fs = new System.IO.FileStream(cf, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
|
||||
using (NonSeekableStream nss = new NonSeekableStream(fs))
|
||||
(backend as Library.Interface.IStreamingBackend).Get(files[i].remotefilename, nss);
|
||||
}
|
||||
else
|
||||
backend.Get(files[i].remotefilename, cf);
|
||||
|
||||
e = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e = ex;
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
Console.WriteLine("failed\n*** Error: {0}", e.ToString());
|
||||
else
|
||||
Console.WriteLine("done");
|
||||
|
||||
Console.Write("Checking hash ... ");
|
||||
|
||||
using (System.IO.FileStream fs = new System.IO.FileStream(cf, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||||
if (Convert.ToBase64String(sha.ComputeHash(fs)) != Convert.ToBase64String(files[i].hash))
|
||||
{
|
||||
if (dummyFileHash != null && Convert.ToBase64String(sha.ComputeHash(fs)) == Convert.ToBase64String(dummyFileHash))
|
||||
Console.WriteLine("failed\n*** Downloaded file was the dummy file");
|
||||
else
|
||||
Console.WriteLine("failed\n*** Downloaded file was corrupt");
|
||||
}
|
||||
else
|
||||
Console.WriteLine("done");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Deleting files...");
|
||||
|
||||
foreach (TempFile tx in files)
|
||||
try { backend.Delete(tx.remotefilename); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("*** Failed to delete file {0}, message: {1}", tx.remotefilename, ex.ToString());
|
||||
}
|
||||
|
||||
curlist = backend.List();
|
||||
foreach (Library.Interface.IFileEntry fe in curlist)
|
||||
if (!fe.IsFolder)
|
||||
{
|
||||
Console.WriteLine("*** Remote folder contains {0} after cleanup", fe.Name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach (Library.Interface.IGenericModule m in loadedModules)
|
||||
if (m is IDisposable)
|
||||
((IDisposable)m).Dispose();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void Uploadfile(string localfilename, int i, string remotefilename, IBackend backend, bool disableStreaming)
|
||||
{
|
||||
Console.Write("Uploading file {0}, {1} ... ", i, Duplicati.Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(localfilename).Length));
|
||||
Exception e = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (backend is Library.Interface.IStreamingBackend && !disableStreaming)
|
||||
{
|
||||
using (System.IO.FileStream fs = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
|
||||
using (NonSeekableStream nss = new NonSeekableStream(fs))
|
||||
(backend as Library.Interface.IStreamingBackend).Put(remotefilename, nss);
|
||||
}
|
||||
else
|
||||
backend.Put(remotefilename, localfilename);
|
||||
|
||||
e = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e = ex;
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
Console.WriteLine("Failed to upload file {0}, error message: {1}, remote name: {2}", i, e.ToString(), remotefilename);
|
||||
while (e.InnerException != null)
|
||||
{
|
||||
e = e.InnerException;
|
||||
Console.WriteLine(string.Format(" Inner exception: {0}", e.ToString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(" done!");
|
||||
}
|
||||
}
|
||||
|
||||
private static string CreateRandomFile(Library.Utility.TempFolder tf, int i, int min_file_size, int max_file_size, Random rnd)
|
||||
{
|
||||
Console.Write("Generating file {0}", i);
|
||||
string filename = System.IO.Path.Combine(tf, i.ToString());
|
||||
using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write))
|
||||
{
|
||||
//Random size
|
||||
byte[] buf = new byte[1024];
|
||||
int size = rnd.Next(min_file_size, max_file_size);
|
||||
|
||||
Console.WriteLine(" ({0})", Duplicati.Library.Utility.Utility.FormatSizeString(size));
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
rnd.NextBytes(buf);
|
||||
fs.Write(buf, 0, Math.Min(buf.Length, size));
|
||||
size -= buf.Length;
|
||||
}
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
public static IList<ICommandLineArgument> SupportedCommands
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<ICommandLineArgument>(new ICommandLineArgument[] {
|
||||
new CommandLineArgument("reruns", CommandLineArgument.ArgumentType.Integer, "The number of test runs to perform", "A number that describes how many times the test is performed", "5"),
|
||||
new CommandLineArgument("tempdir", CommandLineArgument.ArgumentType.Path, "The path used to store temporary files", "The backend tester will use the system default temp path. You can set this option to choose another path."),
|
||||
new CommandLineArgument("extended-chars", CommandLineArgument.ArgumentType.String, "A list of allowed extended filename chars", "A list of characters besides {a-z, A-Z, 0-9} to use when generating filenames", ExtendedChars),
|
||||
new CommandLineArgument("number-of-files", CommandLineArgument.ArgumentType.Integer, "The number of files to test with", "An integer describing how many files to upload during a test run", "10"),
|
||||
new CommandLineArgument("min-file-size", CommandLineArgument.ArgumentType.Size, "The minimum allowed file size", "File sizes are chosen at random, this valus is the lower bound", "1kb"),
|
||||
new CommandLineArgument("max-file-size", CommandLineArgument.ArgumentType.Size, "The maximum allowed file size", "File sizes are chosen at random, this valus is the upper bound", "50mb"),
|
||||
new CommandLineArgument("min-filename-length", CommandLineArgument.ArgumentType.Integer, "The minimum allowed filename length", "File name lengths are chosen at random, this valus is the lower bound", "5"),
|
||||
new CommandLineArgument("max-filename-length", CommandLineArgument.ArgumentType.Integer, "The minimum allowed filename length", "File name lengths are chosen at random, this valus is the upper bound", "80"),
|
||||
new CommandLineArgument("auto-create-folder", CommandLineArgument.ArgumentType.Boolean, "Allows automatic folder creation", "A value that indicates if missing folders are created automatically", "false"),
|
||||
new CommandLineArgument("skip-overwrite-test", CommandLineArgument.ArgumentType.Boolean, "Bypasses the overwrite test", "A value that indicates if dummy files should be uploaded prior to uploading the real files", "false"),
|
||||
new CommandLineArgument("auto-clean", CommandLineArgument.ArgumentType.Boolean, "Removes any files found in target folder", "A value that indicates if all files in the target folder should be deleted before starting the first test", "false"),
|
||||
new CommandLineArgument("force", CommandLineArgument.ArgumentType.Boolean, "Activates file deletion", "A value that indicates if existing files should really be deleted when using auto-clean", "false")
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("CommandLine.BackendTester")]
|
||||
[assembly: AssemblyDescription("A backend debugging tool for Duplicati")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("CommandLine.BackendTester")]
|
||||
[assembly: AssemblyCopyright("Copyright © HexaD 2010")]
|
||||
[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("53df9eb0-a6e8-49a2-838d-b2a2c4a8d41f")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.1.276")]
|
||||
[assembly: AssemblyFileVersion("1.0.1.276")]
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true" />
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
|
||||
</configuration>
|
||||
@@ -0,0 +1,16 @@
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 50 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r50
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 100 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r100
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 150 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r150
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 200 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r200
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 250 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 251 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 252 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 253 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 254 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 255 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 256 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 257 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 258 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 259 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 260 http://dsmcbe.googlecode.com/svn/trunk/ bin\Debug\DSMCBE\r250
|
||||
pause
|
||||
@@ -0,0 +1,7 @@
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 100 http://svn.osgeo.org/mapguide/trunk/MgDev bin\Debug\MapGuide\r100
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 1000 http://svn.osgeo.org/mapguide/trunk/MgDev bin\Debug\MapGuide\r1000
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 2000 http://svn.osgeo.org/mapguide/trunk/MgDev bin\Debug\MapGuide\r2000
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 3000 http://svn.osgeo.org/mapguide/trunk/MgDev bin\Debug\MapGuide\r3000
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 3100 http://svn.osgeo.org/mapguide/trunk/MgDev bin\Debug\MapGuide\r3100
|
||||
"%ProgramFiles%\CollabNet Subversion\svn" checkout -r 3200 http://svn.osgeo.org/mapguide/trunk/MgDev bin\Debug\MapGuide\r3200
|
||||
pause
|
||||
@@ -0,0 +1,103 @@
|
||||
<?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>{E2AF781D-D1E1-4512-BF2C-D6DA8D0F797F}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Duplicati.CommandLine.Decrypter</RootNamespace>
|
||||
<AssemblyName>Duplicati.CommandLine.Decrypter</AssemblyName>
|
||||
<ApplicationIcon>TrayUnknown.ico</ApplicationIcon>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Strings\Program.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Program.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Library\Encryption\Duplicati.Library.Encryption.csproj">
|
||||
<Project>{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}</Project>
|
||||
<Name>Duplicati.Library.Encryption</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\Interface\Duplicati.Library.Interface.csproj">
|
||||
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
|
||||
<Name>Duplicati.Library.Interface</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="Duplicati.snk" />
|
||||
<None Include="Resources\Usage.txt" />
|
||||
<Content Include="TrayUnknown.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Strings\Program.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Program.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</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>
|
||||
Binary file not shown.
@@ -0,0 +1,41 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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 Duplicati.Library.Encryption;
|
||||
|
||||
namespace Duplicati.CommandLine.Decrypter
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length != 3)
|
||||
{
|
||||
Console.WriteLine(Strings.Program.ProgramUsage);
|
||||
return;
|
||||
}
|
||||
|
||||
AESEncryption c = new AESEncryption(args[0], new Dictionary<string,string>());
|
||||
c.Decrypt(args[1], args[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("Duplicati.CommandLine.Decrypter")]
|
||||
[assembly: AssemblyDescription("A commandline decryption tool for Duplicati")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("Duplicati.CommandLine.Decrypter")]
|
||||
[assembly: AssemblyCopyright("LGPL, Copyright © HexaD 2010")]
|
||||
[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("31de2d8c-9bab-4357-99c6-6a99058928a2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.1.276")]
|
||||
[assembly: AssemblyFileVersion("1.0.1.276")]
|
||||
@@ -0,0 +1,72 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.237
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Duplicati.CommandLine.Decrypter.Strings {
|
||||
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 Program {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Program() {
|
||||
}
|
||||
|
||||
/// <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("Duplicati.CommandLine.Decrypter.Strings.Program", typeof(Program).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 Usage: Duplicati.CommandLine.Decrypter.exe <passphrase> <inputfile> <outputfile>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsage {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsage", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?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>
|
||||
<data name="ProgramUsage" xml:space="preserve">
|
||||
<value>Usage: Duplicati.CommandLine.Decrypter.exe <passphrase> <inputfile> <outputfile></value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
@@ -0,0 +1,211 @@
|
||||
<?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>{81765A64-3661-4E3E-B850-2F6F87A51F74}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Duplicati.CommandLine</RootNamespace>
|
||||
<AssemblyName>Duplicati.CommandLine</AssemblyName>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
<ApplicationIcon>TrayWarning.ico</ApplicationIcon>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Help.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Strings\Program.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Program.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UnitTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
|
||||
<Project>{1BFAE226-8364-4086-825C-BB83F6F3EE4C}</Project>
|
||||
<Name>Duplicati.Library.Backend.CloudFiles</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\File\Duplicati.Library.Backend.File.csproj">
|
||||
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
|
||||
<Name>Duplicati.Library.Backend.File</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\FTP\Duplicati.Library.Backend.FTP.csproj">
|
||||
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
|
||||
<Name>Duplicati.Library.Backend.FTP</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\GoogleDocs\Duplicati.Library.Backend.GoogleDocs.csproj">
|
||||
<Project>{42C91180-11EB-4590-82EA-80FE9D4DEBEC}</Project>
|
||||
<Name>Duplicati.Library.Backend.GoogleDocs</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\SkyDrive\Duplicati.Library.Backend.SkyDrive.csproj">
|
||||
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
|
||||
<Name>Duplicati.Library.Backend.SkyDrive</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
|
||||
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
|
||||
<Name>Duplicati.Library.Backend.SSHv2</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\TahoeLAFS\Duplicati.Library.Backend.TahoeLAFS.csproj">
|
||||
<Project>{C0270709-2A40-43B5-8CF1-69581B9FA2A1}</Project>
|
||||
<Name>Duplicati.Library.Backend.TahoeLAFS</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\WEBDAV\Duplicati.Library.Backend.WEBDAV.csproj">
|
||||
<Project>{BAE27510-8B5D-44B2-B33E-372A98908041}</Project>
|
||||
<Name>Duplicati.Library.Backend.WEBDAV</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Compression\Duplicati.Library.Compression.csproj">
|
||||
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
|
||||
<Name>Duplicati.Library.Compression</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Utility\Duplicati.Library.Utility.csproj">
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Library.Utility</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\DynamicLoader\Duplicati.Library.DynamicLoader.csproj">
|
||||
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
|
||||
<Name>Duplicati.Library.DynamicLoader</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Encryption\Duplicati.Library.Encryption.csproj">
|
||||
<Project>{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}</Project>
|
||||
<Name>Duplicati.Library.Encryption</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Interface\Duplicati.Library.Interface.csproj">
|
||||
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
|
||||
<Name>Duplicati.Library.Interface</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Logging\Duplicati.Library.Logging.csproj">
|
||||
<Project>{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}</Project>
|
||||
<Name>Duplicati.Library.Logging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Main\Duplicati.Library.Main.csproj">
|
||||
<Project>{10D2D1B7-C664-41D8-9B3A-00040C3D421B}</Project>
|
||||
<Name>Duplicati.Library.Main</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
|
||||
<Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
|
||||
<Name>Duplicati.Library.Modules.Builtin</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\SharpRSync\Duplicati.Library.SharpRSync.csproj">
|
||||
<Project>{47FE73E1-0832-44F7-96B9-2580273206C3}</Project>
|
||||
<Name>Duplicati.Library.SharpRSync</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\License\Duplicati.License.csproj">
|
||||
<Project>{4D012CB1-4B92-47F4-89B7-BF80A73A2E99}</Project>
|
||||
<Name>Duplicati.License</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>
|
||||
<Content Include="..\..\thirdparty\Putty\pscp.exe">
|
||||
<Link>win-tools\pscp.exe</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<EmbeddedResource Include="help.txt" />
|
||||
<Content Include="TrayWarning.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Strings\Program.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Program.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</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>
|
||||
Binary file not shown.
@@ -0,0 +1,477 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Duplicati.CommandLine
|
||||
{
|
||||
public static class Help
|
||||
{
|
||||
private static readonly Dictionary<string, string> _document;
|
||||
private const string RESOURCE_NAME = "Duplicati.CommandLine.help.txt";
|
||||
private static readonly System.Text.RegularExpressions.Regex NAMEDOPTION_REGEX = new System.Text.RegularExpressions.Regex("\\%OPTION\\:(?<name>[^\\%]+)\\%");
|
||||
|
||||
static Help()
|
||||
{
|
||||
_document = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
using (System.IO.StreamReader sr = new System.IO.StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(RESOURCE_NAME)))
|
||||
{
|
||||
List<string> keywords = new List<string>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(var line in sr.ReadToEnd().Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None))
|
||||
{
|
||||
if (line.Trim().StartsWith("#"))
|
||||
continue;
|
||||
|
||||
if (line.Trim().StartsWith(">"))
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
string s = sb.ToString();
|
||||
foreach(var k in keywords)
|
||||
_document[k] = s;
|
||||
|
||||
keywords.Clear();
|
||||
sb.Clear();
|
||||
}
|
||||
|
||||
string[] elems = line.Split(new string[] {" ", "\t"}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (elems.Length >= 2 && string.Equals(elems[elems.Length - 2], "help", StringComparison.InvariantCultureIgnoreCase))
|
||||
keywords.Add(elems[elems.Length - 1]);
|
||||
else if (elems.Length == 3 && string.Equals(elems[elems.Length - 1], "help", StringComparison.InvariantCultureIgnoreCase))
|
||||
keywords.Add("help");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
string s = sb.ToString();
|
||||
foreach(var k in keywords)
|
||||
_document[k] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PrintUsage(string topic, IDictionary<string, string> options)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Force translation off
|
||||
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
|
||||
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(topic))
|
||||
topic = "help";
|
||||
|
||||
if (string.Equals("help", topic, StringComparison.InvariantCultureIgnoreCase) && options.Count == 1)
|
||||
topic = new List<string>(options.Keys)[0];
|
||||
|
||||
|
||||
if (_document.ContainsKey(topic))
|
||||
{
|
||||
string tp = _document[topic];
|
||||
Library.Main.Options opts = new Library.Main.Options(new Dictionary<string, string>());
|
||||
|
||||
tp = tp.Replace("%VERSION%", License.VersionNumbers.Version);
|
||||
tp = tp.Replace("%BACKENDS%", string.Join(", ", Library.DynamicLoader.BackendLoader.Keys));
|
||||
tp = tp.Replace("%MONO%", Library.Utility.Utility.IsMono ? "mono " : "");
|
||||
tp = tp.Replace("%APP_PATH%", System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location));
|
||||
tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", Library.Utility.Utility.IsClientLinux ? "/source" : "D:\\source");
|
||||
tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", Library.Utility.Utility.IsClientLinux ? "/source/myfile.txt" : "D:\\source\\file.txt");
|
||||
tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", Library.Utility.Utility.IsClientLinux ? "/restore" : "D:\\restore");
|
||||
tp = tp.Replace("%ENCRYPTIONMODULES%", string.Join(", ", Library.DynamicLoader.EncryptionLoader.Keys));
|
||||
tp = tp.Replace("%COMPRESSIONMODULES%", string.Join(", ", Library.DynamicLoader.CompressionLoader.Keys));
|
||||
tp = tp.Replace("%DEFAULTENCRYPTIONMODULE%", opts.EncryptionModule);
|
||||
tp = tp.Replace("%DEFAULTCOMPRESSIONMODULE%", opts.CompressionModule);
|
||||
tp = tp.Replace("%GENERICMODULES%", string.Join(", ", Library.DynamicLoader.GenericLoader.Keys));
|
||||
|
||||
if (tp.Contains("%MAINOPTIONS%"))
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
SortedList<string, Library.Interface.ICommandLineArgument> sorted = new SortedList<string, Library.Interface.ICommandLineArgument>();
|
||||
foreach (Library.Interface.ICommandLineArgument arg in opts.SupportedCommands)
|
||||
sorted.Add(arg.Name, arg);
|
||||
|
||||
foreach (Library.Interface.ICommandLineArgument arg in Program.SupportedCommands)
|
||||
|
||||
sorted.Add(arg.Name, arg);
|
||||
|
||||
|
||||
foreach (Library.Interface.ICommandLineArgument arg in sorted.Values)
|
||||
lines.Add(PrintArgSimple(arg, arg.Name));
|
||||
|
||||
tp = tp.Replace("%MAINOPTIONS%", string.Join(Environment.NewLine, lines.ToArray()));
|
||||
}
|
||||
|
||||
if (tp.Contains("%ALLOPTIONS%"))
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
foreach (Library.Interface.ICommandLineArgument arg in opts.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
|
||||
|
||||
|
||||
foreach (Library.Interface.ICommandLineArgument arg in Program.SupportedCommands)
|
||||
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.SupportedBackendsHeader);
|
||||
foreach (Duplicati.Library.Interface.IBackend back in Library.DynamicLoader.BackendLoader.Backends)
|
||||
PrintBackend(back, lines);
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.SupportedEncryptionModulesHeader);
|
||||
foreach (Duplicati.Library.Interface.IEncryption mod in Library.DynamicLoader.EncryptionLoader.Modules)
|
||||
PrintEncryptionModule(mod, lines);
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.SupportedCompressionModulesHeader);
|
||||
foreach (Duplicati.Library.Interface.ICompression mod in Library.DynamicLoader.CompressionLoader.Modules)
|
||||
PrintCompressionModule(mod, lines);
|
||||
|
||||
lines.Add("");
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.GenericModulesHeader);
|
||||
foreach (Duplicati.Library.Interface.IGenericModule mod in Library.DynamicLoader.GenericLoader.Modules)
|
||||
PrintGenericModule(mod, lines);
|
||||
|
||||
lines.Add("");
|
||||
|
||||
tp = tp.Replace("%ALLOPTIONS%", string.Join(Environment.NewLine, lines.ToArray()));
|
||||
}
|
||||
|
||||
if (tp.Contains("%MODULEOPTIONS%"))
|
||||
{
|
||||
//Figure out which module we are in
|
||||
IList<Library.Interface.ICommandLineArgument> args = null;
|
||||
bool found = false;
|
||||
foreach (Duplicati.Library.Interface.IBackend backend in Library.DynamicLoader.BackendLoader.Backends)
|
||||
if (string.Equals(backend.ProtocolKey, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
args = backend.SupportedCommands;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
foreach (Duplicati.Library.Interface.IEncryption module in Library.DynamicLoader.EncryptionLoader.Modules)
|
||||
if (string.Equals(module.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
args = module.SupportedCommands;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
foreach (Duplicati.Library.Interface.ICompression module in Library.DynamicLoader.CompressionLoader.Modules)
|
||||
if (string.Equals(module.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
args = module.SupportedCommands;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
foreach (Duplicati.Library.Interface.IGenericModule module in Library.DynamicLoader.GenericLoader.Modules)
|
||||
if (string.Equals(module.Key, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
args = module.SupportedCommands;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//If the module is not found, we do not display the description
|
||||
if (found)
|
||||
tp = tp.Replace("%MODULEOPTIONS%", PrintArgsSimple(args));
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Topic not found: {0}", topic);
|
||||
Console.WriteLine();
|
||||
//Prevent recursive lookups
|
||||
if (topic != "help")
|
||||
PrintUsage("help", new Dictionary<string, string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (NAMEDOPTION_REGEX.IsMatch(tp))
|
||||
tp = NAMEDOPTION_REGEX.Replace(tp, new Matcher().MathEvaluator);
|
||||
|
||||
PrintFormatted(tp.Split(new string[] { Environment.NewLine }, StringSplitOptions.None));
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
|
||||
foreach (Duplicati.Library.Interface.IBackend backend in Library.DynamicLoader.BackendLoader.Backends)
|
||||
if (string.Equals(backend.ProtocolKey, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
PrintBackend(backend, lines);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lines.Count == 0)
|
||||
foreach (Duplicati.Library.Interface.IEncryption mod in Library.DynamicLoader.EncryptionLoader.Modules)
|
||||
if (string.Equals(mod.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
PrintEncryptionModule(mod, lines);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lines.Count == 0)
|
||||
foreach (Duplicati.Library.Interface.ICompression mod in Library.DynamicLoader.CompressionLoader.Modules)
|
||||
if (string.Equals(mod.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
PrintCompressionModule(mod, lines);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lines.Count == 0)
|
||||
foreach (Duplicati.Library.Interface.IGenericModule mod in Library.DynamicLoader.GenericLoader.Modules)
|
||||
if (string.Equals(mod.Key, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
PrintGenericModule(mod, lines);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (lines.Count == 0)
|
||||
PrintArgumentIfFound(new Matcher().Values, topic, lines);
|
||||
|
||||
if (lines.Count != 0)
|
||||
{
|
||||
PrintFormatted(lines);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Topic not found: {0}", topic);
|
||||
Console.WriteLine();
|
||||
PrintUsage("help", new Dictionary<string, string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintArgumentIfFound(IEnumerable<Duplicati.Library.Interface.ICommandLineArgument> args, string topic, List<string> lines)
|
||||
{
|
||||
if (args == null)
|
||||
return;
|
||||
|
||||
foreach (Duplicati.Library.Interface.ICommandLineArgument arg in args)
|
||||
{
|
||||
if (string.Equals(arg.Name, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg.Aliases != null)
|
||||
foreach (string k in arg.Aliases)
|
||||
{
|
||||
if (string.Equals(k, topic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintBackend(Duplicati.Library.Interface.IBackend back, List<string> lines)
|
||||
{
|
||||
lines.Add(back.DisplayName + " (" + back.ProtocolKey + "):");
|
||||
lines.Add(" " + back.Description);
|
||||
if (back.SupportedCommands != null && back.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in back.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
private static void PrintEncryptionModule(Duplicati.Library.Interface.IEncryption mod, List<string> lines)
|
||||
{
|
||||
lines.Add(mod.DisplayName + " (." + mod.FilenameExtension + "):");
|
||||
lines.Add(" " + mod.Description);
|
||||
if (mod.SupportedCommands != null && mod.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in mod.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
private static void PrintCompressionModule(Duplicati.Library.Interface.ICompression mod, List<string> lines)
|
||||
{
|
||||
lines.Add(mod.DisplayName + " (." + mod.FilenameExtension + "):");
|
||||
lines.Add(" " + mod.Description);
|
||||
if (mod.SupportedCommands != null && mod.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in mod.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
private static void PrintGenericModule(Duplicati.Library.Interface.IGenericModule mod, List<string> lines)
|
||||
{
|
||||
lines.Add(mod.DisplayName + " (" + mod.Key + "):");
|
||||
lines.Add(" " + mod.Description);
|
||||
lines.Add(" " + (mod.LoadAsDefault ? Strings.Program.ModuleIsLoadedAutomatically : Strings.Program.ModuleIsNotLoadedAutomatically));
|
||||
if (mod.SupportedCommands != null && mod.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in mod.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
private static string PrintArguments(IEnumerable<Duplicati.Library.Interface.ICommandLineArgument> args)
|
||||
{
|
||||
if (args == null)
|
||||
return "";
|
||||
|
||||
List<string> lines = new List<string>();
|
||||
foreach (Library.Interface.ICommandLineArgument arg in args)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
|
||||
|
||||
return string.Join(Environment.NewLine, lines.ToArray());
|
||||
|
||||
}
|
||||
|
||||
private static void PrintFormatted(IEnumerable<string> lines)
|
||||
{
|
||||
foreach (string s in lines)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s) || s.Trim().Length == 0)
|
||||
{
|
||||
Console.WriteLine();
|
||||
continue;
|
||||
}
|
||||
|
||||
string c = s;
|
||||
|
||||
string leadingSpaces = "";
|
||||
while (c.Length > 0 && c.StartsWith(" "))
|
||||
{
|
||||
leadingSpaces += " ";
|
||||
c = c.Remove(0, 1);
|
||||
}
|
||||
|
||||
bool extraIndent = c.StartsWith("--");
|
||||
|
||||
while (c.Length > 0)
|
||||
{
|
||||
int len = Math.Min(Console.WindowWidth - 2, leadingSpaces.Length + c.Length);
|
||||
len -= leadingSpaces.Length;
|
||||
if (len < c.Length)
|
||||
{
|
||||
int ix = c.LastIndexOf(" ", len);
|
||||
if (ix > 0)
|
||||
len = ix;
|
||||
}
|
||||
|
||||
Console.WriteLine(leadingSpaces + c.Substring(0, len).Trim());
|
||||
c = c.Remove(0, len);
|
||||
if (extraIndent)
|
||||
{
|
||||
extraIndent = false;
|
||||
leadingSpaces += " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Matcher
|
||||
{
|
||||
Dictionary<string, Library.Interface.ICommandLineArgument> args = new Dictionary<string, Library.Interface.ICommandLineArgument>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
public Matcher()
|
||||
{
|
||||
Library.Main.Options opts = new Library.Main.Options(new Dictionary<string, string>());
|
||||
List<IList<Library.Interface.ICommandLineArgument>> foundArgs = new List<IList<Library.Interface.ICommandLineArgument>>();
|
||||
foundArgs.Add(new Library.Main.Options(new Dictionary<string, string>()).SupportedCommands);
|
||||
foundArgs.Add(Program.SupportedCommands);
|
||||
|
||||
foreach (Duplicati.Library.Interface.IBackend backend in Library.DynamicLoader.BackendLoader.Backends)
|
||||
if (backend.SupportedCommands != null)
|
||||
foundArgs.Add(backend.SupportedCommands);
|
||||
foreach (Duplicati.Library.Interface.IEncryption mod in Library.DynamicLoader.EncryptionLoader.Modules)
|
||||
if (mod.SupportedCommands != null)
|
||||
foundArgs.Add(mod.SupportedCommands);
|
||||
foreach (Duplicati.Library.Interface.ICompression mod in Library.DynamicLoader.CompressionLoader.Modules)
|
||||
if (mod.SupportedCommands != null)
|
||||
foundArgs.Add(mod.SupportedCommands);
|
||||
foreach (Duplicati.Library.Interface.IGenericModule mod in Library.DynamicLoader.GenericLoader.Modules)
|
||||
if (mod.SupportedCommands != null)
|
||||
foundArgs.Add(mod.SupportedCommands);
|
||||
|
||||
foreach (IEnumerable<Library.Interface.ICommandLineArgument> arglst in foundArgs)
|
||||
if (arglst != null)
|
||||
{
|
||||
foreach (Library.Interface.ICommandLineArgument arg in arglst)
|
||||
{
|
||||
if (!args.ContainsKey(arg.Name))
|
||||
args[arg.Name] = arg;
|
||||
|
||||
if (arg.Aliases != null)
|
||||
foreach (string a in arg.Aliases)
|
||||
if (!args.ContainsKey(a))
|
||||
args[a] = arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Library.Interface.ICommandLineArgument> Values { get { return args.Values; } }
|
||||
|
||||
public string MathEvaluator(System.Text.RegularExpressions.Match m)
|
||||
{
|
||||
if (!m.Success || !m.Groups["name"].Success)
|
||||
return "";
|
||||
|
||||
Duplicati.Library.Interface.ICommandLineArgument arg;
|
||||
if (!args.TryGetValue(m.Groups["name"].Value, out arg))
|
||||
return "";
|
||||
else
|
||||
return PrintArgSimple(arg, m.Groups["name"].Value.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
|
||||
private static string PrintArgsSimple(IEnumerable<Duplicati.Library.Interface.ICommandLineArgument> args)
|
||||
{
|
||||
if (args == null)
|
||||
return "";
|
||||
|
||||
List<string> lines = new List<string>();
|
||||
foreach(Duplicati.Library.Interface.ICommandLineArgument arg in args)
|
||||
lines.Add(PrintArgSimple(arg, arg.Name));
|
||||
|
||||
return string.Join(Environment.NewLine, lines.ToArray());
|
||||
}
|
||||
|
||||
|
||||
private static string PrintArgSimple(Duplicati.Library.Interface.ICommandLineArgument arg, string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(arg.DefaultValue))
|
||||
return string.Format(" --{0}{1} {2}", name, Environment.NewLine, arg.LongDescription);
|
||||
else
|
||||
return string.Format(" --{0} = {1}{2} {3}", name, arg.DefaultValue, Environment.NewLine, arg.LongDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,768 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Duplicati.CommandLine
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private static readonly string[] COMMANDS_AS_ARGUMENTS = new string[] { "delete-all-but-n-full", "delete-all-but-n", "delete-older-than" };
|
||||
|
||||
static int Main(string[] args)
|
||||
{
|
||||
bool verboseErrors = false;
|
||||
try
|
||||
{
|
||||
List<string> cargs = new List<string>(args);
|
||||
string filter = Duplicati.Library.Utility.FilenameFilter.EncodeAsFilter(Duplicati.Library.Utility.FilenameFilter.ParseCommandLine(cargs, true));
|
||||
Dictionary<string, string> options = Library.Utility.CommandLineParser.ExtractOptions(cargs);
|
||||
|
||||
verboseErrors = Library.Utility.Utility.ParseBoolOption(options, "debug-output");
|
||||
|
||||
//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)
|
||||
{
|
||||
string wintools = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "win-tools");
|
||||
Environment.SetEnvironmentVariable("PATH",
|
||||
Environment.GetEnvironmentVariable("PATH") +
|
||||
System.IO.Path.PathSeparator.ToString() +
|
||||
wintools +
|
||||
System.IO.Path.PathSeparator.ToString() +
|
||||
System.IO.Path.Combine(wintools, "gpg") //GPG needs to be in a subfolder for wrapping reasons
|
||||
);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (cargs.Count > 1 && cargs[0].ToLower() == "unittest")
|
||||
{
|
||||
//The unit test is only enabled in DEBUG builds
|
||||
//it works by getting a list of folders, and treats them as
|
||||
//if they have the same data, but on different times
|
||||
|
||||
//The first folder is used to make a full backup,
|
||||
//and each subsequent folder is used to make an incremental backup
|
||||
|
||||
//After all backups are made, the files are restored and verified against
|
||||
//the original folders.
|
||||
|
||||
//The best way to test it, is to use SVN checkouts at different
|
||||
//revisions, as this is how a regular folder would evolve
|
||||
|
||||
cargs.RemoveAt(0);
|
||||
UnitTest.RunTest(cargs.ToArray(), options);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cargs.Count > 0)
|
||||
{
|
||||
//Because options are of the format --name=value, it seems natural to write "delete-all-but-n-full=5",
|
||||
// so we allow that format as well
|
||||
foreach (string s in COMMANDS_AS_ARGUMENTS)
|
||||
if (cargs[0].Trim().ToLower().StartsWith(s + "="))
|
||||
{
|
||||
cargs.Insert(1, cargs[0].Substring(s.Length + 1));
|
||||
cargs[0] = s;
|
||||
}
|
||||
}
|
||||
|
||||
//AFTER converting options to commands, we check for internal switches
|
||||
foreach (string internaloption in Library.Main.Options.InternalOptions)
|
||||
if (options.ContainsKey(internaloption))
|
||||
{
|
||||
Console.WriteLine(Strings.Program.InternalOptionUsedError, internaloption);
|
||||
return 200;
|
||||
}
|
||||
|
||||
if ((options.ContainsKey("parameters-file") && !string.IsNullOrEmpty("parameters-file")) || (options.ContainsKey("parameter-file") && !string.IsNullOrEmpty("parameter-file")))
|
||||
{
|
||||
string filename;
|
||||
if (options.ContainsKey("parameters-file") && !string.IsNullOrEmpty("parameters-file"))
|
||||
{
|
||||
filename = options["parameters-file"];
|
||||
options.Remove("parameters-file");
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = options["parameter-file"];
|
||||
options.Remove("parameter-file");
|
||||
}
|
||||
|
||||
if (!ReadOptionsFromFile(filename, ref filter, cargs, options))
|
||||
return 100;
|
||||
}
|
||||
|
||||
//After checking for internal options, we set the filter option
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
options["filter"] = filter;
|
||||
|
||||
if (cargs.Count == 1)
|
||||
{
|
||||
switch (cargs[0].Trim().ToLower())
|
||||
{
|
||||
case "purge-signature-cache":
|
||||
Library.Main.Interface.PurgeSignatureCache(options);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cargs.Count < 2 || cargs[0].Trim().Equals("help", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (cargs.Count < 2)
|
||||
Help.PrintUsage("help", options);
|
||||
else
|
||||
Help.PrintUsage(cargs[1], options);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
string source = cargs[0];
|
||||
string target = cargs[1];
|
||||
|
||||
if (source.Trim().ToLower() == "restore" && cargs.Count == 3)
|
||||
{
|
||||
source = target;
|
||||
target = cargs[2];
|
||||
options["restore"] = null;
|
||||
cargs.RemoveAt(0);
|
||||
}
|
||||
else if (source.Trim().ToLower() == "backup" && cargs.Count == 3)
|
||||
{
|
||||
source = target;
|
||||
target = cargs[2];
|
||||
cargs.RemoveAt(0);
|
||||
}
|
||||
|
||||
if (!options.ContainsKey("passphrase"))
|
||||
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("PASSPHRASE")))
|
||||
options["passphrase"] = System.Environment.GetEnvironmentVariable("PASSPHRASE");
|
||||
|
||||
if (!options.ContainsKey("ftp-password"))
|
||||
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("FTP_PASSWORD")))
|
||||
options["ftp-password"] = System.Environment.GetEnvironmentVariable("FTP_PASSWORD");
|
||||
|
||||
if (!options.ContainsKey("ftp-username"))
|
||||
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("FTP_USERNAME")))
|
||||
options["ftp-username"] = System.Environment.GetEnvironmentVariable("FTP_USERNAME");
|
||||
|
||||
if (source.Trim().ToLower() == "list")
|
||||
Console.WriteLine(string.Join(Environment.NewLine, Duplicati.Library.Main.Interface.List(target, options)));
|
||||
else if (source.Trim().ToLower() == "list-current-files")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
Console.WriteLine(string.Join(Environment.NewLine, new List<string>(Duplicati.Library.Main.Interface.ListCurrentFiles(target, options)).ToArray()));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "list-source-folders")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
Console.WriteLine(string.Join(Environment.NewLine, Duplicati.Library.Main.Interface.ListSourceFolders(target, options) ?? new string[0]));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "list-actual-signature-files")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
List<KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string>> files = Duplicati.Library.Main.Interface.ListActualSignatureFiles(cargs[0], options);
|
||||
|
||||
Console.WriteLine("* " + Strings.Program.DeletedFoldersHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.DeletedFolder)
|
||||
Console.WriteLine(x.Value);
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.AddedFoldersHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.AddedFolder)
|
||||
Console.WriteLine(x.Value);
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.DeletedFilesHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.DeletedFile)
|
||||
Console.WriteLine(x.Value);
|
||||
|
||||
bool hasCombinedSignatures = false;
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.AddedOrUpdatedFile)
|
||||
{
|
||||
hasCombinedSignatures = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasCombinedSignatures)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.NewOrModifiedFilesHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.AddedOrUpdatedFile)
|
||||
Console.WriteLine(x.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.NewFilesHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.AddedFile)
|
||||
Console.WriteLine(x.Value);
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.ModifiedFilesHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.UpdatedFile)
|
||||
Console.WriteLine(x.Value);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.ControlFilesHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.ControlFile)
|
||||
Console.WriteLine(x.Value);
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("* " + Strings.Program.SymlinksHeader + ":");
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.RSync.RSyncDir.PatchFileType, string> x in files)
|
||||
if (x.Key == Duplicati.Library.Main.RSync.RSyncDir.PatchFileType.Symlink)
|
||||
Console.WriteLine(x.Value);
|
||||
}
|
||||
else if (source.Trim().ToLower() == "collection-status")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
List<Duplicati.Library.Main.ManifestEntry> entries = Duplicati.Library.Main.Interface.ParseFileList(cargs[0], options);
|
||||
|
||||
Console.WriteLine(Strings.Program.CollectionStatusHeader.Replace("\\t", "\t"), entries.Count);
|
||||
|
||||
foreach (Duplicati.Library.Main.ManifestEntry m in entries)
|
||||
{
|
||||
Console.WriteLine();
|
||||
|
||||
long size = Math.Max(m.Fileentry.Size ,0);
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.SignatureEntry, Duplicati.Library.Main.ContentEntry> x in m.Volumes)
|
||||
size += Math.Max(x.Key.Fileentry.Size, 0) + Math.Max(x.Value.Fileentry.Size, 0);
|
||||
|
||||
Console.WriteLine(Strings.Program.CollectionStatusLineFull.Replace("\\t", "\t"), m.Time.ToString(), m.Volumes.Count, Library.Utility.Utility.FormatSizeString(size));
|
||||
|
||||
foreach (Duplicati.Library.Main.ManifestEntry mi in m.Incrementals)
|
||||
{
|
||||
size = Math.Max(mi.Fileentry.Size, 0);
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.SignatureEntry, Duplicati.Library.Main.ContentEntry> x in mi.Volumes)
|
||||
size += Math.Max(x.Key.Fileentry.Size, 0) + Math.Max(x.Value.Fileentry.Size, 0);
|
||||
|
||||
Console.WriteLine(Strings.Program.CollectionStatusLineInc.Replace("\\t", "\t"), mi.Time.ToString(), mi.Volumes.Count, Library.Utility.Utility.FormatSizeString(size));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (source.Trim().ToLower() == "delete-all-but-n-full" || source.Trim().ToLower() == "delete-all-but-n")
|
||||
{
|
||||
int n = 0;
|
||||
if (!int.TryParse(target, out n) || n < 0)
|
||||
{
|
||||
Console.WriteLine(string.Format(Strings.Program.IntegerParseError, target));
|
||||
return 200;
|
||||
}
|
||||
|
||||
options["delete-all-but-n-full"] = n.ToString();
|
||||
|
||||
cargs.RemoveAt(0);
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
if (source.Trim().ToLower() == "delete-all-but-n")
|
||||
Console.WriteLine(Duplicati.Library.Main.Interface.DeleteAllButN(cargs[0], options));
|
||||
else
|
||||
Console.WriteLine(Duplicati.Library.Main.Interface.DeleteAllButNFull(cargs[0], options));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "delete-older-than")
|
||||
{
|
||||
try
|
||||
{
|
||||
Duplicati.Library.Utility.Timeparser.ParseTimeSpan(target);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format(Strings.Program.TimeParseError, target, ex.Message));
|
||||
return 200;
|
||||
}
|
||||
|
||||
options["delete-older-than"] = target;
|
||||
|
||||
cargs.RemoveAt(0);
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
Console.WriteLine(Duplicati.Library.Main.Interface.DeleteOlderThan(cargs[0], options));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "cleanup")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
Console.WriteLine(Duplicati.Library.Main.Interface.Cleanup(cargs[0], options));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "create-folder")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
Duplicati.Library.Main.Interface.CreateFolder(cargs[0], options);
|
||||
Console.WriteLine(string.Format(Strings.Program.FolderCreatedMessage, cargs[0]));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "find-last-version")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
List<KeyValuePair<string, DateTime>> results = Duplicati.Library.Main.Interface.FindLastFileVersion(cargs[0], options);
|
||||
Console.WriteLine(Strings.Program.FindLastVersionHeader.Replace("\\t", "\t"));
|
||||
foreach(KeyValuePair<string, DateTime> k in results)
|
||||
Console.WriteLine(string.Format(Strings.Program.FindLastVersionEntry.Replace("\\t", "\t"), k.Value.Ticks == 0 ? Strings.Program.FileEntryNotFound : k.Value.ToLocalTime().ToString("yyyyMMdd hhmmss"), k.Key));
|
||||
}
|
||||
else if (source.Trim().ToLower() == "verify")
|
||||
{
|
||||
cargs.RemoveAt(0);
|
||||
|
||||
if (cargs.Count != 1)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 1);
|
||||
return 200;
|
||||
}
|
||||
|
||||
List<KeyValuePair<Duplicati.Library.Main.BackupEntryBase, Exception>> results = Duplicati.Library.Main.Interface.VerifyBackup(cargs[0], options);
|
||||
|
||||
int manifests = 0;
|
||||
int signatures = 0;
|
||||
int contentfiles = 0;
|
||||
int errors = 0;
|
||||
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.BackupEntryBase, Exception> x in results)
|
||||
{
|
||||
if (x.Key is Duplicati.Library.Main.ManifestEntry)
|
||||
manifests++;
|
||||
else if (x.Key is Duplicati.Library.Main.SignatureEntry)
|
||||
signatures++;
|
||||
else if (x.Key is Duplicati.Library.Main.ContentEntry)
|
||||
contentfiles++;
|
||||
|
||||
if (x.Value != null)
|
||||
errors++;
|
||||
}
|
||||
|
||||
Console.WriteLine(string.Format(Strings.Program.VerificationCompleted, manifests, signatures, contentfiles, errors));
|
||||
if (errors > 0)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(Strings.Program.VerificationErrorHeader);
|
||||
Console.WriteLine();
|
||||
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.BackupEntryBase, Exception> x in results)
|
||||
if (x.Value != null)
|
||||
Console.WriteLine(string.Format("{0}: {1}", x.Key.Filename, x.Value.Message));
|
||||
}
|
||||
}
|
||||
else if (source.IndexOf("://") > 0 || options.ContainsKey("restore"))
|
||||
{
|
||||
if (cargs.Count != 2)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 2);
|
||||
return 200;
|
||||
}
|
||||
|
||||
Console.WriteLine(Duplicati.Library.Main.Interface.Restore(source, target.Split(System.IO.Path.PathSeparator), options));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cargs.Count != 2)
|
||||
{
|
||||
PrintWrongNumberOfArguments(cargs, 2);
|
||||
return 200;
|
||||
}
|
||||
|
||||
string result = Duplicati.Library.Main.Interface.Backup(source.Split(System.IO.Path.PathSeparator), target, options);
|
||||
Console.WriteLine(result);
|
||||
|
||||
Dictionary<string, string> tmp = ParseDuplicatiOutput(result);
|
||||
|
||||
//Interrupted = 50
|
||||
if (tmp.ContainsKey("PartialBackup"))
|
||||
return 50;
|
||||
|
||||
//Completed with warnings = 2
|
||||
if (tmp.ContainsKey("NumberOfWarnings"))
|
||||
return 2;
|
||||
|
||||
//Success, but no upload = 1
|
||||
if (tmp.ContainsKey("BytesUploaded"))
|
||||
{
|
||||
long s;
|
||||
if (long.TryParse(tmp["BytesUploaded"], out s) && s == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//Normal operation = 0
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
while (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
|
||||
ex = ex.InnerException;
|
||||
|
||||
if (!(ex is Library.Interface.CancelException))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ex.Message))
|
||||
{
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine(verboseErrors ? ex.ToString() : ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine(Strings.Program.UnhandledException, ex.ToString());
|
||||
|
||||
while (ex.InnerException != null)
|
||||
{
|
||||
ex = ex.InnerException;
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine(Strings.Program.UnhandledInnerException, ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
//Error = 100
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> ParseDuplicatiOutput(string output)
|
||||
{
|
||||
System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex("(?<key>[^\\:]+)\\:(?<value>[^\\n]*)", System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
Dictionary<string, string> res = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (System.Text.RegularExpressions.Match m in re.Matches(output))
|
||||
res[m.Groups["key"].Value.Trim()] = m.Groups["value"].Value.Trim();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static void PrintWrongNumberOfArguments(List<string> args, int expected)
|
||||
{
|
||||
Console.WriteLine(Strings.Program.WrongNumberOfCommandsError_v2, args.Count, expected, args.Count == 0 ? "" : "\"" + string.Join("\", \"", args.ToArray()) + "\"");
|
||||
}
|
||||
|
||||
public static IList<Library.Interface.ICommandLineArgument> SupportedCommands
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<Library.Interface.ICommandLineArgument>(new Library.Interface.ICommandLineArgument[] {
|
||||
new Library.Interface.CommandLineArgument("parameters-file", Library.Interface.CommandLineArgument.ArgumentType.Path, Strings.Program.ParametersFileOptionShort, Strings.Program.ParametersFileOptionLong, "", new string[] {"parameter-file"})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ReadOptionsFromFile(string filename, ref string filter, IList<string> cargs, Dictionary<string, string> options)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<string> fargs = new List<string>(Library.Utility.Utility.ReadFileWithDefaultEncoding(filename).Replace("\r", "").Split(new String[] { "\n" }, StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
string newfilter = Duplicati.Library.Utility.FilenameFilter.EncodeAsFilter(Duplicati.Library.Utility.FilenameFilter.ParseCommandLine(fargs, true));
|
||||
|
||||
// If the user specifies parameters-file, all filters must be in the file.
|
||||
// Allowing to specify some filters on the command line could result in wrong filter ordering
|
||||
if (!string.IsNullOrEmpty(filter) && !string.IsNullOrEmpty(newfilter))
|
||||
throw new Exception(Strings.Program.FiltersCannotBeUsedWithFileError);
|
||||
|
||||
filter = newfilter;
|
||||
|
||||
Dictionary<string, string> opt = Library.Utility.CommandLineParser.ExtractOptions(fargs);
|
||||
String newsource = null, newtarget = null;
|
||||
foreach (KeyValuePair<String, String> keyvalue in opt)
|
||||
{
|
||||
switch (keyvalue.Key.ToLower())
|
||||
{
|
||||
// This replaces any previous value, file parameters take precedence;
|
||||
case "source":
|
||||
newsource = keyvalue.Value;
|
||||
break;
|
||||
case "target":
|
||||
newtarget = keyvalue.Value;
|
||||
break;
|
||||
default:
|
||||
options[keyvalue.Key] = keyvalue.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When the action is to backup, allow the source and/or the target
|
||||
// to be specified in the parameters file as --source= and --target=.
|
||||
// Note: this block is faily complex due to the way parameters are handled by the rest of the
|
||||
// procedure. It could likely be much simpler and versatile (allow --source and --target on
|
||||
// restore or other actions) with some refactoring of the parameters decision tree
|
||||
if (!String.IsNullOrEmpty(newsource) || !String.IsNullOrEmpty(newtarget))
|
||||
{
|
||||
int offset = cargs.Count > 0 && (cargs[0] == "backup" || cargs[0] == "restore") ? 1 : 0;
|
||||
bool isrestore = cargs.Count > 0 && cargs[0] == "restore"
|
||||
|| cargs.Count >= 2 && cargs[0].Contains("://");
|
||||
|
||||
if (cargs.Count == 0 + offset)
|
||||
{
|
||||
// if either is empty loading will fail later, so we don't really care.
|
||||
if (!String.IsNullOrEmpty(newsource)) cargs.Add(newsource);
|
||||
if (!String.IsNullOrEmpty(newtarget)) cargs.Add(newtarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isurl = cargs[offset].Contains("://");
|
||||
bool isdir = !isurl && cargs[offset].IndexOfAny(new char[] { '/', '\\', ':' }) >= 0;
|
||||
if (offset > 0 || isdir || isurl)
|
||||
{
|
||||
if (cargs.Count == 1 + offset)
|
||||
{
|
||||
if (isrestore ^ isurl)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(newtarget)) cargs[offset] = newtarget;
|
||||
if (!String.IsNullOrEmpty(newsource)) cargs.Insert(offset, newsource);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.IsNullOrEmpty(newtarget)) cargs[offset] = newsource;
|
||||
if (!String.IsNullOrEmpty(newsource)) cargs.Add(newtarget);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.IsNullOrEmpty(newsource)) cargs[offset] = newsource;
|
||||
if (!String.IsNullOrEmpty(newtarget)) cargs[offset + 1] = newtarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(Strings.Program.FailedToParseParametersFileError, filename, e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintOldUsage(bool extended)
|
||||
{
|
||||
bool isLinux = Library.Utility.Utility.IsClientLinux;
|
||||
|
||||
List<string> lines = new List<string>();
|
||||
lines.AddRange(
|
||||
string.Format(
|
||||
Strings.Program.ProgramUsageHeader.Replace("\r", ""),
|
||||
License.VersionNumbers.Version
|
||||
).Split('\n')
|
||||
);
|
||||
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageBackup.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageRestore.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageCleanup.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageListFiles.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageListSets.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageListContentFiles.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageListSourceFolders.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageListSignatureFiles.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageFindLastVersion.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageVerify.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsagePurgeCache.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageDeleteOld.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageCreateFolders.Replace("\r", "")).Split('\n'));
|
||||
|
||||
lines.AddRange(("\n " + Strings.Program.ProgramUsageBackend.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n" + Strings.Program.ProgramUsageOptionTypes.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(("\n" + Strings.Program.ProgramUsageTimes.Replace("\r", "")).Split('\n'));
|
||||
lines.AddRange(
|
||||
string.Format(
|
||||
"\n" + Strings.Program.ProgramUsageFilters.Replace("\r", ""),
|
||||
isLinux ? Strings.Program.UsageExampleLinux : Strings.Program.UsageExampleWindows
|
||||
).Split('\n')
|
||||
);
|
||||
|
||||
lines.Add("");
|
||||
|
||||
if (extended)
|
||||
{
|
||||
|
||||
lines.Add(Strings.Program.DuplicatiOptionsHeader);
|
||||
Library.Main.Options opt = new Library.Main.Options(new Dictionary<string, string>());
|
||||
foreach (Library.Interface.ICommandLineArgument arg in opt.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg);
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.SupportedBackendsHeader);
|
||||
foreach (Duplicati.Library.Interface.IBackend back in Library.DynamicLoader.BackendLoader.Backends)
|
||||
{
|
||||
lines.Add(back.DisplayName + " (" + back.ProtocolKey + "):");
|
||||
lines.Add(" " + back.Description);
|
||||
if (back.SupportedCommands != null && back.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in back.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg);
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.SupportedEncryptionModulesHeader);
|
||||
foreach (Duplicati.Library.Interface.IEncryption mod in Library.DynamicLoader.EncryptionLoader.Modules)
|
||||
{
|
||||
lines.Add(mod.DisplayName + " (." + mod.FilenameExtension + "):");
|
||||
lines.Add(" " + mod.Description);
|
||||
if (mod.SupportedCommands != null && mod.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in mod.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg);
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.SupportedCompressionModulesHeader);
|
||||
foreach (Duplicati.Library.Interface.ICompression mod in Library.DynamicLoader.CompressionLoader.Modules)
|
||||
{
|
||||
lines.Add(mod.DisplayName + " (." + mod.FilenameExtension + "):");
|
||||
lines.Add(" " + mod.Description);
|
||||
if (mod.SupportedCommands != null && mod.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in mod.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg);
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
lines.Add("");
|
||||
|
||||
lines.Add("");
|
||||
lines.Add("");
|
||||
lines.Add(Strings.Program.GenericModulesHeader);
|
||||
foreach (Duplicati.Library.Interface.IGenericModule mod in Library.DynamicLoader.GenericLoader.Modules)
|
||||
{
|
||||
lines.Add(mod.DisplayName + " (." + mod.Key + "):");
|
||||
lines.Add(" " + mod.Description);
|
||||
lines.Add(" " + (mod.LoadAsDefault ? Strings.Program.ModuleIsLoadedAutomatically : Strings.Program.ModuleIsNotLoadedAutomatically));
|
||||
if (mod.SupportedCommands != null && mod.SupportedCommands.Count > 0)
|
||||
{
|
||||
lines.Add(" " + Strings.Program.SupportedOptionsHeader);
|
||||
foreach (Library.Interface.ICommandLineArgument arg in mod.SupportedCommands)
|
||||
Library.Interface.CommandLineArgument.PrintArgument(lines, arg);
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
foreach (string s in lines)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
Console.WriteLine();
|
||||
continue;
|
||||
}
|
||||
|
||||
string c = s;
|
||||
|
||||
string leadingSpaces = "";
|
||||
while (c.Length > 0 && c.StartsWith(" "))
|
||||
{
|
||||
leadingSpaces += " ";
|
||||
c = c.Remove(0, 1);
|
||||
}
|
||||
|
||||
while (c.Length > 0)
|
||||
{
|
||||
int len = Math.Min(Console.WindowWidth - 2, leadingSpaces.Length + c.Length);
|
||||
len -= leadingSpaces.Length;
|
||||
if (len < c.Length)
|
||||
{
|
||||
int ix = c.LastIndexOf(" ", len);
|
||||
if (ix > 0)
|
||||
len = ix;
|
||||
}
|
||||
|
||||
Console.WriteLine(leadingSpaces + c.Substring(0, len).Trim());
|
||||
c = c.Remove(0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("Duplicati.CommandLine")]
|
||||
[assembly: AssemblyDescription("A commandline version of Duplicati")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("Duplicati.CommandLine")]
|
||||
[assembly: AssemblyCopyright("LGPL, Copyright © HexaD 2010")]
|
||||
[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("bfc1d214-8825-417d-8e2c-be4bb0d6524d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.1.276")]
|
||||
[assembly: AssemblyFileVersion("1.0.1.276")]
|
||||
@@ -0,0 +1,3 @@
|
||||
cd bin\Debug
|
||||
Duplicati.CommandLine.exe UNITTEST DSMCBE\r50 DSMCBE\r100 DSMCBE\r150 DSMCBE\r200 DSMCBE\r250 DSMCBE\r251 DSMCBE\r252 DSMCBE\r253 DSMCBE\r254 DSMCBE\r255 DSMCBE\r256 DSMCBE\r257 DSMCBE\r258 DSMCBE\r259 DSMCBE\r260
|
||||
pause
|
||||
@@ -0,0 +1,3 @@
|
||||
cd bin\Debug
|
||||
Duplicati.CommandLine.exe UNITTEST MapGuide\r100 MapGuide\r1000 MapGuide\r2000 MapGuide\r3000 MapGuide\r3100 MapGuide\r3200
|
||||
pause
|
||||
+607
@@ -0,0 +1,607 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.296
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Duplicati.CommandLine.Strings {
|
||||
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 Program {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Program() {
|
||||
}
|
||||
|
||||
/// <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("Duplicati.CommandLine.Strings.Program", typeof(Program).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 Added folders.
|
||||
/// </summary>
|
||||
internal static string AddedFoldersHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("AddedFoldersHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Found {0} backup chains on backend
|
||||
///
|
||||
///Type\tTime\t\t\tVolumes\tSize.
|
||||
/// </summary>
|
||||
internal static string CollectionStatusHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("CollectionStatusHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Full\t{0}\t{1}\t{2}.
|
||||
/// </summary>
|
||||
internal static string CollectionStatusLineFull {
|
||||
get {
|
||||
return ResourceManager.GetString("CollectionStatusLineFull", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Inc\t{0}\t{1}\t{2}.
|
||||
/// </summary>
|
||||
internal static string CollectionStatusLineInc {
|
||||
get {
|
||||
return ResourceManager.GetString("CollectionStatusLineInc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Control files.
|
||||
/// </summary>
|
||||
internal static string ControlFilesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("ControlFilesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Deleted files.
|
||||
/// </summary>
|
||||
internal static string DeletedFilesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("DeletedFilesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Deleted folders.
|
||||
/// </summary>
|
||||
internal static string DeletedFoldersHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("DeletedFoldersHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Duplicati options:.
|
||||
/// </summary>
|
||||
internal static string DuplicatiOptionsHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("DuplicatiOptionsHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to read the parameters file "{0}", reason: {1}.
|
||||
/// </summary>
|
||||
internal static string FailedToParseParametersFileError {
|
||||
get {
|
||||
return ResourceManager.GetString("FailedToParseParametersFileError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to < not found >.
|
||||
/// </summary>
|
||||
internal static string FileEntryNotFound {
|
||||
get {
|
||||
return ResourceManager.GetString("FileEntryNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Filters cannot be specified on the commandline if filters are also present in the parameter file.
|
||||
/// </summary>
|
||||
internal static string FiltersCannotBeUsedWithFileError {
|
||||
get {
|
||||
return ResourceManager.GetString("FiltersCannotBeUsedWithFileError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0}\t{1}.
|
||||
/// </summary>
|
||||
internal static string FindLastVersionEntry {
|
||||
get {
|
||||
return ResourceManager.GetString("FindLastVersionEntry", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Backuptime\t\tFilename.
|
||||
/// </summary>
|
||||
internal static string FindLastVersionHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("FindLastVersionHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The folder {0} was created.
|
||||
/// </summary>
|
||||
internal static string FolderCreatedMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("FolderCreatedMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supported generic modules:.
|
||||
/// </summary>
|
||||
internal static string GenericModulesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("GenericModulesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to parse "{0}" into a number.
|
||||
/// </summary>
|
||||
internal static string IntegerParseError {
|
||||
get {
|
||||
return ResourceManager.GetString("IntegerParseError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The option --{0} was supplied, but it is reserved for internal use and may not be set on the commandline.
|
||||
/// </summary>
|
||||
internal static string InternalOptionUsedError {
|
||||
get {
|
||||
return ResourceManager.GetString("InternalOptionUsedError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Modified files.
|
||||
/// </summary>
|
||||
internal static string ModifiedFilesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("ModifiedFilesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Module is loaded atomatically, use --disable-module to prevent this.
|
||||
/// </summary>
|
||||
internal static string ModuleIsLoadedAutomatically {
|
||||
get {
|
||||
return ResourceManager.GetString("ModuleIsLoadedAutomatically", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Module is not loaded atomatically, use --enable-module to load it.
|
||||
/// </summary>
|
||||
internal static string ModuleIsNotLoadedAutomatically {
|
||||
get {
|
||||
return ResourceManager.GetString("ModuleIsNotLoadedAutomatically", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New files.
|
||||
/// </summary>
|
||||
internal static string NewFilesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("NewFilesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New/Modified files.
|
||||
/// </summary>
|
||||
internal static string NewOrModifiedFilesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("NewOrModifiedFilesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This option can be used to store some or all of the options given to the commandline client. The file must be a plain text file, UTF-8 encoding is preferred. Each line in the file should be of the format --option=value. The special options --source and --target can be used to override the localpath and the remote destination uri, respectively. The options in this file take precedence over the options provided on the commandline. You cannot specify filters in both the file and on the commandline..
|
||||
/// </summary>
|
||||
internal static string ParametersFileOptionLong {
|
||||
get {
|
||||
return ResourceManager.GetString("ParametersFileOptionLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Path to a file with parameters.
|
||||
/// </summary>
|
||||
internal static string ParametersFileOptionShort {
|
||||
get {
|
||||
return ResourceManager.GetString("ParametersFileOptionShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A <backend> is identified by an url like ftp://host/ or ssh://server/.
|
||||
/// Using this system, Duplicati can detect if you want to backup or restore.
|
||||
/// The cleanup and delete commands do not delete files, unless the --force option is specified, so you may examine what files are affected, before actually deleting the files.
|
||||
/// The cleanup command should not be used unless a backup was interrupted and has left partial files. Duplicati will inform you if this happens.
|
||||
/// The delete command can be used to remove bac [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageBackend {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageBackend", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Backup (make a full or incremental backup):
|
||||
/// Duplicati.CommandLine [full] [options] <sourcefolder> <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageBackup {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageBackup", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cleanup (remove partial and unused files):
|
||||
/// Duplicati.CommandLine cleanup [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageCleanup {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageCleanup", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Create folder (usually done automatically):
|
||||
/// Duplicati.CommandLine create-folder [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageCreateFolders {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageCreateFolders", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete old backups:
|
||||
/// Duplicati.CommandLine delete-all-but-n-full <number of full backups to keep> [options] <backend>
|
||||
/// Duplicati.CommandLine delete-older-than <max allowed age> [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageDeleteOld {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageDeleteOld", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Filters:
|
||||
/// Duplicati uses filters to include and exclude files.
|
||||
/// Duplicati uses a "first-touch" filter where the first rule that matches a file determines if the file is included or excluded. Internally Duplicati uses regular expression filters, but supports filters in the form of filename globbing. The order of the commandline arguments also determine what order they are applied in. An example:
|
||||
/// --include=*.txt --exclude=*\Thumbs.db --include=*
|
||||
///
|
||||
/// Even though the last filter includes everything, no [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageFilters {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageFilters", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Find the last version of a file:
|
||||
/// Duplicati.CommandLine find-last-version [options] --file-to-restore=<files to find> <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageFindLastVersion {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageFindLastVersion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ********** Duplicati v. {0} **********
|
||||
///
|
||||
///Usage:.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List content files (files that can be restored):
|
||||
/// Duplicati.CommandLine list-current-files [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageListContentFiles {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageListContentFiles", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List files:
|
||||
/// Duplicati.CommandLine list [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageListFiles {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageListFiles", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List backup sets:
|
||||
/// Duplicati.CommandLine collection-status [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageListSets {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageListSets", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List signature files (files in a single backup volume set):
|
||||
/// Duplicati.CommandLine list-actual-signature-files [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageListSignatureFiles {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageListSignatureFiles", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List source folders (folders backed up from):
|
||||
/// Duplicati.CommandLine list-source-folders [options] <backend>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageListSourceFolders {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageListSourceFolders", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Option types:
|
||||
/// The following option types are available:
|
||||
/// Integer: a numerical value
|
||||
/// Boolean: a truth value, --force and --force=true are equivalent. --force=false is the opposite
|
||||
/// Timespan: a time in the special time format (explained below)
|
||||
/// Size: a size like 5mb or 200kb
|
||||
/// Enumeration: any of the listed values
|
||||
/// Path: the path to a folder or file
|
||||
/// String: any other type.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageOptionTypes {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageOptionTypes", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Purge signature cache:
|
||||
/// Duplicati.CommandLine purge-signature-cache [options].
|
||||
/// </summary>
|
||||
internal static string ProgramUsagePurgeCache {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsagePurgeCache", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Restore (restore all or some files):
|
||||
/// Duplicati.CommandLine [options] <backend> <destinationfolder>.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageRestore {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageRestore", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Times:
|
||||
/// Duplicati uses the time system from duplicity, where times may be presented as:
|
||||
/// 1: the string "now", indicating the current time
|
||||
/// 2: the number of seconds after epoch, eg: 123456890
|
||||
/// 3: a string like "2009-03-26T08:30:00+01:00"
|
||||
/// 4: an interval string, using Y, M, W, D, h, m, s for Year, Month, Week, Day, hour, minute or second, eg: "1M4D" for one month and four days, or "5m" for five minutes..
|
||||
/// </summary>
|
||||
internal static string ProgramUsageTimes {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageTimes", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Verify backup integrity:
|
||||
/// Duplicati.CommandLine verify <backend> --verification-level=manifest|signatures|full.
|
||||
/// </summary>
|
||||
internal static string ProgramUsageVerify {
|
||||
get {
|
||||
return ResourceManager.GetString("ProgramUsageVerify", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supported backends:.
|
||||
/// </summary>
|
||||
internal static string SupportedBackendsHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("SupportedBackendsHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supported compression modules:.
|
||||
/// </summary>
|
||||
internal static string SupportedCompressionModulesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("SupportedCompressionModulesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supported encryption modules:.
|
||||
/// </summary>
|
||||
internal static string SupportedEncryptionModulesHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("SupportedEncryptionModulesHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supported options:.
|
||||
/// </summary>
|
||||
internal static string SupportedOptionsHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("SupportedOptionsHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Symbolic links.
|
||||
/// </summary>
|
||||
internal static string SymlinksHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("SymlinksHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to parse "{0}" into a time offset: {1}.
|
||||
/// </summary>
|
||||
internal static string TimeParseError {
|
||||
get {
|
||||
return ResourceManager.GetString("TimeParseError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An error occured: {0}.
|
||||
/// </summary>
|
||||
internal static string UnhandledException {
|
||||
get {
|
||||
return ResourceManager.GetString("UnhandledException", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The inner error message is: {0}.
|
||||
/// </summary>
|
||||
internal static string UnhandledInnerException {
|
||||
get {
|
||||
return ResourceManager.GetString("UnhandledInnerException", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Duplicati.CommandLine /home/user/ ftp://host/folder --exclude=/file.txt
|
||||
///
|
||||
/// In this example the file "/home/user/file.txt" is excluded..
|
||||
/// </summary>
|
||||
internal static string UsageExampleLinux {
|
||||
get {
|
||||
return ResourceManager.GetString("UsageExampleLinux", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Duplicati.CommandLine C:\Documents\Files ftp://host/folder --exclude=\file.txt
|
||||
///
|
||||
/// In this example the file "C:\Documents\Files\file.txt" is excluded..
|
||||
/// </summary>
|
||||
internal static string UsageExampleWindows {
|
||||
get {
|
||||
return ResourceManager.GetString("UsageExampleWindows", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Verification completed, summary:
|
||||
///Manifest files verified: {0}
|
||||
///Signature files verified: {1}
|
||||
///Content files verified: {2}
|
||||
///Errors: {3}.
|
||||
/// </summary>
|
||||
internal static string VerificationCompleted {
|
||||
get {
|
||||
return ResourceManager.GetString("VerificationCompleted", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Reported error messages:.
|
||||
/// </summary>
|
||||
internal static string VerificationErrorHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("VerificationErrorHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Found {0} commands but expected {1}, commands:
|
||||
///{2}.
|
||||
/// </summary>
|
||||
internal static string WrongNumberOfCommandsError_v2 {
|
||||
get {
|
||||
return ResourceManager.GetString("WrongNumberOfCommandsError_v2", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
<?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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AddedFoldersHeader" xml:space="preserve">
|
||||
<value>Added folders</value>
|
||||
</data>
|
||||
<data name="CollectionStatusHeader" xml:space="preserve">
|
||||
<value>Found {0} backup chains on backend
|
||||
|
||||
Type\tTime\t\t\tVolumes\tSize</value>
|
||||
</data>
|
||||
<data name="CollectionStatusLineFull" xml:space="preserve">
|
||||
<value>Full\t{0}\t{1}\t{2}</value>
|
||||
</data>
|
||||
<data name="CollectionStatusLineInc" xml:space="preserve">
|
||||
<value> Inc\t{0}\t{1}\t{2}</value>
|
||||
</data>
|
||||
<data name="ControlFilesHeader" xml:space="preserve">
|
||||
<value>Control files</value>
|
||||
</data>
|
||||
<data name="DeletedFilesHeader" xml:space="preserve">
|
||||
<value>Deleted files</value>
|
||||
</data>
|
||||
<data name="DeletedFoldersHeader" xml:space="preserve">
|
||||
<value>Deleted folders</value>
|
||||
</data>
|
||||
<data name="DuplicatiOptionsHeader" xml:space="preserve">
|
||||
<value>Duplicati options:</value>
|
||||
</data>
|
||||
<data name="FailedToParseParametersFileError" xml:space="preserve">
|
||||
<value>Unable to read the parameters file "{0}", reason: {1}</value>
|
||||
</data>
|
||||
<data name="FileEntryNotFound" xml:space="preserve">
|
||||
<value>< not found ></value>
|
||||
</data>
|
||||
<data name="FiltersCannotBeUsedWithFileError" xml:space="preserve">
|
||||
<value>Filters cannot be specified on the commandline if filters are also present in the parameter file</value>
|
||||
</data>
|
||||
<data name="FindLastVersionEntry" xml:space="preserve">
|
||||
<value>{0}\t{1}</value>
|
||||
</data>
|
||||
<data name="FindLastVersionHeader" xml:space="preserve">
|
||||
<value>Backuptime\t\tFilename</value>
|
||||
</data>
|
||||
<data name="FolderCreatedMessage" xml:space="preserve">
|
||||
<value>The folder {0} was created</value>
|
||||
</data>
|
||||
<data name="GenericModulesHeader" xml:space="preserve">
|
||||
<value>Supported generic modules:</value>
|
||||
</data>
|
||||
<data name="IntegerParseError" xml:space="preserve">
|
||||
<value>Unable to parse "{0}" into a number</value>
|
||||
</data>
|
||||
<data name="InternalOptionUsedError" xml:space="preserve">
|
||||
<value>The option --{0} was supplied, but it is reserved for internal use and may not be set on the commandline</value>
|
||||
</data>
|
||||
<data name="ModifiedFilesHeader" xml:space="preserve">
|
||||
<value>Modified files</value>
|
||||
</data>
|
||||
<data name="ModuleIsLoadedAutomatically" xml:space="preserve">
|
||||
<value>Module is loaded atomatically, use --disable-module to prevent this</value>
|
||||
</data>
|
||||
<data name="ModuleIsNotLoadedAutomatically" xml:space="preserve">
|
||||
<value>Module is not loaded atomatically, use --enable-module to load it</value>
|
||||
</data>
|
||||
<data name="NewFilesHeader" xml:space="preserve">
|
||||
<value>New files</value>
|
||||
</data>
|
||||
<data name="NewOrModifiedFilesHeader" xml:space="preserve">
|
||||
<value>New/Modified files</value>
|
||||
</data>
|
||||
<data name="ParametersFileOptionLong" xml:space="preserve">
|
||||
<value>This option can be used to store some or all of the options given to the commandline client. The file must be a plain text file, UTF-8 encoding is preferred. Each line in the file should be of the format --option=value. The special options --source and --target can be used to override the localpath and the remote destination uri, respectively. The options in this file take precedence over the options provided on the commandline. You cannot specify filters in both the file and on the commandline.</value>
|
||||
</data>
|
||||
<data name="ParametersFileOptionShort" xml:space="preserve">
|
||||
<value>Path to a file with parameters</value>
|
||||
</data>
|
||||
<data name="ProgramUsageBackend" xml:space="preserve">
|
||||
<value>A <backend> is identified by an url like ftp://host/ or ssh://server/.
|
||||
Using this system, Duplicati can detect if you want to backup or restore.
|
||||
The cleanup and delete commands do not delete files, unless the --force option is specified, so you may examine what files are affected, before actually deleting the files.
|
||||
The cleanup command should not be used unless a backup was interrupted and has left partial files. Duplicati will inform you if this happens.
|
||||
The delete command can be used to remove backup sets when newer backups are present.</value>
|
||||
</data>
|
||||
<data name="ProgramUsageBackup" xml:space="preserve">
|
||||
<value>Backup (make a full or incremental backup):
|
||||
Duplicati.CommandLine [full] [options] <sourcefolder> <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageCleanup" xml:space="preserve">
|
||||
<value>Cleanup (remove partial and unused files):
|
||||
Duplicati.CommandLine cleanup [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageCreateFolders" xml:space="preserve">
|
||||
<value>Create folder (usually done automatically):
|
||||
Duplicati.CommandLine create-folder [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageDeleteOld" xml:space="preserve">
|
||||
<value>Delete old backups:
|
||||
Duplicati.CommandLine delete-all-but-n-full <number of full backups to keep> [options] <backend>
|
||||
Duplicati.CommandLine delete-older-than <max allowed age> [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageFilters" xml:space="preserve">
|
||||
<value>Filters:
|
||||
Duplicati uses filters to include and exclude files.
|
||||
Duplicati uses a "first-touch" filter where the first rule that matches a file determines if the file is included or excluded. Internally Duplicati uses regular expression filters, but supports filters in the form of filename globbing. The order of the commandline arguments also determine what order they are applied in. An example:
|
||||
--include=*.txt --exclude=*\Thumbs.db --include=*
|
||||
|
||||
Even though the last filter includes everything, no files named "Thumbs.db" are included because they match the exclude rule before the include rule. Paths are evaluated in full, and as paths that are relative to folder being backed up, but including a leading slash. An example:
|
||||
|
||||
{0}
|
||||
If a folder is excluded, files in that folder are always excluded, even if there are filters that include files in that folder. If a folder is included with a wildcard at the end, all files are included, if the folder is included without a wildcard, files may be excluded or included with extra rules.</value>
|
||||
</data>
|
||||
<data name="ProgramUsageFindLastVersion" xml:space="preserve">
|
||||
<value>Find the last version of a file:
|
||||
Duplicati.CommandLine find-last-version [options] --file-to-restore=<files to find> <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageHeader" xml:space="preserve">
|
||||
<value>********** Duplicati v. {0} **********
|
||||
|
||||
Usage:</value>
|
||||
</data>
|
||||
<data name="ProgramUsageListContentFiles" xml:space="preserve">
|
||||
<value>List content files (files that can be restored):
|
||||
Duplicati.CommandLine list-current-files [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageListFiles" xml:space="preserve">
|
||||
<value>List files:
|
||||
Duplicati.CommandLine list [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageListSets" xml:space="preserve">
|
||||
<value>List backup sets:
|
||||
Duplicati.CommandLine collection-status [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageListSignatureFiles" xml:space="preserve">
|
||||
<value>List signature files (files in a single backup volume set):
|
||||
Duplicati.CommandLine list-actual-signature-files [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageListSourceFolders" xml:space="preserve">
|
||||
<value>List source folders (folders backed up from):
|
||||
Duplicati.CommandLine list-source-folders [options] <backend></value>
|
||||
</data>
|
||||
<data name="ProgramUsageOptionTypes" xml:space="preserve">
|
||||
<value>Option types:
|
||||
The following option types are available:
|
||||
Integer: a numerical value
|
||||
Boolean: a truth value, --force and --force=true are equivalent. --force=false is the opposite
|
||||
Timespan: a time in the special time format (explained below)
|
||||
Size: a size like 5mb or 200kb
|
||||
Enumeration: any of the listed values
|
||||
Path: the path to a folder or file
|
||||
String: any other type</value>
|
||||
</data>
|
||||
<data name="ProgramUsagePurgeCache" xml:space="preserve">
|
||||
<value>Purge signature cache:
|
||||
Duplicati.CommandLine purge-signature-cache [options]</value>
|
||||
</data>
|
||||
<data name="ProgramUsageRestore" xml:space="preserve">
|
||||
<value>Restore (restore all or some files):
|
||||
Duplicati.CommandLine [options] <backend> <destinationfolder></value>
|
||||
</data>
|
||||
<data name="ProgramUsageTimes" xml:space="preserve">
|
||||
<value>Times:
|
||||
Duplicati uses the time system from duplicity, where times may be presented as:
|
||||
1: the string "now", indicating the current time
|
||||
2: the number of seconds after epoch, eg: 123456890
|
||||
3: a string like "2009-03-26T08:30:00+01:00"
|
||||
4: an interval string, using Y, M, W, D, h, m, s for Year, Month, Week, Day, hour, minute or second, eg: "1M4D" for one month and four days, or "5m" for five minutes.</value>
|
||||
</data>
|
||||
<data name="ProgramUsageVerify" xml:space="preserve">
|
||||
<value>Verify backup integrity:
|
||||
Duplicati.CommandLine verify <backend> --verification-level=manifest|signatures|full</value>
|
||||
</data>
|
||||
<data name="SupportedBackendsHeader" xml:space="preserve">
|
||||
<value>Supported backends:</value>
|
||||
</data>
|
||||
<data name="SupportedCompressionModulesHeader" xml:space="preserve">
|
||||
<value>Supported compression modules:</value>
|
||||
</data>
|
||||
<data name="SupportedEncryptionModulesHeader" xml:space="preserve">
|
||||
<value>Supported encryption modules:</value>
|
||||
</data>
|
||||
<data name="SupportedOptionsHeader" xml:space="preserve">
|
||||
<value>Supported options:</value>
|
||||
</data>
|
||||
<data name="SymlinksHeader" xml:space="preserve">
|
||||
<value>Symbolic links</value>
|
||||
</data>
|
||||
<data name="TimeParseError" xml:space="preserve">
|
||||
<value>Unable to parse "{0}" into a time offset: {1}</value>
|
||||
</data>
|
||||
<data name="UnhandledException" xml:space="preserve">
|
||||
<value>An error occured: {0}</value>
|
||||
</data>
|
||||
<data name="UnhandledInnerException" xml:space="preserve">
|
||||
<value>The inner error message is: {0}</value>
|
||||
</data>
|
||||
<data name="UsageExampleLinux" xml:space="preserve">
|
||||
<value>Duplicati.CommandLine /home/user/ ftp://host/folder --exclude=/file.txt
|
||||
|
||||
In this example the file "/home/user/file.txt" is excluded.</value>
|
||||
</data>
|
||||
<data name="UsageExampleWindows" xml:space="preserve">
|
||||
<value>Duplicati.CommandLine C:\Documents\Files ftp://host/folder --exclude=\file.txt
|
||||
|
||||
In this example the file "C:\Documents\Files\file.txt" is excluded.</value>
|
||||
</data>
|
||||
<data name="VerificationCompleted" xml:space="preserve">
|
||||
<value>Verification completed, summary:
|
||||
Manifest files verified: {0}
|
||||
Signature files verified: {1}
|
||||
Content files verified: {2}
|
||||
Errors: {3}</value>
|
||||
</data>
|
||||
<data name="VerificationErrorHeader" xml:space="preserve">
|
||||
<value>Reported error messages:</value>
|
||||
</data>
|
||||
<data name="WrongNumberOfCommandsError_v2" xml:space="preserve">
|
||||
<value>Found {0} commands but expected {1}, commands:
|
||||
{2}</value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,524 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
|
||||
#if DEBUG
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Duplicati.Library.Logging;
|
||||
using Duplicati.Library.Utility;
|
||||
|
||||
namespace Duplicati.CommandLine
|
||||
{
|
||||
/// <summary>
|
||||
/// This class encapsulates a simple method for testing the correctness of duplicati.
|
||||
/// </summary>
|
||||
public class UnitTest
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class to write debug messages to the log file
|
||||
/// </summary>
|
||||
private class LogHelper : StreamLog
|
||||
{
|
||||
private string m_backupset;
|
||||
|
||||
public string Backupset
|
||||
{
|
||||
get { return m_backupset; }
|
||||
set { m_backupset = value; }
|
||||
}
|
||||
|
||||
public LogHelper(string file)
|
||||
: base(file)
|
||||
{
|
||||
this.Backupset = "none";
|
||||
}
|
||||
|
||||
public override void WriteMessage(string message, LogMessageType type, Exception exception)
|
||||
{
|
||||
base.WriteMessage(this.Backupset + ", " + message, type, exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Running the unit test confirms the correctness of duplicati
|
||||
/// </summary>
|
||||
/// <param name="folders">The folders to backup. Folder at index 0 is the base, all others are incrementals</param>
|
||||
public static void RunTest(string[] folders, Dictionary<string, string> options)
|
||||
{
|
||||
//Place a file called "unittest_target.txt" in the bin folder, and enter a connection string like "ftp://username:password@example.com"
|
||||
|
||||
string ftp_password = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "unittest_ftppassword.txt");
|
||||
if (System.IO.File.Exists(ftp_password))
|
||||
options["ftp-password"] = System.IO.File.ReadAllText(ftp_password).Trim();
|
||||
|
||||
string alttarget = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "unittest_target.txt");
|
||||
if (System.IO.File.Exists(alttarget))
|
||||
RunTest(folders, options, System.IO.File.ReadAllText(alttarget).Trim());
|
||||
else
|
||||
RunTest(folders, options, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Running the unit test confirms the correctness of duplicati
|
||||
/// </summary>
|
||||
/// <param name="folders">The folders to backup. Folder at index 0 is the base, all others are incrementals</param>
|
||||
/// <param name="target">The target destination for the backups</param>
|
||||
public static void RunTest(string[] folders, Dictionary<string, string> options, string target)
|
||||
{
|
||||
LogHelper log = new LogHelper("unittest.log");
|
||||
Log.CurrentLog = log; ;
|
||||
Log.LogLevel = Duplicati.Library.Logging.LogMessageType.Profiling;
|
||||
|
||||
string tempdir = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "tempdir");
|
||||
|
||||
try
|
||||
{
|
||||
if (System.IO.Directory.Exists(tempdir))
|
||||
System.IO.Directory.Delete(tempdir, true);
|
||||
|
||||
System.IO.Directory.CreateDirectory(tempdir);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.WriteMessage("Failed to clean tempdir", LogMessageType.Error, ex);
|
||||
}
|
||||
|
||||
Duplicati.Library.Utility.TempFolder.SystemTempPath = tempdir;
|
||||
|
||||
//Set some defaults
|
||||
if (!options.ContainsKey("passphrase"))
|
||||
options["passphrase"] = "secret password!";
|
||||
|
||||
if (!options.ContainsKey("backup-prefix"))
|
||||
options["backup-prefix"] = "duplicati_unittest";
|
||||
|
||||
//This would break the test, because the data is not modified the normal way
|
||||
options["disable-filetime-check"] = "true";
|
||||
//We do not use the same folder, so we need this option
|
||||
options["allow-sourcefolder-change"] = "true";
|
||||
//We want all messages in the log
|
||||
options["log-level"] = LogMessageType.Profiling.ToString();
|
||||
//We cannot rely on USN numbering, but we can use USN enumeration
|
||||
//options["disable-usn-diff-check"] = "true";
|
||||
|
||||
//We use precise times
|
||||
options["disable-time-tolerance"] = "true";
|
||||
|
||||
options["verification-level"] = "full";
|
||||
|
||||
//We need all sets, even if they are unchanged
|
||||
options["upload-unchanged-backups"] = "true";
|
||||
|
||||
using(new Timer("Total unittest"))
|
||||
using(TempFolder tf = new TempFolder())
|
||||
{
|
||||
//The code below tests for a race condition in the ssh backend.
|
||||
/*string[] list = null;
|
||||
string[] prevList = null;
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
Console.WriteLine(string.Format("Listing, test {0}", i));
|
||||
list = Duplicati.Library.Main.Interface.List(target, options);
|
||||
if (i != 0 && list.Length != prevList.Length)
|
||||
Console.WriteLine(string.Format("Count mismatch {0} vs {1}", list.Length, prevList.Length));
|
||||
|
||||
prevList = list;
|
||||
}*/
|
||||
|
||||
if (options.ContainsKey("fh-dbpath"))
|
||||
{
|
||||
options["fh-dbpath"] = System.IO.Path.Combine(tempdir, "fh-unittest.sqlite");
|
||||
if (System.IO.File.Exists(options["fh-dbpath"]))
|
||||
System.IO.File.Delete(options["fh-dbpath"]);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(target))
|
||||
{
|
||||
target = "file://" + tf;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Removing old backups");
|
||||
Dictionary<string, string> tmp = new Dictionary<string, string>(options);
|
||||
tmp["delete-all-but-n-full"] = "0";
|
||||
tmp["force"] = "";
|
||||
tmp["allow-full-removal"] = "";
|
||||
|
||||
using (new Timer("Cleaning up any existing backups"))
|
||||
Console.WriteLine(Duplicati.Library.Main.Interface.DeleteAllButNFull(target, tmp));
|
||||
}
|
||||
|
||||
log.Backupset = "Backup " + folders[0];
|
||||
Console.WriteLine("Backing up the full copy: " + folders[0]);
|
||||
using (new Timer("Full backup of " + folders[0]))
|
||||
{
|
||||
options["full"] = "";
|
||||
Log.WriteMessage(Duplicati.Library.Main.Interface.Backup(folders[0].Split(System.IO.Path.PathSeparator), target, options), LogMessageType.Information);
|
||||
options.Remove("full");
|
||||
}
|
||||
|
||||
for (int i = 1; i < folders.Length; i++)
|
||||
{
|
||||
//options["passphrase"] = "bad password";
|
||||
//If the backups are too close, we can't pick the right one :(
|
||||
System.Threading.Thread.Sleep(1000 * 5);
|
||||
log.Backupset = "Backup " + folders[i];
|
||||
Console.WriteLine("Backing up the incremental copy: " + folders[i]);
|
||||
using (new Timer("Incremental backup of " + folders[i]))
|
||||
Log.WriteMessage(Duplicati.Library.Main.Interface.Backup(folders[i].Split(System.IO.Path.PathSeparator), target, options), LogMessageType.Information);
|
||||
}
|
||||
|
||||
Duplicati.Library.Main.Options opts = new Duplicati.Library.Main.Options(options);
|
||||
using (Duplicati.Library.Interface.IBackend bk = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(target, options))
|
||||
foreach (Duplicati.Library.Interface.IFileEntry fe in bk.List())
|
||||
if (fe.Size > opts.VolumeSize)
|
||||
{
|
||||
string msg = string.Format("The file {0} is {1} bytes larger than allowed", fe.Name, fe.Size - opts.VolumeSize);
|
||||
Console.WriteLine(msg);
|
||||
Log.WriteMessage(msg, LogMessageType.Error);
|
||||
}
|
||||
|
||||
IList<DateTime> entries;
|
||||
if (options.ContainsKey("fh-dbpath"))
|
||||
{
|
||||
entries = new List<DateTime>();
|
||||
foreach (var el in Duplicati.Library.Main.Interface.ParseFhFileList(target, options))
|
||||
if (el.FileType == Library.Main.ForestHash.RemoteVolumeType.Files)
|
||||
entries.Add(el.Time.ToLocalTime());
|
||||
|
||||
if (entries.Count != folders.Length)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Entry count: " + entries.Count.ToString());
|
||||
sb.Append(string.Format("Found {0} filelists but there were {1} source folders", entries.Count, folders.Length));
|
||||
throw new Exception("Filename parsing problem, or corrupt storage: " + sb.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Duplicati.Library.Main.ManifestEntry> mfs = Duplicati.Library.Main.Interface.ParseFileList(target, options);
|
||||
|
||||
if (mfs.Count != 1 || mfs[0].Incrementals.Count != folders.Length - 1)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Entry count: " + mfs.Count.ToString());
|
||||
if (mfs.Count == 1)
|
||||
sb.Append(string.Format("Found {0} incrementals but there were {1} source folders", mfs[0].Incrementals.Count, folders.Length));
|
||||
throw new Exception("Filename parsing problem, or corrupt storage: " + sb.ToString());
|
||||
}
|
||||
|
||||
Console.WriteLine("Verifying the backup chain");
|
||||
using (new Timer("Verify backup"))
|
||||
{
|
||||
List<KeyValuePair<Duplicati.Library.Main.BackupEntryBase, Exception>> results = Duplicati.Library.Main.Interface.VerifyBackup(target, options);
|
||||
foreach (KeyValuePair<Duplicati.Library.Main.BackupEntryBase, Exception> x in results)
|
||||
if (x.Value != null)
|
||||
Console.WriteLine(string.Format("Error: {0}: {1}", x.Key.Filename, x.Value.ToString()));
|
||||
}
|
||||
|
||||
entries = new List<DateTime>();
|
||||
entries.Add(mfs[0].Time);
|
||||
foreach (Duplicati.Library.Main.ManifestEntry mf in mfs[0].Incrementals)
|
||||
entries.Add(mf.Time);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
using (TempFolder ttf = new TempFolder())
|
||||
{
|
||||
log.Backupset = "Restore " + folders[i];
|
||||
Console.WriteLine("Restoring the copy: " + folders[i]);
|
||||
|
||||
options["restore-time"] = entries[i].ToString();
|
||||
|
||||
string[] actualfolders = folders[i].Split(System.IO.Path.PathSeparator);
|
||||
string[] restorefoldernames;
|
||||
if (actualfolders.Length == 1)
|
||||
restorefoldernames = new string[] { ttf };
|
||||
else
|
||||
{
|
||||
restorefoldernames = new string[actualfolders.Length];
|
||||
for (int j = 0; j < actualfolders.Length; j++)
|
||||
restorefoldernames[j] = System.IO.Path.Combine(ttf, System.IO.Path.GetFileName(actualfolders[j]));
|
||||
}
|
||||
|
||||
Console.WriteLine("Partial restore of: " + folders[i]);
|
||||
using (TempFolder ptf = new TempFolder())
|
||||
{
|
||||
List<string> testfiles = new List<string>();
|
||||
using (new Timer("Extract list of files from" + folders[i]))
|
||||
{
|
||||
IList<string> sourcefiles = Duplicati.Library.Main.Interface.ListCurrentFiles(target, options);
|
||||
|
||||
//Remove all folders from list
|
||||
for (int j = 0; j < sourcefiles.Count; j++)
|
||||
if (sourcefiles[j].EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
|
||||
{
|
||||
sourcefiles.RemoveAt(j);
|
||||
j--;
|
||||
}
|
||||
|
||||
|
||||
int testfilecount = 15;
|
||||
Random r = new Random();
|
||||
while (testfilecount-- > 0 && sourcefiles.Count > 0)
|
||||
{
|
||||
int rn = r.Next(0, sourcefiles.Count);
|
||||
testfiles.Add(sourcefiles[rn]);
|
||||
sourcefiles.RemoveAt(rn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Add all folders to avoid warnings in restore log
|
||||
int c = testfiles.Count;
|
||||
Dictionary<string, string> partialFolders = new Dictionary<string, string>(Utility.ClientFilenameStringComparer);
|
||||
|
||||
for (int j = 0; j < c; j++)
|
||||
{
|
||||
string f = testfiles[j];
|
||||
|
||||
if (options.ContainsKey("fh-dbpath"))
|
||||
{
|
||||
if (!f.StartsWith(folders[i], Utility.ClientFilenameStringComparision))
|
||||
throw new Exception(string.Format("Unexpected file found: {0}, path is not a subfolder for {1}", f, folders[i]));
|
||||
|
||||
f = f.Substring(Utility.AppendDirSeparator(folders[i]).Length);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
f = System.IO.Path.GetDirectoryName(f);
|
||||
partialFolders[Utility.AppendDirSeparator(f)] = null;
|
||||
} while (f.IndexOf(System.IO.Path.DirectorySeparatorChar) > 0);
|
||||
}
|
||||
|
||||
if (partialFolders.ContainsKey(""))
|
||||
partialFolders.Remove("");
|
||||
|
||||
Dictionary<string, string> tops = new Dictionary<string,string>(options);
|
||||
List<string> filterlist = new List<string>();
|
||||
filterlist.AddRange(partialFolders.Keys);
|
||||
filterlist.AddRange(testfiles);
|
||||
|
||||
if (options.ContainsKey("fh-dbpath"))
|
||||
{
|
||||
//We need a minor tweak here because the two models
|
||||
// use releative vs. absolute paths
|
||||
List<string> t = new List<string>();
|
||||
foreach(var s in filterlist)
|
||||
t.Add(System.IO.Path.Combine(folders[i], s));
|
||||
|
||||
filterlist = t;
|
||||
if (!filterlist.Contains(Utility.AppendDirSeparator(folders[i])))
|
||||
filterlist.Add(Utility.AppendDirSeparator(folders[i]));
|
||||
|
||||
t = new List<string>();
|
||||
foreach (var s in testfiles)
|
||||
t.Add(s.Substring(Utility.AppendDirSeparator(folders[i]).Length));
|
||||
testfiles = t;
|
||||
}
|
||||
tops["file-to-restore"] = String.Join(System.IO.Path.PathSeparator.ToString(), filterlist.ToArray());
|
||||
|
||||
using (new Timer("Partial restore of " + folders[i]))
|
||||
Log.WriteMessage(Duplicati.Library.Main.Interface.Restore(target, new string[] { ptf }, tops), LogMessageType.Information);
|
||||
|
||||
Console.WriteLine("Verifying partial restore of: " + folders[i]);
|
||||
using (new Timer("Verification of partial restore from " + folders[i]))
|
||||
foreach (string s in testfiles)
|
||||
{
|
||||
string restoredname;
|
||||
string sourcename;
|
||||
|
||||
if (actualfolders.Length == 1)
|
||||
{
|
||||
sourcename = System.IO.Path.Combine(actualfolders[0], s);
|
||||
restoredname = System.IO.Path.Combine(ptf, s);;
|
||||
}
|
||||
else
|
||||
{
|
||||
int six = s.IndexOf(System.IO.Path.DirectorySeparatorChar);
|
||||
sourcename = System.IO.Path.Combine(actualfolders[int.Parse(s.Substring(0, six))], s.Substring(six + 1));
|
||||
restoredname = System.IO.Path.Combine(System.IO.Path.Combine(ptf, System.IO.Path.GetFileName(folders[0].Split(System.IO.Path.PathSeparator)[int.Parse(s.Substring(0, six))])), s.Substring(six + 1));
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists(restoredname))
|
||||
{
|
||||
Log.WriteMessage("Partial restore missing file: " + restoredname, LogMessageType.Error);
|
||||
Console.WriteLine("Partial restore missing file: " + restoredname);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!System.IO.File.Exists(sourcename))
|
||||
{
|
||||
Log.WriteMessage("Partial restore missing file: " + sourcename, LogMessageType.Error);
|
||||
Console.WriteLine("Partial restore missing file: " + sourcename);
|
||||
throw new Exception("Unittest is broken");
|
||||
}
|
||||
|
||||
if (!CompareFiles(sourcename, restoredname, s))
|
||||
{
|
||||
Log.WriteMessage("Partial restore file differs: " + s, LogMessageType.Error);
|
||||
Console.WriteLine("Partial restore file differs: " + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (new Timer("Restore of " + folders[i]))
|
||||
Log.WriteMessage(Duplicati.Library.Main.Interface.Restore(target, restorefoldernames, options), LogMessageType.Information);
|
||||
|
||||
Console.WriteLine("Verifying the copy: " + folders[i]);
|
||||
|
||||
using (new Timer("Verification of " + folders[i]))
|
||||
{
|
||||
for (int j = 0; j < actualfolders.Length; j++)
|
||||
VerifyDir(actualfolders[j], restorefoldernames[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
(Log.CurrentLog as StreamLog).Dispose();
|
||||
Log.CurrentLog = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of a given string, using the file system case sensitivity
|
||||
/// </summary>
|
||||
/// <returns>The index of the entry or -1 if no entry was found</returns>
|
||||
/// <param name='lst'>The list to search</param>
|
||||
/// <param name='m'>The string to find</param>
|
||||
private static int IndexOf(List<string> lst, string m)
|
||||
{
|
||||
StringComparison sc = Duplicati.Library.Utility.Utility.ClientFilenameStringComparision;
|
||||
for(int i = 0; i < lst.Count; i++)
|
||||
if (lst[i].Equals(m, sc))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the existence of all files and folders, and ensures that all
|
||||
/// files are binary equal.
|
||||
/// </summary>
|
||||
/// <param name="f1">One folder</param>
|
||||
/// <param name="f2">Another folder</param>
|
||||
private static void VerifyDir(string f1, string f2)
|
||||
{
|
||||
f1 = Utility.AppendDirSeparator(f1);
|
||||
f2 = Utility.AppendDirSeparator(f2);
|
||||
|
||||
List<string> folders1 = Utility.EnumerateFolders(f1);
|
||||
List<string> folders2 = Utility.EnumerateFolders(f2);
|
||||
|
||||
foreach (string s in folders1)
|
||||
{
|
||||
string relpath = s.Substring(f1.Length);
|
||||
string target = System.IO.Path.Combine(f2, relpath);
|
||||
int ix = IndexOf(folders2, target);
|
||||
if (ix < 0)
|
||||
{
|
||||
Log.WriteMessage("Missing folder: " + relpath, LogMessageType.Error);
|
||||
Console.WriteLine("Missing folder: " + relpath);
|
||||
}
|
||||
else
|
||||
folders2.RemoveAt(ix);
|
||||
}
|
||||
|
||||
foreach (string s in folders2)
|
||||
{
|
||||
Log.WriteMessage("Extra folder: " + s.Substring(f2.Length), LogMessageType.Error);
|
||||
Console.WriteLine("Extra folder: " + s.Substring(f2.Length));
|
||||
}
|
||||
|
||||
List<string> files1 = Utility.EnumerateFiles(f1);
|
||||
List<string> files2 = Utility.EnumerateFiles(f2);
|
||||
foreach (string s in files1)
|
||||
{
|
||||
string relpath = s.Substring(f1.Length);
|
||||
string target = System.IO.Path.Combine(f2, relpath);
|
||||
int ix = IndexOf(files2, target);
|
||||
if (ix < 0)
|
||||
{
|
||||
Log.WriteMessage("Missing file: " + relpath, LogMessageType.Error);
|
||||
Console.WriteLine("Missing file: " + relpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
files2.RemoveAt(ix);
|
||||
if (!CompareFiles(s, target, relpath))
|
||||
{
|
||||
Log.WriteMessage("File differs: " + relpath, LogMessageType.Error);
|
||||
Console.WriteLine("File differs: " + relpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string s in files2)
|
||||
{
|
||||
Log.WriteMessage("Extra file: " + s.Substring(f2.Length), LogMessageType.Error);
|
||||
Console.WriteLine("Extra file: " + s.Substring(f2.Length));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two files by reading all bytes, and comparing one by one
|
||||
/// </summary>
|
||||
/// <param name="f1">One file</param>
|
||||
/// <param name="f2">Another file</param>
|
||||
/// <param name="display">File display name</param>
|
||||
/// <returns>True if they are equal, false otherwise</returns>
|
||||
private static bool CompareFiles(string f1, string f2, string display)
|
||||
{
|
||||
using (System.IO.FileStream fs1 = System.IO.File.OpenRead(f1))
|
||||
using (System.IO.FileStream fs2 = System.IO.File.OpenRead(f2))
|
||||
if (fs1.Length != fs2.Length)
|
||||
{
|
||||
Log.WriteMessage("Lengths differ: " + display + ", " + fs1.Length.ToString() + " vs. " + fs2.Length.ToString(), LogMessageType.Error);
|
||||
Console.WriteLine("Lengths differ: " + display + ", " + fs1.Length.ToString() + " vs. " + fs2.Length.ToString());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
long len = fs1.Length;
|
||||
for (long l = 0; l < len; l++)
|
||||
if (fs1.ReadByte() != fs2.ReadByte())
|
||||
{
|
||||
Log.WriteMessage("Mismatch in byte " + l.ToString() + " in file " + display, LogMessageType.Error);
|
||||
Console.WriteLine("Mismatch in byte " + l.ToString() + " in file " + display);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true" />
|
||||
</runtime>
|
||||
<startup useLegacyV2RuntimeActivationPolicy="true">
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -0,0 +1,411 @@
|
||||
# This file is the help for the Duplicati Command Line Client. It shows what
|
||||
# commands the CLI understands and what the outputs are. Sometimes we used
|
||||
# placeholders for options. In that case descriptions are taken directly from
|
||||
# the modules. Sometimes we described options here. The reason for that is,
|
||||
# that we found the new description much better but did not want to create a
|
||||
# need for translation as many options are described in the UI as well and
|
||||
# they are translated there.
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe
|
||||
> duplicati.commandline.exe help
|
||||
|
||||
See duplicati.commandline.exe help <topic> for more information.
|
||||
|
||||
Examples: example
|
||||
|
||||
Commands: backup, restore, delete-all-but-n-full, delete-all-but-n, cleanup, delete-older-than, list, list-current-files, list-source-folders, list-actual-signature-files, collection-status, create-folder, find-last-version, verify
|
||||
|
||||
Debugging: debug, logging
|
||||
|
||||
Targets: %BACKENDS%
|
||||
|
||||
Modules: %ENCRYPTIONMODULES%, %COMPRESSIONMODULES%, %GENERICMODULES%
|
||||
|
||||
Formats: date, time, size, encryption, compression
|
||||
|
||||
Advanced options: advanced, returncodes, filter, <option> (e.g. --auto-cleanup)
|
||||
|
||||
http://www.duplicati.com/ Version: %VERSION%
|
||||
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help example
|
||||
> duplicati.commandline.exe help examples
|
||||
|
||||
Make an encrypted backup
|
||||
========================
|
||||
The following command will make an encrypted backup and store it on an FTP server. The first backup will be full followed by 10 incremental backups before another full backup is made. As no passphrase is specified, the user will be prompted for a password. The upload speed is throttled to 500kB/s.
|
||||
|
||||
%MONO%"%APP_PATH%" backup
|
||||
"%EXAMPLE_SOURCE_PATH%" "ftp://ftp.example.com/target"
|
||||
--ftp-username=username
|
||||
--ftp-password=password
|
||||
--full-if-more-than-n-incrementals=10
|
||||
--auto-cleanup
|
||||
--max-upload-pr-second=500kB
|
||||
|
||||
|
||||
Delete old backups
|
||||
==================
|
||||
The following command will delete old backups. If no passphrase is specified, the user will be prompted for a passphrase. The option --force is required to delete the files; without that option no files will be deleted. Duplicati does not delete backup files that are required to restore files from a valid newer backup (a full backup is always required to restore files from an incremental backup).
|
||||
|
||||
%MONO%"%APP_PATH%" delete-older-than 10D
|
||||
"ftp://ftp.example.com/target"
|
||||
--ftp-username=username
|
||||
--ftp-password=password
|
||||
--force
|
||||
|
||||
|
||||
Restore a specific file
|
||||
=======================
|
||||
The following command will restore "%EXAMPLE_SOURCE_FILE%" from the backup in the latest version to the local folder "%EXAMPLE_RESTORE_PATH%".
|
||||
|
||||
%MONO%"%APP_PATH%" restore
|
||||
"ftp://ftp.example.com/target" "%EXAMPLE_RESTORE_PATH%"
|
||||
--ftp-username=username
|
||||
--ftp-password=password
|
||||
--file-to-restore="%EXAMPLE_SOURCE_FILE%"
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help backup
|
||||
|
||||
Usage: backup <source folder> <target url> <options>
|
||||
|
||||
This will perform full or incremental backups. It reads all files from <source folder> and stores the backups in <target url>. If no rule for full backups is specified, Duplicati will create one full backup and incremental backups afterwards. Multiple source folders have to be separated by the operating system's delimiter (semicolon ";" on Windows, colon ":" on Linux).
|
||||
|
||||
Options:
|
||||
--auto-cleanup
|
||||
Removes all files that do not belong to the backup (e.g. partial files caused by interrupted uploads).
|
||||
--backup-prefix = <string>
|
||||
Replaces the default "duplicati" with <string> in the file names of the backup files. It is required to specify different prefixes if multiple backups are stored in the same target folder.
|
||||
--full
|
||||
Make a full backup. If nothing is specified, an initial full backup is made with incremental backups afterwards.
|
||||
--full-if-older-than = <date>
|
||||
Make a new full backup after the specified relative date or time.
|
||||
--full-if-more-than-n-incrementals = <number>
|
||||
Make a full backup after n incremental backups.
|
||||
--max-upload-pr-second = <size>
|
||||
Limits the upload speed to the specified value. <size> is interpreted as bandwidth/s.
|
||||
--no-encryption
|
||||
The backup is NOT encrypted with a passphrase. Unencrypted files are stored.
|
||||
--passphrase = <passphrase>
|
||||
The passphrase that is used to encrypt the backup. If nothing is specified here, the environment variable PASSPHRASE will be used or the user will be prompted to type in the passphrase.
|
||||
--volsize = <size>
|
||||
The maximum size of files being written to the target. Default size is 10MB.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help restore
|
||||
|
||||
Usage: restore <source url> <target folder>
|
||||
|
||||
This will restore one or more files from the backup in <source url> to the local folder <target folder>.
|
||||
|
||||
Options:
|
||||
--file-to-restore = <list of files>
|
||||
List of files to be restored separated by a semicolon ";" on Windows or colon ":" on Linux.
|
||||
--restore-time = <date>
|
||||
Restore from a specific or relative date or time. If nothing is specified, the latest version is restored.
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help delete-all-but-n-full
|
||||
|
||||
Usage: delete-all-but-n-full <number> <source url>
|
||||
|
||||
This will keep the <number> latests full backups and delete older ones.
|
||||
|
||||
Options:
|
||||
%OPTION:force%
|
||||
%OPTION:allow-full-removal%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help delete-all-but-n
|
||||
|
||||
Usage: delete-all-but-n <number> <target url>
|
||||
|
||||
This will keep the <number> latest backups no matter if they are full or incremental. Older backups will be deleted. No backups are deleted that are required to restore files from a valid newer backup.
|
||||
|
||||
Options:
|
||||
%OPTION:force%
|
||||
%OPTION:allow-full-removal%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help delete-older-than
|
||||
|
||||
Usage: delete-older-than <date> <target url>
|
||||
|
||||
This will delete all backups from the target that older than the specified absolute or relative date and time.
|
||||
|
||||
Options:
|
||||
%OPTION:force%
|
||||
%OPTION:allow-full-removal%
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help debug
|
||||
> duplicati.commandline.exe help logging
|
||||
|
||||
Duplicati provides information for debugging and logging purposes. By default, all debugging and logging is turned off.
|
||||
|
||||
--debug-output
|
||||
Error messages are more verbose.
|
||||
--debug-retry-errors
|
||||
If something needs to be retried (e.g. upload failed) this will cause an entry in the log file.
|
||||
--log-file = <path>
|
||||
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".
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help encryption
|
||||
> duplicati.commandline.exe help compression
|
||||
|
||||
Duplicati offers various options for the used compression and encryption modules.
|
||||
|
||||
--encryption-module = %ENCRYPTIONMODULES%
|
||||
The encryption module that is used to encrypt backups. Default is %DEFAULTENCRYPTIONMODULE%.
|
||||
--compression-module = %COMPRESSIONMODULES%
|
||||
The compression module that is used. Default is %DEFAULTCOMPRESSIONMODULE%.
|
||||
--enable-module = %GENERICMODULES%
|
||||
Enable a built-in generic module that is not enabled by default
|
||||
--disable-module = %GENERICMODULES%
|
||||
Disable a built-in generic module that is enabled by default
|
||||
%OPTION:passphrase%
|
||||
%OPTION:no-encryption%
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help gpg
|
||||
|
||||
Duplicati is shipped with an interface to GNU Privary Guard. It requires that the gpg executable is available on the system. On Windows it is assumed that this is in the default installation folder under program files, under Linux and OSX it is assumed that the program is available via the PATH environment variable. It is possible to supply the path to GPG using the --gpg-program-path switch.
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help cleanup
|
||||
|
||||
Usage: cleanup <target url>
|
||||
|
||||
Removes all files that do not belong to the backup (e.g. partial files caused by interrupted uploads). This can also be performed when the actions backup, restore are run with the option --auto-cleanup.
|
||||
|
||||
Options:
|
||||
%OPTION:force%
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help list
|
||||
|
||||
Usage: list <target url>
|
||||
|
||||
Lists all files stored on the remote server. These are manifest files, signature files, content files and other files that do not to any backup created by duplicati. This command can be used to see the contents of the remote folder.
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help list-current-files
|
||||
|
||||
Usage: list-current-files <target url>
|
||||
|
||||
Lists the (source) files that are contained in a backup. By default, the latest versions are listed. This action is useful to try out what files would be restored with a given set or options.
|
||||
|
||||
Options:
|
||||
--restore-time = <date>
|
||||
By default, Duplicati will restore files from the most recent backup, use this option to restore older versions of a file. You may use relative times, like "-2M" for a backup from two months ago. Duplicati will pick the next older version of the value specified. If you specify "-2M", the restored version could be 2 months and 3 days old.
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help list-source-folders
|
||||
|
||||
Usage: list-source-folders <target url>
|
||||
|
||||
Lists the source folders that have been included in a backup. By default, the source folders of the latest backup are listed. This action is useful to check what source folders had been included in a backup at a given date or time.
|
||||
|
||||
Options:
|
||||
--restore-time = <date>
|
||||
By default, Duplicati will restore files from the most recent backup, use this option to restore older versions of a file. You may use relative times, like "-2M" for a backup from two months ago. Duplicati will pick the next older version of the value specified. If you specify "-2M", the restored version could be 2 months and 3 days old.
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help list-actual-signature-files
|
||||
|
||||
Usage: list-actual-signature-files <target url>
|
||||
|
||||
Lists the files found in a single backup set with a status: (added, modified, deleted). This is the same as a "change set".
|
||||
|
||||
Options:
|
||||
--restore-time = <date>
|
||||
By default, Duplicati will restore files from the most recent backup, use this option to select another item. You may use relative times, like "-2M" for a backup from two months ago.
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help file
|
||||
|
||||
Duplicati can use the local file system to store backups. The following target URL formats can be used:
|
||||
file://hostname/folder
|
||||
file://\\server\folder (UNC path)
|
||||
file://c:\folder (Windows)
|
||||
file:///usr/pub/files (Linux)
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help tahoe
|
||||
> duplicati.commandline.exe help tahoelafs
|
||||
|
||||
Duplicati can use the TahoeLAFS to store backups. The following target URL format is used:
|
||||
tahoe://hostname:port/uri/$DIRCAP
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help ftp
|
||||
|
||||
Duplicati can use FTP servers to store backups. The following target URL formats can be used:
|
||||
ftp://hostname/folder
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help ssh
|
||||
|
||||
Duplicati can use SSH servers to store backups. The following target URL formats can be used:
|
||||
ssh://hostname/folder
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help webdav
|
||||
|
||||
Duplicati can use WebDAV servers to store backups. The following target URL formats can be used:
|
||||
webdav://hostname/folder"
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help s3
|
||||
|
||||
Duplicati can use S3-compatible servers to store backups. The following target URL format is used:
|
||||
s3://bucketname/prefix
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help skydrive
|
||||
|
||||
Duplicati can use Windows Live Skydrive to store backups. The following target URL format is used:
|
||||
skydrive://folder/subfolder
|
||||
Please note that there is no official API and accessing SkyDrive through this backend may violate the ToS and may stop to work if Microsoft decides to change the API.
|
||||
|
||||
Options:
|
||||
%MODULEOPTIONS%
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help date
|
||||
> duplicati.commandline.exe help time
|
||||
|
||||
Duplicati supports absolute and relative dates and times:
|
||||
|
||||
now --> The current time
|
||||
|
||||
1234567890 --> A timestamp, seconds since 1970.
|
||||
|
||||
"2009-03-26T08:30:00+01:00" --> An absolute date and time. You can also use the local date and time format of your system like e.g. "01-14-2000" or "01 jan. 2004".
|
||||
|
||||
Y, M, D, W, h, m, s --> Relative date and time: year, month, day, week, hour, minute, second. Example: 2M10D5h is now + 2 months + 10 days + 5 hours.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help size
|
||||
|
||||
Whenever a size is required, you can use any of the following suffixes:
|
||||
|
||||
B - Bytes
|
||||
kB - Kilobytes
|
||||
MB - Megabytes
|
||||
GB - Gigabytes
|
||||
|
||||
For speed limits, use the same format. If you enter 1MB this will be 1MB/sec.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help filter
|
||||
> duplicati.commandline.exe help filters
|
||||
|
||||
Duplicati can apply globbing and regex filter rules to backup and restore specific files only. It can also exclude files that meet specific conditions. It is recommended to check the website for more information how Duplicati processes filter rules. For more information, please visit http://code.google.com/p/duplicati/wiki/FilterUsage
|
||||
|
||||
%OPTION:include%
|
||||
%OPTION:exclude%
|
||||
%OPTION:include-regexp%
|
||||
%OPTION:exclude-regexp%
|
||||
%OPTION:skip-files-larger-than%
|
||||
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help collection-status
|
||||
Usage: collection-status <target url>
|
||||
|
||||
Collection status will list all backup chains found on the target, along with the combined size of each volume.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help create-folder
|
||||
Usage: create-folder <target url>
|
||||
|
||||
This command can be used to create the folder on the remote backend.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help find-last-version
|
||||
Usage: find-last-version <target url> --file-to-restore=%EXAMPLE_SOURCE_FILE%
|
||||
|
||||
This command finds the last backup set that contains a specified file. This can be used to locate the last backup of a file that has been deleted.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help verify
|
||||
Usage: verify <target url> --verification-level=manifest
|
||||
|
||||
Duplicati will check the integrity of a remote backup. Therefore, it will download backup files and check their integrity locally. Default behaviour is, that only the manifest files required to restore the latest version of the backup are checked. Using the below listed options, it is possible to also check signature and content files. It is also possible to check older versions of a backup. Please note that this command might download a lot of data!
|
||||
|
||||
Options:
|
||||
--verification-level = Manifest | Signature | Full
|
||||
Defines what files are downloaded and checked.
|
||||
Manifest --> manifest files
|
||||
Signature --> manifest + signature files
|
||||
Full --> manifest + signature + content files
|
||||
--restore-time = <date>
|
||||
Select another version of the backup that is older than the specified absolute or relative date.
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help advanced
|
||||
> duplicati.commandline.exe help option
|
||||
> duplicati.commandline.exe help options
|
||||
|
||||
Duplicati offers more options than listed in the other topics. Those additional options should only be used with care. For normal operation none of them should ever be required. Here is a complete list of options supported by Duplicati:
|
||||
|
||||
%MAINOPTIONS%
|
||||
|
||||
# =============================================================================
|
||||
> duplicati.commandline.exe help returncodes
|
||||
> duplicati.commandline.exe help exitcodes
|
||||
> duplicati.commandline.exe help statuscodes
|
||||
|
||||
Duplicati reports the following return/exit codes:
|
||||
0 - Success
|
||||
1 - Successful backup, but no files were changed
|
||||
2 - Successful backup, with warnings
|
||||
50 - Backup uploaded some files, but did not finish
|
||||
100 - An error occurred
|
||||
200 - Invalid commandline arguments found
|
||||
|
||||
+503
@@ -0,0 +1,503 @@
|
||||
namespace Duplicati.GUI
|
||||
{
|
||||
partial class ApplicationSetup
|
||||
{
|
||||
/// <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.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ApplicationSetup));
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.BalloonNotificationLevel = new System.Windows.Forms.ComboBox();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.HideDonateButton = new System.Windows.Forms.CheckBox();
|
||||
this.StartupDelayDuration = new Duplicati.GUI.HelperControls.DurationEditor();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.LanguageSelection = new System.Windows.Forms.ComboBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.RecentDuration = new Duplicati.GUI.HelperControls.DurationEditor();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.CacheSizeLabel = new System.Windows.Forms.Label();
|
||||
this.ClearCacheButton = new System.Windows.Forms.Button();
|
||||
this.SignatureCacheEnabled = new System.Windows.Forms.CheckBox();
|
||||
this.SignatureCachePathBrowse = new System.Windows.Forms.Button();
|
||||
this.SignatureCachePath = new System.Windows.Forms.TextBox();
|
||||
this.TempPathBrowse = new System.Windows.Forms.Button();
|
||||
this.TempPath = new System.Windows.Forms.TextBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.OKBtn = new System.Windows.Forms.Button();
|
||||
this.CancelBtn = new System.Windows.Forms.Button();
|
||||
this.BrowseTempPath = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.PasswordDefaultsGroup = new System.Windows.Forms.GroupBox();
|
||||
this.PasswordPanel = new System.Windows.Forms.Panel();
|
||||
this.EncryptionModule = new System.Windows.Forms.ComboBox();
|
||||
this.EncryptionMethod = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.CommonPassword = new Duplicati.Winforms.Controls.PasswordControl();
|
||||
this.UseCommonPassword = new System.Windows.Forms.CheckBox();
|
||||
this.BrowseSignatureCachePath = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.CacheSizeCalculator = new System.ComponentModel.BackgroundWorker();
|
||||
this.TabContainer = new System.Windows.Forms.TabControl();
|
||||
this.BasicTab = new System.Windows.Forms.TabPage();
|
||||
this.AdvancedTab = new System.Windows.Forms.TabPage();
|
||||
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
||||
this.Bandwidth = new Duplicati.GUI.HelperControls.BandwidthLimit();
|
||||
this.ThreadPriorityPicker = new Duplicati.GUI.HelperControls.ThreadPriorityPicker();
|
||||
this.LicenseTab = new System.Windows.Forms.TabPage();
|
||||
this.LicenseLink = new System.Windows.Forms.LinkLabel();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.LicenseText = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.LicenseSections = new System.Windows.Forms.ListBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.PasswordDefaultsGroup.SuspendLayout();
|
||||
this.PasswordPanel.SuspendLayout();
|
||||
this.TabContainer.SuspendLayout();
|
||||
this.BasicTab.SuspendLayout();
|
||||
this.AdvancedTab.SuspendLayout();
|
||||
this.groupBox4.SuspendLayout();
|
||||
this.LicenseTab.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(this.label1, "label1");
|
||||
this.label1.Name = "label1";
|
||||
this.toolTip.SetToolTip(this.label1, resources.GetString("label1.ToolTip"));
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.BalloonNotificationLevel);
|
||||
this.groupBox1.Controls.Add(this.label8);
|
||||
this.groupBox1.Controls.Add(this.HideDonateButton);
|
||||
this.groupBox1.Controls.Add(this.StartupDelayDuration);
|
||||
this.groupBox1.Controls.Add(this.label7);
|
||||
this.groupBox1.Controls.Add(this.LanguageSelection);
|
||||
this.groupBox1.Controls.Add(this.label3);
|
||||
this.groupBox1.Controls.Add(this.RecentDuration);
|
||||
this.groupBox1.Controls.Add(this.label1);
|
||||
resources.ApplyResources(this.groupBox1, "groupBox1");
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.TabStop = false;
|
||||
//
|
||||
// BalloonNotificationLevel
|
||||
//
|
||||
resources.ApplyResources(this.BalloonNotificationLevel, "BalloonNotificationLevel");
|
||||
this.BalloonNotificationLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.BalloonNotificationLevel.FormattingEnabled = true;
|
||||
this.BalloonNotificationLevel.Name = "BalloonNotificationLevel";
|
||||
this.toolTip.SetToolTip(this.BalloonNotificationLevel, resources.GetString("BalloonNotificationLevel.ToolTip"));
|
||||
this.BalloonNotificationLevel.SelectedIndexChanged += new System.EventHandler(this.BalloonNotificationLevel_SelectedIndexChanged);
|
||||
//
|
||||
// label8
|
||||
//
|
||||
resources.ApplyResources(this.label8, "label8");
|
||||
this.label8.Name = "label8";
|
||||
this.toolTip.SetToolTip(this.label8, resources.GetString("label8.ToolTip"));
|
||||
//
|
||||
// HideDonateButton
|
||||
//
|
||||
resources.ApplyResources(this.HideDonateButton, "HideDonateButton");
|
||||
this.HideDonateButton.Name = "HideDonateButton";
|
||||
this.toolTip.SetToolTip(this.HideDonateButton, resources.GetString("HideDonateButton.ToolTip"));
|
||||
this.HideDonateButton.UseVisualStyleBackColor = true;
|
||||
this.HideDonateButton.CheckedChanged += new System.EventHandler(this.HideDonateButton_CheckedChanged);
|
||||
//
|
||||
// StartupDelayDuration
|
||||
//
|
||||
resources.ApplyResources(this.StartupDelayDuration, "StartupDelayDuration");
|
||||
this.StartupDelayDuration.Name = "StartupDelayDuration";
|
||||
this.toolTip.SetToolTip(this.StartupDelayDuration, resources.GetString("StartupDelayDuration.ToolTip"));
|
||||
this.StartupDelayDuration.Value = "";
|
||||
this.StartupDelayDuration.ValueChanged += new System.EventHandler(this.StartupDelayDuration_ValueChanged);
|
||||
//
|
||||
// label7
|
||||
//
|
||||
resources.ApplyResources(this.label7, "label7");
|
||||
this.label7.Name = "label7";
|
||||
this.toolTip.SetToolTip(this.label7, resources.GetString("label7.ToolTip"));
|
||||
//
|
||||
// LanguageSelection
|
||||
//
|
||||
resources.ApplyResources(this.LanguageSelection, "LanguageSelection");
|
||||
this.LanguageSelection.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.LanguageSelection.FormattingEnabled = true;
|
||||
this.LanguageSelection.Name = "LanguageSelection";
|
||||
this.toolTip.SetToolTip(this.LanguageSelection, resources.GetString("LanguageSelection.ToolTip"));
|
||||
this.LanguageSelection.SelectedIndexChanged += new System.EventHandler(this.LanguageSelection_SelectedIndexChanged);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(this.label3, "label3");
|
||||
this.label3.Name = "label3";
|
||||
this.toolTip.SetToolTip(this.label3, resources.GetString("label3.ToolTip"));
|
||||
//
|
||||
// RecentDuration
|
||||
//
|
||||
resources.ApplyResources(this.RecentDuration, "RecentDuration");
|
||||
this.RecentDuration.Name = "RecentDuration";
|
||||
this.toolTip.SetToolTip(this.RecentDuration, resources.GetString("RecentDuration.ToolTip"));
|
||||
this.RecentDuration.Value = "";
|
||||
this.RecentDuration.ValueChanged += new System.EventHandler(this.RecentDuration_ValueChanged);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.CacheSizeLabel);
|
||||
this.groupBox2.Controls.Add(this.ClearCacheButton);
|
||||
this.groupBox2.Controls.Add(this.SignatureCacheEnabled);
|
||||
this.groupBox2.Controls.Add(this.SignatureCachePathBrowse);
|
||||
this.groupBox2.Controls.Add(this.SignatureCachePath);
|
||||
this.groupBox2.Controls.Add(this.TempPathBrowse);
|
||||
this.groupBox2.Controls.Add(this.TempPath);
|
||||
this.groupBox2.Controls.Add(this.label4);
|
||||
resources.ApplyResources(this.groupBox2, "groupBox2");
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.TabStop = false;
|
||||
//
|
||||
// CacheSizeLabel
|
||||
//
|
||||
resources.ApplyResources(this.CacheSizeLabel, "CacheSizeLabel");
|
||||
this.CacheSizeLabel.Name = "CacheSizeLabel";
|
||||
this.toolTip.SetToolTip(this.CacheSizeLabel, resources.GetString("CacheSizeLabel.ToolTip"));
|
||||
//
|
||||
// ClearCacheButton
|
||||
//
|
||||
resources.ApplyResources(this.ClearCacheButton, "ClearCacheButton");
|
||||
this.ClearCacheButton.Name = "ClearCacheButton";
|
||||
this.toolTip.SetToolTip(this.ClearCacheButton, resources.GetString("ClearCacheButton.ToolTip"));
|
||||
this.ClearCacheButton.UseVisualStyleBackColor = true;
|
||||
this.ClearCacheButton.Click += new System.EventHandler(this.ClearCacheButton_Click);
|
||||
//
|
||||
// SignatureCacheEnabled
|
||||
//
|
||||
resources.ApplyResources(this.SignatureCacheEnabled, "SignatureCacheEnabled");
|
||||
this.SignatureCacheEnabled.Name = "SignatureCacheEnabled";
|
||||
this.toolTip.SetToolTip(this.SignatureCacheEnabled, resources.GetString("SignatureCacheEnabled.ToolTip"));
|
||||
this.SignatureCacheEnabled.UseVisualStyleBackColor = true;
|
||||
this.SignatureCacheEnabled.CheckedChanged += new System.EventHandler(this.SignatureCacheEnabled_CheckedChanged);
|
||||
//
|
||||
// SignatureCachePathBrowse
|
||||
//
|
||||
resources.ApplyResources(this.SignatureCachePathBrowse, "SignatureCachePathBrowse");
|
||||
this.SignatureCachePathBrowse.Name = "SignatureCachePathBrowse";
|
||||
this.toolTip.SetToolTip(this.SignatureCachePathBrowse, resources.GetString("SignatureCachePathBrowse.ToolTip"));
|
||||
this.SignatureCachePathBrowse.UseVisualStyleBackColor = true;
|
||||
this.SignatureCachePathBrowse.Click += new System.EventHandler(this.SignatureCachePathBrowse_Click);
|
||||
//
|
||||
// SignatureCachePath
|
||||
//
|
||||
resources.ApplyResources(this.SignatureCachePath, "SignatureCachePath");
|
||||
this.SignatureCachePath.Name = "SignatureCachePath";
|
||||
this.SignatureCachePath.TextChanged += new System.EventHandler(this.SignatureCachePath_TextChanged);
|
||||
//
|
||||
// TempPathBrowse
|
||||
//
|
||||
resources.ApplyResources(this.TempPathBrowse, "TempPathBrowse");
|
||||
this.TempPathBrowse.Name = "TempPathBrowse";
|
||||
this.toolTip.SetToolTip(this.TempPathBrowse, resources.GetString("TempPathBrowse.ToolTip"));
|
||||
this.TempPathBrowse.UseVisualStyleBackColor = true;
|
||||
this.TempPathBrowse.Click += new System.EventHandler(this.TempPathBrowse_Click);
|
||||
//
|
||||
// TempPath
|
||||
//
|
||||
resources.ApplyResources(this.TempPath, "TempPath");
|
||||
this.TempPath.Name = "TempPath";
|
||||
this.toolTip.SetToolTip(this.TempPath, resources.GetString("TempPath.ToolTip"));
|
||||
this.TempPath.TextChanged += new System.EventHandler(this.TempPath_TextChanged);
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(this.label4, "label4");
|
||||
this.label4.Name = "label4";
|
||||
this.toolTip.SetToolTip(this.label4, resources.GetString("label4.ToolTip"));
|
||||
//
|
||||
// OKBtn
|
||||
//
|
||||
resources.ApplyResources(this.OKBtn, "OKBtn");
|
||||
this.OKBtn.Name = "OKBtn";
|
||||
this.OKBtn.UseVisualStyleBackColor = true;
|
||||
this.OKBtn.Click += new System.EventHandler(this.OKBtn_Click);
|
||||
//
|
||||
// CancelBtn
|
||||
//
|
||||
resources.ApplyResources(this.CancelBtn, "CancelBtn");
|
||||
this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.CancelBtn.Name = "CancelBtn";
|
||||
this.CancelBtn.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// PasswordDefaultsGroup
|
||||
//
|
||||
this.PasswordDefaultsGroup.Controls.Add(this.PasswordPanel);
|
||||
this.PasswordDefaultsGroup.Controls.Add(this.UseCommonPassword);
|
||||
resources.ApplyResources(this.PasswordDefaultsGroup, "PasswordDefaultsGroup");
|
||||
this.PasswordDefaultsGroup.Name = "PasswordDefaultsGroup";
|
||||
this.PasswordDefaultsGroup.TabStop = false;
|
||||
//
|
||||
// PasswordPanel
|
||||
//
|
||||
this.PasswordPanel.Controls.Add(this.EncryptionModule);
|
||||
this.PasswordPanel.Controls.Add(this.EncryptionMethod);
|
||||
this.PasswordPanel.Controls.Add(this.label5);
|
||||
this.PasswordPanel.Controls.Add(this.CommonPassword);
|
||||
resources.ApplyResources(this.PasswordPanel, "PasswordPanel");
|
||||
this.PasswordPanel.Name = "PasswordPanel";
|
||||
//
|
||||
// EncryptionModule
|
||||
//
|
||||
this.EncryptionModule.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.EncryptionModule.FormattingEnabled = true;
|
||||
resources.ApplyResources(this.EncryptionModule, "EncryptionModule");
|
||||
this.EncryptionModule.Name = "EncryptionModule";
|
||||
this.toolTip.SetToolTip(this.EncryptionModule, resources.GetString("EncryptionModule.ToolTip"));
|
||||
this.EncryptionModule.SelectedIndexChanged += new System.EventHandler(this.EncryptionModule_SelectedIndexChanged);
|
||||
this.EncryptionModule.TextChanged += new System.EventHandler(this.EncryptionModule_SelectedIndexChanged);
|
||||
//
|
||||
// EncryptionMethod
|
||||
//
|
||||
resources.ApplyResources(this.EncryptionMethod, "EncryptionMethod");
|
||||
this.EncryptionMethod.Name = "EncryptionMethod";
|
||||
this.toolTip.SetToolTip(this.EncryptionMethod, resources.GetString("EncryptionMethod.ToolTip"));
|
||||
//
|
||||
// label5
|
||||
//
|
||||
resources.ApplyResources(this.label5, "label5");
|
||||
this.label5.Name = "label5";
|
||||
this.toolTip.SetToolTip(this.label5, resources.GetString("label5.ToolTip"));
|
||||
//
|
||||
// CommonPassword
|
||||
//
|
||||
this.CommonPassword.AskToEnterNewPassword = false;
|
||||
this.CommonPassword.InitialPassword = null;
|
||||
this.CommonPassword.IsPasswordVisible = false;
|
||||
resources.ApplyResources(this.CommonPassword, "CommonPassword");
|
||||
this.CommonPassword.MaximumSize = new System.Drawing.Size(5000, 20);
|
||||
this.CommonPassword.MinimumSize = new System.Drawing.Size(150, 20);
|
||||
this.CommonPassword.Name = "CommonPassword";
|
||||
this.toolTip.SetToolTip(this.CommonPassword, resources.GetString("CommonPassword.ToolTip"));
|
||||
this.CommonPassword.TextChanged += new System.EventHandler(this.CommonPassword_TextChanged);
|
||||
//
|
||||
// UseCommonPassword
|
||||
//
|
||||
resources.ApplyResources(this.UseCommonPassword, "UseCommonPassword");
|
||||
this.UseCommonPassword.Name = "UseCommonPassword";
|
||||
this.toolTip.SetToolTip(this.UseCommonPassword, resources.GetString("UseCommonPassword.ToolTip"));
|
||||
this.UseCommonPassword.UseVisualStyleBackColor = true;
|
||||
this.UseCommonPassword.CheckedChanged += new System.EventHandler(this.UseCommonPassword_CheckedChanged);
|
||||
//
|
||||
// CacheSizeCalculator
|
||||
//
|
||||
this.CacheSizeCalculator.WorkerSupportsCancellation = true;
|
||||
this.CacheSizeCalculator.DoWork += new System.ComponentModel.DoWorkEventHandler(this.CacheSizeCalculator_DoWork);
|
||||
this.CacheSizeCalculator.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.CacheSizeCalculator_RunWorkerCompleted);
|
||||
//
|
||||
// TabContainer
|
||||
//
|
||||
this.TabContainer.Controls.Add(this.BasicTab);
|
||||
this.TabContainer.Controls.Add(this.AdvancedTab);
|
||||
this.TabContainer.Controls.Add(this.LicenseTab);
|
||||
resources.ApplyResources(this.TabContainer, "TabContainer");
|
||||
this.TabContainer.Name = "TabContainer";
|
||||
this.TabContainer.SelectedIndex = 0;
|
||||
//
|
||||
// BasicTab
|
||||
//
|
||||
this.BasicTab.Controls.Add(this.PasswordDefaultsGroup);
|
||||
this.BasicTab.Controls.Add(this.groupBox1);
|
||||
resources.ApplyResources(this.BasicTab, "BasicTab");
|
||||
this.BasicTab.Name = "BasicTab";
|
||||
this.BasicTab.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// AdvancedTab
|
||||
//
|
||||
this.AdvancedTab.Controls.Add(this.groupBox2);
|
||||
this.AdvancedTab.Controls.Add(this.groupBox4);
|
||||
resources.ApplyResources(this.AdvancedTab, "AdvancedTab");
|
||||
this.AdvancedTab.Name = "AdvancedTab";
|
||||
this.AdvancedTab.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox4
|
||||
//
|
||||
this.groupBox4.Controls.Add(this.Bandwidth);
|
||||
this.groupBox4.Controls.Add(this.ThreadPriorityPicker);
|
||||
resources.ApplyResources(this.groupBox4, "groupBox4");
|
||||
this.groupBox4.Name = "groupBox4";
|
||||
this.groupBox4.TabStop = false;
|
||||
//
|
||||
// Bandwidth
|
||||
//
|
||||
this.Bandwidth.DownloadLimit = null;
|
||||
this.Bandwidth.DownloadLimitInBytes = ((long)(0));
|
||||
resources.ApplyResources(this.Bandwidth, "Bandwidth");
|
||||
this.Bandwidth.Name = "Bandwidth";
|
||||
this.toolTip.SetToolTip(this.Bandwidth, resources.GetString("Bandwidth.ToolTip"));
|
||||
this.Bandwidth.UploadLimit = null;
|
||||
this.Bandwidth.UploadLimitInBytes = ((long)(0));
|
||||
this.Bandwidth.DownloadLimitChanged += new System.EventHandler(this.Bandwidth_DownloadLimitChanged);
|
||||
this.Bandwidth.UploadLimitChanged += new System.EventHandler(this.Bandwidth_UploadLimitChanged);
|
||||
//
|
||||
// ThreadPriorityPicker
|
||||
//
|
||||
resources.ApplyResources(this.ThreadPriorityPicker, "ThreadPriorityPicker");
|
||||
this.ThreadPriorityPicker.Name = "ThreadPriorityPicker";
|
||||
this.toolTip.SetToolTip(this.ThreadPriorityPicker, resources.GetString("ThreadPriorityPicker.ToolTip"));
|
||||
this.ThreadPriorityPicker.SelectedPriorityChanged += new System.EventHandler(this.ThreadPriorityPicker_SelectedPriorityChanged);
|
||||
//
|
||||
// LicenseTab
|
||||
//
|
||||
this.LicenseTab.Controls.Add(this.LicenseLink);
|
||||
this.LicenseTab.Controls.Add(this.label6);
|
||||
this.LicenseTab.Controls.Add(this.LicenseText);
|
||||
this.LicenseTab.Controls.Add(this.label2);
|
||||
this.LicenseTab.Controls.Add(this.LicenseSections);
|
||||
resources.ApplyResources(this.LicenseTab, "LicenseTab");
|
||||
this.LicenseTab.Name = "LicenseTab";
|
||||
this.LicenseTab.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// LicenseLink
|
||||
//
|
||||
resources.ApplyResources(this.LicenseLink, "LicenseLink");
|
||||
this.LicenseLink.Name = "LicenseLink";
|
||||
this.LicenseLink.TabStop = true;
|
||||
this.toolTip.SetToolTip(this.LicenseLink, resources.GetString("LicenseLink.ToolTip"));
|
||||
this.LicenseLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LicenseLink_LinkClicked);
|
||||
//
|
||||
// label6
|
||||
//
|
||||
resources.ApplyResources(this.label6, "label6");
|
||||
this.label6.Name = "label6";
|
||||
//
|
||||
// LicenseText
|
||||
//
|
||||
resources.ApplyResources(this.LicenseText, "LicenseText");
|
||||
this.LicenseText.Name = "LicenseText";
|
||||
this.LicenseText.ReadOnly = true;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
resources.ApplyResources(this.label2, "label2");
|
||||
this.label2.Name = "label2";
|
||||
//
|
||||
// LicenseSections
|
||||
//
|
||||
this.LicenseSections.FormattingEnabled = true;
|
||||
resources.ApplyResources(this.LicenseSections, "LicenseSections");
|
||||
this.LicenseSections.Name = "LicenseSections";
|
||||
this.toolTip.SetToolTip(this.LicenseSections, resources.GetString("LicenseSections.ToolTip"));
|
||||
this.LicenseSections.SelectedIndexChanged += new System.EventHandler(this.LicenseSections_SelectedIndexChanged);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.OKBtn);
|
||||
this.panel1.Controls.Add(this.CancelBtn);
|
||||
resources.ApplyResources(this.panel1, "panel1");
|
||||
this.panel1.Name = "panel1";
|
||||
//
|
||||
// ApplicationSetup
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.CancelBtn;
|
||||
this.Controls.Add(this.TabContainer);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "ApplicationSetup";
|
||||
this.Load += new System.EventHandler(this.ApplicationSetup_Load);
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ApplicationSetup_FormClosing);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.PasswordDefaultsGroup.ResumeLayout(false);
|
||||
this.PasswordDefaultsGroup.PerformLayout();
|
||||
this.PasswordPanel.ResumeLayout(false);
|
||||
this.PasswordPanel.PerformLayout();
|
||||
this.TabContainer.ResumeLayout(false);
|
||||
this.BasicTab.ResumeLayout(false);
|
||||
this.AdvancedTab.ResumeLayout(false);
|
||||
this.groupBox4.ResumeLayout(false);
|
||||
this.LicenseTab.ResumeLayout(false);
|
||||
this.LicenseTab.PerformLayout();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.Button OKBtn;
|
||||
private System.Windows.Forms.Button CancelBtn;
|
||||
private Duplicati.GUI.HelperControls.DurationEditor RecentDuration;
|
||||
private System.Windows.Forms.Button TempPathBrowse;
|
||||
private System.Windows.Forms.TextBox TempPath;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.FolderBrowserDialog BrowseTempPath;
|
||||
private System.Windows.Forms.GroupBox PasswordDefaultsGroup;
|
||||
private Duplicati.Winforms.Controls.PasswordControl CommonPassword;
|
||||
private System.Windows.Forms.CheckBox UseCommonPassword;
|
||||
private System.Windows.Forms.Panel PasswordPanel;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.CheckBox SignatureCacheEnabled;
|
||||
private System.Windows.Forms.Button SignatureCachePathBrowse;
|
||||
private System.Windows.Forms.TextBox SignatureCachePath;
|
||||
private System.Windows.Forms.FolderBrowserDialog BrowseSignatureCachePath;
|
||||
private System.Windows.Forms.Label CacheSizeLabel;
|
||||
private System.Windows.Forms.Button ClearCacheButton;
|
||||
private System.ComponentModel.BackgroundWorker CacheSizeCalculator;
|
||||
private System.Windows.Forms.ComboBox LanguageSelection;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private Duplicati.GUI.HelperControls.DurationEditor StartupDelayDuration;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.TabControl TabContainer;
|
||||
private System.Windows.Forms.TabPage BasicTab;
|
||||
private System.Windows.Forms.TabPage AdvancedTab;
|
||||
private System.Windows.Forms.GroupBox groupBox4;
|
||||
private Duplicati.GUI.HelperControls.BandwidthLimit Bandwidth;
|
||||
private Duplicati.GUI.HelperControls.ThreadPriorityPicker ThreadPriorityPicker;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Label EncryptionMethod;
|
||||
private System.Windows.Forms.ComboBox EncryptionModule;
|
||||
private System.Windows.Forms.CheckBox HideDonateButton;
|
||||
private System.Windows.Forms.TabPage LicenseTab;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.ListBox LicenseSections;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.LinkLabel LicenseLink;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.TextBox LicenseText;
|
||||
private System.Windows.Forms.ComboBox BalloonNotificationLevel;
|
||||
private System.Windows.Forms.Label label8;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Data.LightDatamodel;
|
||||
using Duplicati.Datamodel;
|
||||
using System.Globalization;
|
||||
using Duplicati.Library.Utility;
|
||||
|
||||
namespace Duplicati.GUI
|
||||
{
|
||||
public partial class ApplicationSetup : Form
|
||||
{
|
||||
private IDataFetcherWithRelations m_connection;
|
||||
private ApplicationSettings m_settings;
|
||||
private bool m_isUpdating = false;
|
||||
|
||||
//These variables handle the worker thread size calculation
|
||||
private object m_lock = new object();
|
||||
private System.Threading.Thread m_thread = null;
|
||||
private bool m_restartCalculator = false;
|
||||
|
||||
public ApplicationSetup()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
RecentDuration.SetIntervals(new List<KeyValuePair<string, string>>(
|
||||
new KeyValuePair<string, string>[]
|
||||
{
|
||||
new KeyValuePair<string, string>(Strings.Common.OneWeek, "1W"),
|
||||
new KeyValuePair<string, string>(Strings.Common.TwoWeeks, "2W"),
|
||||
new KeyValuePair<string, string>(Strings.Common.OneMonth, "1M"),
|
||||
new KeyValuePair<string, string>(Strings.Common.ThreeMonths, "3M"),
|
||||
}));
|
||||
|
||||
StartupDelayDuration.SetIntervals(new List<KeyValuePair<string, string>>(
|
||||
new KeyValuePair<string, string>[]
|
||||
{
|
||||
new KeyValuePair<string, string>(Strings.Common.NoMinutes, "0"),
|
||||
new KeyValuePair<string, string>(Strings.Common.OneMinute, "1m"),
|
||||
new KeyValuePair<string, string>(Strings.Common.FiveMinutes, "5m"),
|
||||
new KeyValuePair<string, string>(Strings.Common.FifteenMinutes, "15m"),
|
||||
new KeyValuePair<string, string>(Strings.Common.ThirtyMinutes, "30m"),
|
||||
}));
|
||||
|
||||
BalloonNotificationLevel.Items.AddRange(new object[] {
|
||||
new ComboBoxItemPair<ApplicationSettings.NotificationLevel>(Strings.ApplicationSetup.BalloonNotification_Off, ApplicationSettings.NotificationLevel.Off),
|
||||
new ComboBoxItemPair<ApplicationSettings.NotificationLevel>(Strings.ApplicationSetup.BalloonNotification_Errors, ApplicationSettings.NotificationLevel.Errors),
|
||||
new ComboBoxItemPair<ApplicationSettings.NotificationLevel>(Strings.ApplicationSetup.BalloonNotification_Warnings, ApplicationSettings.NotificationLevel.Warnings),
|
||||
new ComboBoxItemPair<ApplicationSettings.NotificationLevel>(Strings.ApplicationSetup.BalloonNotification_Start, ApplicationSettings.NotificationLevel.Start),
|
||||
new ComboBoxItemPair<ApplicationSettings.NotificationLevel>(Strings.ApplicationSetup.BalloonNotification_StartAndStop, ApplicationSettings.NotificationLevel.StartAndStop),
|
||||
new ComboBoxItemPair<ApplicationSettings.NotificationLevel>(Strings.ApplicationSetup.BalloonNotification_Continous, ApplicationSettings.NotificationLevel.Continous),
|
||||
});
|
||||
|
||||
if (Program.TraylessMode)
|
||||
BalloonNotificationLevel.Enabled = label8.Enabled = false;
|
||||
|
||||
LanguageSelection.Items.Clear();
|
||||
LanguageSelection.Items.Add(new ComboBoxItemPair<CultureInfo>(string.Format(Strings.ApplicationSetup.DefaultLanguage, Library.Utility.Utility.DefaultCulture.DisplayName), Library.Utility.Utility.DefaultCulture));
|
||||
|
||||
System.Text.RegularExpressions.Regex cix = new System.Text.RegularExpressions.Regex("[A-z][A-z](\\-[A-z][A-z])?");
|
||||
|
||||
foreach (string f in System.IO.Directory.GetDirectories(Application.StartupPath))
|
||||
if (cix.Match(System.IO.Path.GetFileName(f)).Length == System.IO.Path.GetFileName(f).Length)
|
||||
try
|
||||
{
|
||||
CultureInfo ci = CultureInfo.GetCultureInfo(System.IO.Path.GetFileName(f));
|
||||
LanguageSelection.Items.Add(new ComboBoxItemPair<CultureInfo>(ci.DisplayName, ci));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
bool hasEnglish = false;
|
||||
foreach (ComboBoxItemPair<CultureInfo> c in LanguageSelection.Items)
|
||||
if (c.Value.Name.Equals("en-US", StringComparison.InvariantCultureIgnoreCase))
|
||||
hasEnglish = true;
|
||||
|
||||
if (!hasEnglish)
|
||||
{
|
||||
CultureInfo ci = CultureInfo.GetCultureInfo("en-US");
|
||||
LanguageSelection.Items.Add(new ComboBoxItemPair<CultureInfo>(ci.DisplayName, ci));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
EncryptionModule.Items.Clear();
|
||||
|
||||
foreach (Library.Interface.IEncryption e in Library.DynamicLoader.EncryptionLoader.Modules)
|
||||
EncryptionModule.Items.Add(new ComboBoxItemPair<Library.Interface.IEncryption>(e.DisplayName, e));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, string.Format(Strings.ApplicationSetup.EncryptionModuleLoadError, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
this.Icon = Properties.Resources.TrayNormal;
|
||||
|
||||
#if DEBUG
|
||||
this.Text += " (DEBUG)";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private void RecentDuration_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating || m_settings == null)
|
||||
return;
|
||||
m_settings.RecentBackupDuration = RecentDuration.Value;
|
||||
}
|
||||
|
||||
private void OKBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (UseCommonPassword.Checked && !CommonPassword.VerifyPasswordIfChanged())
|
||||
return;
|
||||
|
||||
foreach (TabPage tab in TabContainer.TabPages)
|
||||
if (tab.Tag as Library.Interface.ISettingsControl != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(tab.Tag as Library.Interface.ISettingsControl).Validate(tab.Controls[0]))
|
||||
return;
|
||||
|
||||
(tab.Tag as Library.Interface.ISettingsControl).Leave(tab.Controls[0]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, string.Format(Strings.ApplicationSetup.SaveExtensionError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Commit all changes made to the context
|
||||
m_connection.CommitAllRecursive();
|
||||
|
||||
System.Globalization.CultureInfo newCI = System.Threading.Thread.CurrentThread.CurrentUICulture;
|
||||
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_settings.DisplayLanguage))
|
||||
newCI = Library.Utility.Utility.DefaultCulture;
|
||||
else
|
||||
newCI = System.Globalization.CultureInfo.GetCultureInfo(m_settings.DisplayLanguage);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
if (newCI != System.Threading.Thread.CurrentThread.CurrentUICulture)
|
||||
{
|
||||
MessageBox.Show(this, Strings.ApplicationSetup.LanguageChangedWarning, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
//We don't change here, because the application has loaded some
|
||||
// resources already, so the switch would be partial
|
||||
}
|
||||
|
||||
|
||||
this.DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void RecentDuration_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
RecentDuration_TextChanged(sender, e);
|
||||
}
|
||||
|
||||
private void TempPathBrowse_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (BrowseTempPath.ShowDialog(this) == DialogResult.OK)
|
||||
TempPath.Text = BrowseTempPath.SelectedPath;
|
||||
}
|
||||
|
||||
private void TempPath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
m_settings.TempPath = TempPath.Text;
|
||||
}
|
||||
|
||||
private void ApplicationSetup_Load(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Text = string.Format(Strings.ApplicationSetup.DialogTitle, License.VersionNumbers.Version);
|
||||
|
||||
m_isUpdating = true;
|
||||
|
||||
m_connection = new DataFetcherNested(Program.DataConnection);
|
||||
m_settings = new ApplicationSettings(m_connection);
|
||||
|
||||
RecentDuration.Value = m_settings.RecentBackupDuration;
|
||||
TempPath.Text = m_settings.TempPath;
|
||||
|
||||
UseCommonPassword.Checked = m_settings.UseCommonPassword;
|
||||
CommonPassword.Text = CommonPassword.InitialPassword = m_settings.CommonPassword;
|
||||
CommonPassword.AskToEnterNewPassword = !string.IsNullOrEmpty(CommonPassword.Text);
|
||||
|
||||
if (EncryptionModule.Items.Count > 0)
|
||||
{
|
||||
bool foundEncryption = false;
|
||||
int defaultIndex = 0;
|
||||
for (int i = 0; i < EncryptionModule.Items.Count; i++)
|
||||
if (((ComboBoxItemPair<Library.Interface.IEncryption>)EncryptionModule.Items[i]).Value.FilenameExtension == m_settings.CommonPasswordEncryptionModule)
|
||||
{
|
||||
foundEncryption = true;
|
||||
EncryptionModule.SelectedIndex = i;
|
||||
break;
|
||||
}
|
||||
else if (((ComboBoxItemPair<Library.Interface.IEncryption>)EncryptionModule.Items[i]).Value.FilenameExtension == "aes")
|
||||
defaultIndex = i;
|
||||
|
||||
if (!foundEncryption)
|
||||
EncryptionModule.SelectedIndex = defaultIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
PasswordDefaultsGroup.Enabled = false;
|
||||
}
|
||||
|
||||
|
||||
SignatureCacheEnabled.Checked = m_settings.SignatureCacheEnabled;
|
||||
SignatureCachePath.Text = m_settings.SignatureCachePath;
|
||||
CalculateSignatureCacheSize();
|
||||
|
||||
StartupDelayDuration.Value = m_settings.StartupDelayDuration;
|
||||
ThreadPriorityPicker.SelectedPriority = m_settings.ThreadPriorityOverride;
|
||||
Bandwidth.UploadLimit = m_settings.UploadSpeedLimit;
|
||||
Bandwidth.DownloadLimit = m_settings.DownloadSpeedLimit;
|
||||
|
||||
HideDonateButton.Checked = m_settings.HideDonateButton;
|
||||
|
||||
BalloonNotificationLevel.SelectedItem = null;
|
||||
foreach(ComboBoxItemPair<ApplicationSettings.NotificationLevel> p in BalloonNotificationLevel.Items)
|
||||
if (p.Value == m_settings.BallonNotificationLevel)
|
||||
{
|
||||
BalloonNotificationLevel.SelectedItem = p;
|
||||
break;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(m_settings.DisplayLanguage))
|
||||
LanguageSelection.SelectedIndex = 0;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
LanguageSelection.SelectedIndex = -1;
|
||||
System.Globalization.CultureInfo cci = System.Globalization.CultureInfo.GetCultureInfo(m_settings.DisplayLanguage);
|
||||
for(int i = 0; i < LanguageSelection.Items.Count; i++)
|
||||
if (((ComboBoxItemPair<CultureInfo>)LanguageSelection.Items[i]).Value == cci)
|
||||
{
|
||||
LanguageSelection.SelectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
LanguageSelection.SelectedIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
foreach (Library.Interface.ISettingsControl ic in Library.DynamicLoader.SettingsControlLoader.Modules)
|
||||
{
|
||||
Control c = ic.GetControl(m_settings.CreateDetachedCopy(), Datamodel.SettingExtension.GetExtensions(m_connection, ic.Key));
|
||||
c.Dock = DockStyle.Fill;
|
||||
TabPage tab = new TabPage();
|
||||
tab.Text = ic.PageTitle;
|
||||
tab.ToolTipText = ic.PageDescription;
|
||||
tab.Controls.Add(c);
|
||||
tab.Tag = ic;
|
||||
TabContainer.TabPages.Add(tab);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, string.Format(Strings.ApplicationSetup.SettingControlsLoadError, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
//Place the license page last
|
||||
TabContainer.TabPages.Remove(LicenseTab);
|
||||
TabContainer.TabPages.Insert(TabContainer.TabPages.Count, LicenseTab);
|
||||
|
||||
string licensePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "licenses");
|
||||
List<Duplicati.License.LicenseEntry> licenses = Duplicati.License.LicenseReader.ReadLicenses(licensePath);
|
||||
licenses.Insert(0, new Duplicati.License.LicenseEntry("Duplicati", System.IO.Path.Combine(licensePath, "duplicati-url.txt"), System.IO.Path.Combine(licensePath, "license.txt")));
|
||||
licenses.Insert(0, new Duplicati.License.LicenseEntry("Acknowledgements", System.IO.Path.Combine(licensePath, "duplicati-url.txt"), System.IO.Path.Combine(licensePath, "acknowledgements.txt")));
|
||||
|
||||
LicenseSections.Items.Clear();
|
||||
LicenseSections.Items.AddRange(licenses.ToArray());
|
||||
LicenseSections.SelectedIndex = -1;
|
||||
LicenseSections.SelectedIndex = 0;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_isUpdating = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UseCommonPassword_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
PasswordPanel.Enabled = UseCommonPassword.Checked;
|
||||
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.UseCommonPassword = UseCommonPassword.Checked;
|
||||
|
||||
if (m_settings.UseCommonPassword)
|
||||
m_settings.CommonPassword = CommonPassword.Text;
|
||||
else
|
||||
m_settings.CommonPassword = ""; //Clear it from DB
|
||||
}
|
||||
|
||||
private void CommonPassword_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.CommonPassword = CommonPassword.Text;
|
||||
}
|
||||
|
||||
private void SignatureCachePathBrowse_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (BrowseSignatureCachePath.ShowDialog(this) == DialogResult.OK)
|
||||
SignatureCachePath.Text = BrowseSignatureCachePath.SelectedPath;
|
||||
|
||||
}
|
||||
|
||||
private void SignatureCachePath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.SignatureCachePath = SignatureCachePath.Text;
|
||||
CalculateSignatureCacheSize();
|
||||
}
|
||||
|
||||
private void SignatureCacheEnabled_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
SignatureCachePath.Enabled = SignatureCachePathBrowse.Enabled = SignatureCacheEnabled.Checked;
|
||||
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.SignatureCacheEnabled = SignatureCacheEnabled.Checked;
|
||||
CalculateSignatureCacheSize();
|
||||
}
|
||||
|
||||
private void CacheSizeCalculator_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_thread = System.Threading.Thread.CurrentThread;
|
||||
|
||||
try
|
||||
{
|
||||
e.Result = string.Format(Strings.ApplicationSetup.CacheSize, Library.Utility.Utility.FormatSizeString(Library.Utility.Utility.GetDirectorySize(System.Environment.ExpandEnvironmentVariables((string)e.Argument), null)));
|
||||
}
|
||||
catch (System.Threading.ThreadAbortException)
|
||||
{
|
||||
System.Threading.Thread.ResetAbort();
|
||||
e.Cancel = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (m_lock)
|
||||
m_thread = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void CacheSizeCalculator_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (e.Cancelled)
|
||||
CacheSizeLabel.Text = Strings.ApplicationSetup.OperationCancelled;
|
||||
else if (e.Error != null)
|
||||
CacheSizeLabel.Text = e.Error.Message;
|
||||
else
|
||||
CacheSizeLabel.Text = (string)e.Result;
|
||||
|
||||
if (m_restartCalculator)
|
||||
CalculateSignatureCacheSize();
|
||||
}
|
||||
|
||||
private void CalculateSignatureCacheSize()
|
||||
{
|
||||
CacheSizeLabel.Text = Strings.ApplicationSetup.CalculatingCacheSize;
|
||||
|
||||
lock (m_lock)
|
||||
if (CacheSizeCalculator.IsBusy)
|
||||
{
|
||||
m_restartCalculator = true;
|
||||
m_thread.Abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_restartCalculator = false;
|
||||
if (SignatureCacheEnabled.Checked)
|
||||
CacheSizeCalculator.RunWorkerAsync(SignatureCachePath.Text);
|
||||
else
|
||||
CacheSizeLabel.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearCacheButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = System.Environment.ExpandEnvironmentVariables(SignatureCachePath.Text);
|
||||
if (MessageBox.Show(this, string.Format(Strings.ApplicationSetup.ConfirmCacheDelete, path), Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) != DialogResult.Yes)
|
||||
return;
|
||||
|
||||
Library.Main.Interface.RemoveSignatureFiles(path);
|
||||
CalculateSignatureCacheSize();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, string.Format(Strings.Common.GenericError, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplicationSetup_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
lock(m_lock)
|
||||
if (m_thread != null)
|
||||
{
|
||||
m_restartCalculator = false;
|
||||
m_thread.Abort();
|
||||
}
|
||||
}
|
||||
|
||||
private void LanguageSelection_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
if (LanguageSelection.SelectedIndex == 0)
|
||||
m_settings.DisplayLanguage = "";
|
||||
else if (LanguageSelection.SelectedIndex > 0)
|
||||
m_settings.DisplayLanguage = ((ComboBoxItemPair<CultureInfo>)LanguageSelection.SelectedItem).Value.Name;
|
||||
}
|
||||
|
||||
private void StartupDelayDuration_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating || m_settings == null)
|
||||
return;
|
||||
|
||||
m_settings.StartupDelayDuration = StartupDelayDuration.Value;
|
||||
}
|
||||
|
||||
private void ThreadPriorityPicker_SelectedPriorityChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.ThreadPriorityOverride = ThreadPriorityPicker.SelectedPriority;
|
||||
}
|
||||
|
||||
private void Bandwidth_UploadLimitChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.UploadSpeedLimit = Bandwidth.UploadLimit;
|
||||
}
|
||||
|
||||
private void Bandwidth_DownloadLimitChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.DownloadSpeedLimit = Bandwidth.DownloadLimit;
|
||||
}
|
||||
|
||||
private void EncryptionModule_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
if (EncryptionModule.SelectedItem as ComboBoxItemPair<Library.Interface.IEncryption> != null)
|
||||
m_settings.CommonPasswordEncryptionModule = ((ComboBoxItemPair<Library.Interface.IEncryption>)EncryptionModule.SelectedItem).Value.FilenameExtension;
|
||||
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> GetApplicationSettings(IDataFetcher connection)
|
||||
{
|
||||
Dictionary<string, string> env = new ApplicationSettings(connection).CreateDetachedCopy();
|
||||
|
||||
//If there are any control extensions, let them modify the environement
|
||||
foreach (Library.Interface.ISettingsControl ic in Library.DynamicLoader.SettingsControlLoader.Modules)
|
||||
ic.BeginEdit(env, SettingExtension.GetExtensions(connection, ic.Key));
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
public static void SaveExtensionSettings(IDataFetcher connection, IDictionary<string, string> env)
|
||||
{
|
||||
//If there are any control extensions, let them modify the environement
|
||||
foreach (Library.Interface.ISettingsControl ic in Library.DynamicLoader.SettingsControlLoader.Modules)
|
||||
ic.EndEdit(env, SettingExtension.GetExtensions(connection, ic.Key));
|
||||
}
|
||||
|
||||
private void HideDonateButton_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
m_settings.HideDonateButton = HideDonateButton.Checked;
|
||||
}
|
||||
|
||||
private void LicenseSections_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (LicenseSections.SelectedItem as Duplicati.License.LicenseEntry != null)
|
||||
{
|
||||
Duplicati.License.LicenseEntry l = LicenseSections.SelectedItem as Duplicati.License.LicenseEntry;
|
||||
LicenseText.Text = l.License;
|
||||
LicenseLink.Visible = !string.IsNullOrEmpty(l.Url);
|
||||
}
|
||||
}
|
||||
|
||||
private void LicenseLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
if (LicenseSections.SelectedItem as Duplicati.License.LicenseEntry != null)
|
||||
{
|
||||
Duplicati.License.LicenseEntry l = LicenseSections.SelectedItem as Duplicati.License.LicenseEntry;
|
||||
if (!string.IsNullOrEmpty(l.Url))
|
||||
Duplicati.Library.Utility.UrlUtillity.OpenUrl(l.Url);
|
||||
}
|
||||
}
|
||||
|
||||
private void BalloonNotificationLevel_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (m_isUpdating)
|
||||
return;
|
||||
|
||||
if (BalloonNotificationLevel.SelectedItem as ComboBoxItemPair<ApplicationSettings.NotificationLevel> != null)
|
||||
m_settings.BallonNotificationLevel = (BalloonNotificationLevel.SelectedItem as ComboBoxItemPair<ApplicationSettings.NotificationLevel>).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<settings>
|
||||
<FullBackupInterval>1M</FullBackupInterval>
|
||||
<MaxFullBackups>4</MaxFullBackups>
|
||||
<BackupExpireInterval></BackupExpireInterval>
|
||||
<RepeatInterval>1D</RepeatInterval>
|
||||
<VolumeSize>10mb</VolumeSize>
|
||||
<BackupTimeOffset>13h</BackupTimeOffset>
|
||||
<EncodedFilters>e:.*\\Thumbs.db</EncodedFilters>
|
||||
<IncludeSetup>true</IncludeSetup>
|
||||
<AsyncTransfer>true</AsyncTransfer>
|
||||
<DisableAESFallbackEncryption>true</DisableAESFallbackEncryption>
|
||||
</settings>
|
||||
@@ -0,0 +1,77 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
/// <metadata>
|
||||
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
|
||||
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Dokumenter\duplicati\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
|
||||
/// <type>Table</type>
|
||||
/// <namespace>Duplicati.Datamodel</namespace>
|
||||
/// <name>ApplicationSetting</name>
|
||||
/// <sql></sql>
|
||||
/// </metadata>
|
||||
|
||||
using System.Data.LightDatamodel;
|
||||
using System.Data.LightDatamodel.DataClassAttributes;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
|
||||
[DatabaseTable("ApplicationSetting")]
|
||||
public partial class ApplicationSetting : DataClassBase
|
||||
{
|
||||
|
||||
#region " private members "
|
||||
|
||||
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
|
||||
private System.Int64 m_ID = long.MinValue;
|
||||
[DatabaseField("Name")]
|
||||
private System.String m_Name = "";
|
||||
[DatabaseField("Value")]
|
||||
private System.String m_Value = "";
|
||||
#endregion
|
||||
|
||||
#region " properties "
|
||||
|
||||
public System.Int64 ID
|
||||
{
|
||||
get{return m_ID;}
|
||||
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Name
|
||||
{
|
||||
get{return m_Name;}
|
||||
set{object oldvalue = m_Name;OnBeforeDataChange(this, "Name", oldvalue, value);m_Name = value;OnAfterDataChange(this, "Name", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Value
|
||||
{
|
||||
get{return m_Value;}
|
||||
set{object oldvalue = m_Value;OnBeforeDataChange(this, "Value", oldvalue, value);m_Value = value;OnAfterDataChange(this, "Value", oldvalue, value);}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " referenced properties "
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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.Data.LightDatamodel;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
public class ApplicationSettings
|
||||
{
|
||||
public enum NotificationLevel
|
||||
{
|
||||
Off,
|
||||
Start,
|
||||
StartAndStop,
|
||||
Continous,
|
||||
Warnings,
|
||||
Errors
|
||||
}
|
||||
|
||||
private SettingsHelper<ApplicationSetting, string, string> m_appset;
|
||||
|
||||
private const string RECENT_DURATION = "Recent duration";
|
||||
private const string TEMP_PATH = "Temp Path";
|
||||
|
||||
private const string USE_COMMON_PASSWORD = "Use common password";
|
||||
private const string COMMON_PASSWORD_ENCRYPTION_MODULE = "Encryption module used with common password";
|
||||
private const string COMMON_PASSWORD = "Common password";
|
||||
|
||||
private const string SIGNATURE_CACHE_PATH = "Signature Cache Path";
|
||||
private const string SIGNATURE_CACHE_ENABLED = "Signature Cache Enabled";
|
||||
|
||||
private const string DISPLAY_LANGUAGE = "Display Language";
|
||||
|
||||
private const string STARTUP_DELAY_DURATION = "Startup delay duration";
|
||||
private const string THREAD_PRIORITY_OVERRIDE = "Thread priority override";
|
||||
private const string UPLOAD_SPEED_LIMIT = "Upload speed limit";
|
||||
private const string DOWNLOAD_SPEED_LIMIT = "Download speed limit";
|
||||
|
||||
private const string HIDE_DONATE_BUTTON = "Hide donate button";
|
||||
|
||||
private const string BALLON_NOTIFICATION_LEVEL = "Balloon notification level";
|
||||
|
||||
public ApplicationSettings(IDataFetcher dataparent)
|
||||
{
|
||||
m_appset = new SettingsHelper<ApplicationSetting, string, string>(dataparent, new List<ApplicationSetting>(dataparent.GetObjects<ApplicationSetting>()), "Name", "Value");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a detached copy of all the application settings
|
||||
/// </summary>
|
||||
/// <returns>A dictionary with application settings</returns>
|
||||
public Dictionary<string, string> CreateDetachedCopy()
|
||||
{
|
||||
//We need to read/write all values to make sure they have the propper defaults
|
||||
foreach (System.Reflection.PropertyInfo pi in this.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly))
|
||||
if (pi.CanRead && pi.CanWrite)
|
||||
pi.SetValue(this, pi.GetValue(this, null), null);
|
||||
|
||||
//After that, simply copy the values over
|
||||
Dictionary<string, string> res = new Dictionary<string, string>();
|
||||
foreach (KeyValuePair<string, string> k in m_appset)
|
||||
res[k.Key] = k.Value;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a reference to the internal options
|
||||
/// </summary>
|
||||
public IDictionary<string, string> RawOptions { get { return m_appset; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of time a log entry will be visible in the list of recent backups
|
||||
/// </summary>
|
||||
public string RecentBackupDuration
|
||||
{
|
||||
get { return string.IsNullOrEmpty(m_appset[RECENT_DURATION]) ? "2W" : m_appset[RECENT_DURATION]; }
|
||||
set { m_appset[RECENT_DURATION] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default Duplicati temp path
|
||||
/// </summary>
|
||||
public static string DefaultTempPath
|
||||
{
|
||||
get
|
||||
{
|
||||
#if DEBUG
|
||||
return System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "TEMP");
|
||||
#else
|
||||
return System.IO.Path.GetTempPath();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to store temporary files. May contain environment variables
|
||||
/// </summary>
|
||||
public string TempPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_appset[TEMP_PATH]))
|
||||
{
|
||||
return DefaultTempPath;
|
||||
}
|
||||
else
|
||||
return m_appset[TEMP_PATH];
|
||||
}
|
||||
set { m_appset[TEMP_PATH] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating if Duplicati should apply a common password to backups
|
||||
/// </summary>
|
||||
public bool UseCommonPassword
|
||||
{
|
||||
get
|
||||
{
|
||||
bool res;
|
||||
string tmp;
|
||||
m_appset.TryGetValue(USE_COMMON_PASSWORD, out tmp);
|
||||
|
||||
if (bool.TryParse(tmp, out res))
|
||||
return res;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
set { m_appset[USE_COMMON_PASSWORD] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the encryption module used as default
|
||||
/// </summary>
|
||||
public string CommonPasswordEncryptionModule
|
||||
{
|
||||
get
|
||||
{
|
||||
string res;
|
||||
m_appset.TryGetValue(COMMON_PASSWORD_ENCRYPTION_MODULE, out res);
|
||||
return string.IsNullOrEmpty(res) ? "aes" : res;
|
||||
}
|
||||
set { m_appset[COMMON_PASSWORD_ENCRYPTION_MODULE] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the common password applied to encrypt files.
|
||||
/// </summary>
|
||||
public string CommonPassword
|
||||
{
|
||||
get
|
||||
{
|
||||
string res;
|
||||
m_appset.TryGetValue(COMMON_PASSWORD, out res);
|
||||
return string.IsNullOrEmpty(res) ? "" : res;
|
||||
}
|
||||
set { m_appset[COMMON_PASSWORD] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default Duplicati signature cache path
|
||||
/// </summary>
|
||||
public static string DefaultSignatureCachePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Duplicati.Library.Utility.Utility.IsClientLinux)
|
||||
return System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%DUPLICATI_HOME%").TrimStart('"').TrimEnd('"'), "Signature Cache");
|
||||
else
|
||||
return System.IO.Path.Combine(System.IO.Path.Combine(Environment.ExpandEnvironmentVariables(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)), "Duplicati"), "Signature Cache");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to store signature cache files. May contain environment variables
|
||||
/// </summary>
|
||||
public string SignatureCachePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_appset[SIGNATURE_CACHE_PATH]))
|
||||
{
|
||||
return DefaultSignatureCachePath;
|
||||
}
|
||||
else
|
||||
return m_appset[SIGNATURE_CACHE_PATH];
|
||||
}
|
||||
set { m_appset[SIGNATURE_CACHE_PATH] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating if the signature cache should be used.
|
||||
/// </summary>
|
||||
public bool SignatureCacheEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
bool res;
|
||||
if (bool.TryParse(m_appset[SIGNATURE_CACHE_ENABLED], out res))
|
||||
return res;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
set { m_appset[SIGNATURE_CACHE_ENABLED] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the language used in the user interface
|
||||
/// </summary>
|
||||
public string DisplayLanguage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_appset[DISPLAY_LANGUAGE]))
|
||||
return "";
|
||||
else
|
||||
return m_appset[DISPLAY_LANGUAGE];
|
||||
}
|
||||
set { m_appset[DISPLAY_LANGUAGE] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of time Duplicati will be paused after startup
|
||||
/// </summary>
|
||||
public string StartupDelayDuration
|
||||
{
|
||||
get { return string.IsNullOrEmpty(m_appset[STARTUP_DELAY_DURATION]) ? "5m" : m_appset[STARTUP_DELAY_DURATION]; }
|
||||
set { m_appset[STARTUP_DELAY_DURATION] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the thread priority used for the backup thread
|
||||
/// </summary>
|
||||
public System.Threading.ThreadPriority? ThreadPriorityOverride
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_appset[THREAD_PRIORITY_OVERRIDE]))
|
||||
return null;
|
||||
else
|
||||
return Library.Utility.Utility.ParsePriority(m_appset[THREAD_PRIORITY_OVERRIDE]);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
m_appset[THREAD_PRIORITY_OVERRIDE] = "";
|
||||
else
|
||||
m_appset[THREAD_PRIORITY_OVERRIDE] = value.Value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper limit for download speeds
|
||||
/// </summary>
|
||||
public string DownloadSpeedLimit
|
||||
{
|
||||
get { return m_appset[DOWNLOAD_SPEED_LIMIT]; }
|
||||
set { m_appset[DOWNLOAD_SPEED_LIMIT] = value == null ? "" : value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper limit for upload speeds
|
||||
/// </summary>
|
||||
public string UploadSpeedLimit
|
||||
{
|
||||
get { return m_appset[UPLOAD_SPEED_LIMIT]; }
|
||||
set { m_appset[UPLOAD_SPEED_LIMIT] = value == null ? "" : value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating if the donate button in Duplicati should be hidden
|
||||
/// </summary>
|
||||
public bool HideDonateButton
|
||||
{
|
||||
get
|
||||
{
|
||||
string tmp;
|
||||
m_appset.TryGetValue(HIDE_DONATE_BUTTON, out tmp);
|
||||
|
||||
return Duplicati.Library.Utility.Utility.ParseBool(tmp, false);
|
||||
}
|
||||
set { m_appset[HIDE_DONATE_BUTTON] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the balloon notification level
|
||||
/// </summary>
|
||||
public NotificationLevel BallonNotificationLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
string v;
|
||||
m_appset.TryGetValue(BALLON_NOTIFICATION_LEVEL, out v);
|
||||
if (!string.IsNullOrEmpty(v))
|
||||
try { return (NotificationLevel)Enum.Parse(typeof(NotificationLevel), v); }
|
||||
catch { }
|
||||
|
||||
return NotificationLevel.Warnings;
|
||||
}
|
||||
set { m_appset[BALLON_NOTIFICATION_LEVEL] = value.ToString(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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("Dulicati.Datamodel")]
|
||||
[assembly: AssemblyDescription("The datamodel for Duplicati")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("Duplicati")]
|
||||
[assembly: AssemblyCopyright("LGPL, Copyright © HexaD 2009")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: ComVisibleAttribute(false)]
|
||||
[assembly: AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
@@ -0,0 +1,92 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
/// <metadata>
|
||||
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
|
||||
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Dokumenter\duplicati\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
|
||||
/// <type>Table</type>
|
||||
/// <namespace>Duplicati.Datamodel</namespace>
|
||||
/// <name>BackendSetting</name>
|
||||
/// <sql></sql>
|
||||
/// </metadata>
|
||||
|
||||
using System.Data.LightDatamodel;
|
||||
using System.Data.LightDatamodel.DataClassAttributes;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
|
||||
[DatabaseTable("BackendSetting")]
|
||||
public partial class BackendSetting : DataClassBase
|
||||
{
|
||||
|
||||
#region " private members "
|
||||
|
||||
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
|
||||
private System.Int64 m_ID = long.MinValue;
|
||||
[Relation("BackendSettingTask", typeof(Task), "ID"), DatabaseField("TaskID")]
|
||||
private System.Int64 m_TaskID = long.MinValue;
|
||||
[DatabaseField("Name")]
|
||||
private System.String m_Name = "";
|
||||
[DatabaseField("Value")]
|
||||
private System.String m_Value = "";
|
||||
#endregion
|
||||
|
||||
#region " properties "
|
||||
|
||||
public System.Int64 ID
|
||||
{
|
||||
get{return m_ID;}
|
||||
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.Int64 TaskID
|
||||
{
|
||||
get{return m_TaskID;}
|
||||
set{object oldvalue = m_TaskID;OnBeforeDataChange(this, "TaskID", oldvalue, value);m_TaskID = value;OnAfterDataChange(this, "TaskID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Name
|
||||
{
|
||||
get{return m_Name;}
|
||||
set{object oldvalue = m_Name;OnBeforeDataChange(this, "Name", oldvalue, value);m_Name = value;OnAfterDataChange(this, "Name", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Value
|
||||
{
|
||||
get{return m_Value;}
|
||||
set{object oldvalue = m_Value;OnBeforeDataChange(this, "Value", oldvalue, value);m_Value = value;OnAfterDataChange(this, "Value", oldvalue, value);}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " referenced properties "
|
||||
|
||||
[Affects(typeof(Task))]
|
||||
public Task Task
|
||||
{
|
||||
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<Task>("BackendSettingTask", this); }
|
||||
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("BackendSettingTask", this, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
/// <metadata>
|
||||
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
|
||||
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Dokumenter\duplicati\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
|
||||
/// <type>Table</type>
|
||||
/// <namespace>Duplicati.Datamodel</namespace>
|
||||
/// <name>CommandQueue</name>
|
||||
/// <sql></sql>
|
||||
/// </metadata>
|
||||
|
||||
using System.Data.LightDatamodel;
|
||||
using System.Data.LightDatamodel.DataClassAttributes;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
|
||||
[DatabaseTable("CommandQueue")]
|
||||
public partial class CommandQueue : DataClassBase
|
||||
{
|
||||
|
||||
#region " private members "
|
||||
|
||||
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
|
||||
private System.Int64 m_ID = long.MinValue;
|
||||
[DatabaseField("Command")]
|
||||
private System.String m_Command = "";
|
||||
[DatabaseField("Argument")]
|
||||
private System.String m_Argument = "";
|
||||
[DatabaseField("Completed")]
|
||||
private System.Boolean m_Completed = false;
|
||||
#endregion
|
||||
|
||||
#region " properties "
|
||||
|
||||
public System.Int64 ID
|
||||
{
|
||||
get{return m_ID;}
|
||||
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Command
|
||||
{
|
||||
get{return m_Command;}
|
||||
set{object oldvalue = m_Command;OnBeforeDataChange(this, "Command", oldvalue, value);m_Command = value;OnAfterDataChange(this, "Command", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Argument
|
||||
{
|
||||
get{return m_Argument;}
|
||||
set{object oldvalue = m_Argument;OnBeforeDataChange(this, "Argument", oldvalue, value);m_Argument = value;OnAfterDataChange(this, "Argument", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.Boolean Completed
|
||||
{
|
||||
get{return m_Completed;}
|
||||
set{object oldvalue = m_Completed;OnBeforeDataChange(this, "Completed", oldvalue, value);m_Completed = value;OnAfterDataChange(this, "Completed", oldvalue, value);}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " referenced properties "
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
/// <metadata>
|
||||
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
|
||||
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Documents\duplicati\gpg-commandline-settings\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
|
||||
/// <type>Table</type>
|
||||
/// <namespace>Duplicati.Datamodel</namespace>
|
||||
/// <name>CompressionSetting</name>
|
||||
/// <sql></sql>
|
||||
/// </metadata>
|
||||
|
||||
using System.Data.LightDatamodel;
|
||||
using System.Data.LightDatamodel.DataClassAttributes;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
|
||||
[DatabaseTable("CompressionSetting")]
|
||||
public partial class CompressionSetting : DataClassBase
|
||||
{
|
||||
|
||||
#region " private members "
|
||||
|
||||
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
|
||||
private System.Int64 m_ID = long.MinValue;
|
||||
[Relation("CompressionSettingTask", typeof(Task), "ID"), DatabaseField("TaskID")]
|
||||
private System.Int64 m_TaskID = long.MinValue;
|
||||
[DatabaseField("Name")]
|
||||
private System.String m_Name = "";
|
||||
[DatabaseField("Value")]
|
||||
private System.String m_Value = "";
|
||||
#endregion
|
||||
|
||||
#region " properties "
|
||||
|
||||
public System.Int64 ID
|
||||
{
|
||||
get{return m_ID;}
|
||||
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.Int64 TaskID
|
||||
{
|
||||
get{return m_TaskID;}
|
||||
set{object oldvalue = m_TaskID;OnBeforeDataChange(this, "TaskID", oldvalue, value);m_TaskID = value;OnAfterDataChange(this, "TaskID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Name
|
||||
{
|
||||
get{return m_Name;}
|
||||
set{object oldvalue = m_Name;OnBeforeDataChange(this, "Name", oldvalue, value);m_Name = value;OnAfterDataChange(this, "Name", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Value
|
||||
{
|
||||
get{return m_Value;}
|
||||
set{object oldvalue = m_Value;OnBeforeDataChange(this, "Value", oldvalue, value);m_Value = value;OnAfterDataChange(this, "Value", oldvalue, value);}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " referenced properties "
|
||||
|
||||
[Affects(typeof(Task))]
|
||||
public Task Task
|
||||
{
|
||||
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<Task>("CompressionSettingTask", this); }
|
||||
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("CompressionSettingTask", this, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "Task" ADD COLUMN "IgnoreTimestamps" BOOLEAN NULL;
|
||||
@@ -0,0 +1,57 @@
|
||||
-- TaskSettings becomes BackendSetting
|
||||
ALTER TABLE TaskSetting RENAME TO BackendSetting;
|
||||
|
||||
-- TaskSetting is now extensions
|
||||
CREATE TABLE "TaskExtension" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
-- Copy values from the Task table
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Max Upload Size', [MaxUploadSize] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Upload bandwidth', [UploadBandwidth] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Download Bandwidth', [DownloadBandwidth] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Volume Size', [VolumeSize] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Thread Priority', [ThreadPriority] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Async Transfer', [AsyncTransfer] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Include Setup', [IncludeSetup] FROM Task;
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [ID], 'Ignore Timestamps', [IgnoreTimestamps] FROM Task;
|
||||
|
||||
-- Move FileTimeSeparator into extensions
|
||||
INSERT INTO TaskExtension ([TaskID], [Name], [Value]) SELECT [TaskID], 'File Time Seperator', Value FROM BackendSetting WHERE [Name] = 'TimeSeparator';
|
||||
DELETE FROM BackendSetting WHERE [Name] = 'TimeSeparator';
|
||||
|
||||
-- Create a reduced Task table
|
||||
CREATE TABLE "TempTask" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"ScheduleID" INTEGER NULL,
|
||||
"Service" TEXT NULL,
|
||||
"Encryptionkey" TEXT NULL,
|
||||
"Signaturekey" TEXT NULL,
|
||||
"SourcePath" TEXT NULL,
|
||||
"KeepFull" INTEGER NULL,
|
||||
"KeepTime" TEXT NULL,
|
||||
"FullAfter" TEXT NULL,
|
||||
"GPGEncryption" BOOLEAN NULL,
|
||||
"IncludeSetup" BOOLEAN NULL
|
||||
);
|
||||
|
||||
-- Copy values
|
||||
INSERT INTO TempTask ([ID], [ScheduleID], [Service], [EncryptionKey], [SignatureKey], [SourcePath], [KeepFull], [KeepTime], [FullAfter], [GPGEncryption], [IncludeSetup]) SELECT [ID], [ScheduleID], [Service], [EncryptionKey], [SignatureKey], [SourcePath], [KeepFull], [KeepTime], [FullAfter], [GPGEncryption], [IncludeSetup] FROM Task;
|
||||
DROP TABLE Task;
|
||||
|
||||
-- Use the new reduced table
|
||||
ALTER TABLE "TempTask" RENAME TO "Task";
|
||||
|
||||
-- Add the override table
|
||||
CREATE TABLE "TaskOverride" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
-- Reduce database size
|
||||
VACUUM;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Set existing SSH connections to be unmanaged
|
||||
INSERT INTO "BackendSetting" ("TaskID", "Name", "Value") SELECT [ID], 'Use Unmanaged SSH', 'True' FROM Task WHERE "Service" LIKE 'ssh';
|
||||
@@ -0,0 +1,66 @@
|
||||
-- Refactor the GPGEncryption column to now use EncryptionModule instead
|
||||
ALTER TABLE "Task" ADD COLUMN "EncryptionModule" TEXT NULL;
|
||||
ALTER TABLE "Task" ADD COLUMN "CompressionModule" TEXT NULL;
|
||||
|
||||
UPDATE "Task" SET "EncryptionModule"="aes";
|
||||
UPDATE "Task" SET "EncryptionModule"="gpg" WHERE "GPGEncryption" = 1;
|
||||
|
||||
-- Create a reduced Task table
|
||||
CREATE TABLE "TempTask" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"ScheduleID" INTEGER NULL,
|
||||
"Service" TEXT NULL,
|
||||
"Encryptionkey" TEXT NULL,
|
||||
"Signaturekey" TEXT NULL,
|
||||
"SourcePath" TEXT NULL,
|
||||
"KeepFull" INTEGER NULL,
|
||||
"KeepTime" TEXT NULL,
|
||||
"FullAfter" TEXT NULL,
|
||||
"EncryptionModule" TEXT NULL,
|
||||
"CompressionModule" TEXT NULL,
|
||||
"IncludeSetup" BOOLEAN NULL
|
||||
);
|
||||
|
||||
INSERT INTO TempTask ([ID], [ScheduleID], [Service], [EncryptionKey], [SignatureKey], [SourcePath], [KeepFull], [KeepTime], [FullAfter], [EncryptionModule], [CompressionModule], [IncludeSetup]) SELECT [ID], [ScheduleID], [Service], [EncryptionKey], [SignatureKey], [SourcePath], [KeepFull], [KeepTime], [FullAfter], [EncryptionModule], [CompressionModule], [IncludeSetup] FROM Task;
|
||||
|
||||
DROP TABLE "Task";
|
||||
ALTER TABLE "TempTask" RENAME TO "Task";
|
||||
|
||||
-- SettingExtension is now supported
|
||||
CREATE TABLE "SettingExtension" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"SettingKey" TEXT NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
-- Add the compression setting table
|
||||
CREATE TABLE "CompressionSetting" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
-- Add the encryption setting table
|
||||
CREATE TABLE "EncryptionSetting" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
-- Use the GPG indicator to set the compression module value
|
||||
UPDATE "ApplicationSetting" SET [Name] = "Encryption module used with common password" WHERE [Name] LIKE "Use PGP with common password";
|
||||
UPDATE "ApplicationSetting" SET [Value] = "aes" WHERE [Name] LIKE "Encryption module used with common password" AND [Value] LIKE "False";
|
||||
UPDATE "ApplicationSetting" SET [Value] = "gpg" WHERE [Name] LIKE "Encryption module used with common password" AND [Value] LIKE "True";
|
||||
|
||||
-- Move the SFTP path into the controls settings, instead of the application settings
|
||||
INSERT INTO "SettingExtension" ([SettingKey], [Name], [Value]) SELECT "ssh-settings", [Name], [Value] FROM "ApplicationSetting" WHERE [Name] LIKE "SFTP Path";
|
||||
DELETE FROM "ApplicationSetting" WHERE [Name] LIKE "SFTP Path";
|
||||
|
||||
-- Move the GPG path into the controls settings, instead of the application settings, fixing the PGP -> GPG mistake on the way
|
||||
INSERT INTO "SettingExtension" ([SettingKey], [Name], [Value]) SELECT "gpg-settings", "GPG Path", [Value] FROM "ApplicationSetting" WHERE [Name] LIKE "PGP Path";
|
||||
DELETE FROM "ApplicationSetting" WHERE [Name] LIKE "PGP Path";
|
||||
|
||||
VACUUM;
|
||||
@@ -0,0 +1,20 @@
|
||||
CREATE TABLE "TempTask" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"ScheduleID" INTEGER NULL,
|
||||
"Service" TEXT NULL,
|
||||
"Encryptionkey" TEXT NULL,
|
||||
"SourcePath" TEXT NULL,
|
||||
"KeepFull" INTEGER NULL,
|
||||
"KeepTime" TEXT NULL,
|
||||
"FullAfter" TEXT NULL,
|
||||
"EncryptionModule" TEXT NULL,
|
||||
"CompressionModule" TEXT NULL,
|
||||
"IncludeSetup" BOOLEAN NULL
|
||||
);
|
||||
|
||||
INSERT INTO TempTask ([ID], [ScheduleID], [Service], [EncryptionKey], [SourcePath], [KeepFull], [KeepTime], [FullAfter], [EncryptionModule], [CompressionModule], [IncludeSetup]) SELECT [ID], [ScheduleID], [Service], [EncryptionKey], [SourcePath], [KeepFull], [KeepTime], [FullAfter], [EncryptionModule], [CompressionModule], [IncludeSetup] FROM Task;
|
||||
|
||||
DROP TABLE "Task";
|
||||
ALTER TABLE "TempTask" RENAME TO "Task";
|
||||
|
||||
VACUUM;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
-- Remove unused options
|
||||
DELETE FROM TaskExtension WHERE [Name] LIKE 'File Time Seperator';
|
||||
DELETE FROM TaskExtension WHERE [Name] LIKE 'Short Filenames';
|
||||
|
||||
-- Remove any empty filename prefixes which should be most common
|
||||
DELETE FROM TaskExtension WHERE [Name] LIKE 'Filename Prefix' AND ([Value] LIKE '' OR [Value] IS NULL);
|
||||
|
||||
-- Move any non-empty filename prefixes into the manual settings override
|
||||
INSERT INTO TaskOverride ([TaskID], [Name], [Value]) SELECT [TaskID], 'filename-prefix', [Value] FROM TaskExtension WHERE [Name] LIKE 'Filename Prefix';
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "Log" ADD COLUMN "ParsedMessage" TEXT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "TaskFilter" ADD COLUMN "GlobbingFilter" TEXT NULL;
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE "ScheduleMetadata" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"ScheduleID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
@@ -0,0 +1,118 @@
|
||||
CREATE TABLE "Task" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"ScheduleID" INTEGER NULL,
|
||||
"Service" TEXT NULL,
|
||||
"Encryptionkey" TEXT NULL,
|
||||
"SourcePath" TEXT NULL,
|
||||
"KeepFull" INTEGER NULL,
|
||||
"KeepTime" TEXT NULL,
|
||||
"FullAfter" TEXT NULL,
|
||||
"EncryptionModule" TEXT NULL,
|
||||
"CompressionModule" TEXT NULL,
|
||||
"IncludeSetup" BOOLEAN NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "Schedule" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"Name" TEXT NULL,
|
||||
"Path" TEXT NULL,
|
||||
"When" DATETIME NULL,
|
||||
"Repeat" TEXT NULL,
|
||||
"Weekdays" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "BackendSetting" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "TaskExtension" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "TaskOverride" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "CommandQueue" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"Command" TEXT NULL,
|
||||
"Argument" TEXT NULL,
|
||||
"Completed" BOOLEAN NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "Log" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"EndTime" DATETIME NULL,
|
||||
"BeginTime" DATETIME NULL,
|
||||
"Action" TEXT NULL,
|
||||
"SubAction" TEXT NULL,
|
||||
"Transfersize" INTEGER NULL,
|
||||
"ParsedStatus" TEXT NULL,
|
||||
"ParsedMessage" TEXT NULL,
|
||||
"LogBlobID" INTEGER NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "LogBlob" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"Data" BLOB NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "Version" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"Version" INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE "ApplicationSetting" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "TaskFilter" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"SortOrder" INTEGER NULL,
|
||||
"Include" BOOLEAN NULL,
|
||||
"Filter" TEXT NULL,
|
||||
"TaskID" INTEGER NULL,
|
||||
"GlobbingFilter" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "SettingExtension" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"SettingKey" TEXT NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "CompressionSetting" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "EncryptionSetting" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"TaskID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "ScheduleMetadata" (
|
||||
"ID" INTEGER PRIMARY KEY,
|
||||
"ScheduleID" INTEGER NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Value" TEXT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "Version" ("Version") VALUES (9);
|
||||
@@ -0,0 +1,185 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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.Data;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
/// <summary>
|
||||
/// This class will read embedded files from the given folder.
|
||||
/// Updates should have the form "1.Sample upgrade.sql".
|
||||
/// When the database schema changes, simply put a new file into the folder.
|
||||
/// Each upgrade file should ONLY upgrade from the previous version.
|
||||
/// If done correctly, a user may be upgrade from the very first version
|
||||
/// to the very latest.
|
||||
///
|
||||
/// The Schema.sql file should ALWAYS have the latests schema, as that will
|
||||
/// ensure that new installs do not run upgrades after installation.
|
||||
/// Also remember to update the last line in Schema.sql to insert the
|
||||
/// current version number in the version table.
|
||||
///
|
||||
/// Currently no upgrades may contain semicolons, except as the SQL statement
|
||||
/// delimiter.
|
||||
/// </summary>
|
||||
public static class DatabaseUpgrader
|
||||
{
|
||||
//This is the "folder" where the embedded resources can be found
|
||||
private const string FOLDER_NAME = "Database_schema";
|
||||
|
||||
//This is the name of the schema sql
|
||||
private const string SCHEMA_NAME = "Schema.sql";
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the database is up to date
|
||||
/// </summary>
|
||||
/// <param name="connection">The database connection to use</param>
|
||||
/// <param name="sourcefile">The file the database is placed in</param>
|
||||
public static void UpgradeDatabase(IDbConnection connection, string sourcefile)
|
||||
{
|
||||
//Shorthand for current assembly
|
||||
System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
|
||||
if (connection.State != ConnectionState.Open)
|
||||
{
|
||||
if (string.IsNullOrEmpty(connection.ConnectionString))
|
||||
connection.ConnectionString = "Data Source=" + sourcefile;
|
||||
|
||||
connection.Open();
|
||||
}
|
||||
|
||||
|
||||
int dbversion = 0;
|
||||
IDbCommand cmd = connection.CreateCommand();
|
||||
try
|
||||
{
|
||||
//See if the version table is present,
|
||||
cmd.CommandText = "SELECT COUNT(*) FROM SQLITE_MASTER WHERE Name LIKE 'Version'";
|
||||
|
||||
int count = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
|
||||
if (count == 0)
|
||||
dbversion = -1; //Empty
|
||||
else if (count == 1)
|
||||
{
|
||||
cmd.CommandText = "SELECT max(Version) FROM Version";
|
||||
dbversion = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
else
|
||||
throw new Exception(Strings.DatabaseUpgrader.TableLayoutError);
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
//Hopefully a more explanatory error message
|
||||
throw new Exception(string.Format(Strings.DatabaseUpgrader.DatabaseFormatError, ex.Message), ex);
|
||||
}
|
||||
|
||||
|
||||
//On a new database, we just load the most current schema, and upgrade from there
|
||||
//This avoids potentitally lenghty upgrades
|
||||
if (dbversion == -1)
|
||||
{
|
||||
cmd.CommandText = new System.IO.StreamReader(asm.GetManifestResourceStream(typeof(DatabaseUpgrader), FOLDER_NAME + "." + SCHEMA_NAME)).ReadToEnd();
|
||||
cmd.ExecuteNonQuery();
|
||||
UpgradeDatabase(connection, sourcefile);
|
||||
return;
|
||||
}
|
||||
|
||||
//Get updates, and sort them according to version
|
||||
//This enables upgrading through several versions
|
||||
//ea, from 1 to 8, by stepping 2->3->4->5->6->7->8
|
||||
SortedDictionary<int, string> upgrades = new SortedDictionary<int, string>();
|
||||
string prefix = typeof(DatabaseUpgrader).Namespace + "." + FOLDER_NAME + ".";
|
||||
int maxversion = -1;
|
||||
foreach (string s in asm.GetManifestResourceNames())
|
||||
{
|
||||
//The resource name will be "Duplicati.GUI.Database_schema.1.Sample upgrade.sql"
|
||||
//The number indicates the version that will be upgraded to
|
||||
if (s.StartsWith(prefix) && !s.Equals(prefix + SCHEMA_NAME))
|
||||
{
|
||||
try
|
||||
{
|
||||
string version = s.Substring(prefix.Length, s.IndexOf(".", prefix.Length + 1) - prefix.Length);
|
||||
int fileversion = int.Parse(version);
|
||||
maxversion = Math.Max(maxversion, fileversion);
|
||||
if (fileversion > dbversion)
|
||||
{
|
||||
if (!upgrades.ContainsKey(fileversion))
|
||||
upgrades.Add(fileversion, "");
|
||||
upgrades[fileversion] += new System.IO.StreamReader(asm.GetManifestResourceStream(s)).ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dbversion > maxversion)
|
||||
throw new Exception(string.Format(Strings.DatabaseUpgrader.InvalidVersionError, dbversion, maxversion, System.IO.Path.GetDirectoryName(sourcefile)));
|
||||
|
||||
if (upgrades.Count > 0)
|
||||
{
|
||||
string backupfile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(sourcefile), Strings.DatabaseUpgrader.BackupFilenamePrefix + " " + DateTime.Now.ToString("yyyyMMddhhmmss") + ".sqlite");
|
||||
|
||||
try
|
||||
{
|
||||
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(backupfile)))
|
||||
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(backupfile));
|
||||
|
||||
//Keep a backup
|
||||
System.IO.File.Copy(sourcefile, backupfile, false);
|
||||
|
||||
int newversion = dbversion;
|
||||
foreach (int key in upgrades.Keys)
|
||||
{
|
||||
//TODO: Find a better way to split SQL statements, as there may be embedded semicolons
|
||||
//in the SQL, like "UPDATE x WHERE y = ';';"
|
||||
|
||||
//We split them to get a better error message
|
||||
foreach(string c in upgrades[key].Split(';'))
|
||||
if (c.Trim().Length > 0)
|
||||
{
|
||||
cmd.CommandText = c;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
newversion = Math.Max(newversion, key);
|
||||
}
|
||||
|
||||
//Update databaseversion, so we don't run the scripts again
|
||||
cmd.CommandText = "Update version SET Version = " + newversion.ToString();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
connection.Close();
|
||||
//Restore the database
|
||||
System.IO.File.Copy(backupfile, sourcefile, true);
|
||||
throw new Exception(string.Format(Strings.DatabaseUpgrader.UpgradeFailure, cmd.CommandText, ex.Message), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<AssemblyKeyContainerName />
|
||||
<AssemblyName>Datamodel</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Duplicati.Datamodel</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation />
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<Optimize>true</Optimize>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<DebugType>none</DebugType>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="LightDatamodel">
|
||||
<HintPath>..\..\..\thirdparty\LightDataModel\LightDatamodel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="SettingsHelper.cs" />
|
||||
<Compile Include="Task.Extension.cs" />
|
||||
<Compile Include="Task.cs" />
|
||||
<Compile Include="Schedule.cs" />
|
||||
<Compile Include="CommandQueue.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="LogBlob.cs" />
|
||||
<Compile Include="ApplicationSettings.cs" />
|
||||
<Compile Include="ApplicationSetting.cs" />
|
||||
<Compile Include="TaskFilter.cs" />
|
||||
<Compile Include="BackendSetting.cs" />
|
||||
<Compile Include="TaskExtension.cs" />
|
||||
<Compile Include="TaskOverride.cs" />
|
||||
<Compile Include="SettingExtension.cs" />
|
||||
<Compile Include="CompressionSetting.cs" />
|
||||
<Compile Include="EncryptionSetting.cs" />
|
||||
<Compile Include="ScheduleMetadata.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="Duplicati.snk" />
|
||||
<Compile Include="Log.Extension.cs" />
|
||||
<Compile Include="LogBlob.Extension.cs" />
|
||||
<Compile Include="Schedule.Extension.cs" />
|
||||
<Compile Include="SettingExtension.Extension.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Library.Utility</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\1. Support timestamp flag.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\2. Refactor for easier extensions.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\3. Default managed SSH.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\4. Support for setting controls.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\5. Remove signaturekey.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\6. Remove TimeSeparator and UseShortFilenames.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\7. Add error message field to log.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\8. Add filter fields.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\9. Add Schedule Metadata table.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Database schema\Schema.sql" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
/// <metadata>
|
||||
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
|
||||
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Documents\duplicati\gpg-commandline-settings\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
|
||||
/// <type>Table</type>
|
||||
/// <namespace>Duplicati.Datamodel</namespace>
|
||||
/// <name>EncryptionSetting</name>
|
||||
/// <sql></sql>
|
||||
/// </metadata>
|
||||
|
||||
using System.Data.LightDatamodel;
|
||||
using System.Data.LightDatamodel.DataClassAttributes;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
|
||||
[DatabaseTable("EncryptionSetting")]
|
||||
public partial class EncryptionSetting : DataClassBase
|
||||
{
|
||||
|
||||
#region " private members "
|
||||
|
||||
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
|
||||
private System.Int64 m_ID = long.MinValue;
|
||||
[Relation("EncryptionSettingTask", typeof(Task), "ID"), DatabaseField("TaskID")]
|
||||
private System.Int64 m_TaskID = long.MinValue;
|
||||
[DatabaseField("Name")]
|
||||
private System.String m_Name = "";
|
||||
[DatabaseField("Value")]
|
||||
private System.String m_Value = "";
|
||||
#endregion
|
||||
|
||||
#region " properties "
|
||||
|
||||
public System.Int64 ID
|
||||
{
|
||||
get{return m_ID;}
|
||||
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.Int64 TaskID
|
||||
{
|
||||
get{return m_TaskID;}
|
||||
set{object oldvalue = m_TaskID;OnBeforeDataChange(this, "TaskID", oldvalue, value);m_TaskID = value;OnAfterDataChange(this, "TaskID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Name
|
||||
{
|
||||
get{return m_Name;}
|
||||
set{object oldvalue = m_Name;OnBeforeDataChange(this, "Name", oldvalue, value);m_Name = value;OnAfterDataChange(this, "Name", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Value
|
||||
{
|
||||
get{return m_Value;}
|
||||
set{object oldvalue = m_Value;OnBeforeDataChange(this, "Value", oldvalue, value);m_Value = value;OnAfterDataChange(this, "Value", oldvalue, value);}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " referenced properties "
|
||||
|
||||
[Affects(typeof(Task))]
|
||||
public Task Task
|
||||
{
|
||||
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<Task>("EncryptionSettingTask", this); }
|
||||
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("EncryptionSettingTask", this, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
public partial class Log
|
||||
{
|
||||
public string TransferSizeString
|
||||
{
|
||||
get
|
||||
{
|
||||
return Library.Utility.Utility.FormatSizeString(this.Transfersize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2011, Kenneth Skovhede
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// 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
|
||||
/// <metadata>
|
||||
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
|
||||
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Dokumenter\duplicati\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
|
||||
/// <type>Table</type>
|
||||
/// <namespace>Duplicati.Datamodel</namespace>
|
||||
/// <name>Log</name>
|
||||
/// <sql></sql>
|
||||
/// </metadata>
|
||||
|
||||
using System.Data.LightDatamodel;
|
||||
using System.Data.LightDatamodel.DataClassAttributes;
|
||||
|
||||
namespace Duplicati.Datamodel
|
||||
{
|
||||
|
||||
[DatabaseTable("Log")]
|
||||
public partial class Log : DataClassBase
|
||||
{
|
||||
|
||||
#region " private members "
|
||||
|
||||
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
|
||||
private System.Int64 m_ID = long.MinValue;
|
||||
[Relation("LogTask", typeof(Task), "ID"), DatabaseField("TaskID")]
|
||||
private System.Int64 m_TaskID = long.MinValue;
|
||||
[DatabaseField("EndTime")]
|
||||
private System.DateTime m_EndTime = new System.DateTime(1, 1, 1);
|
||||
[DatabaseField("BeginTime")]
|
||||
private System.DateTime m_BeginTime = new System.DateTime(1, 1, 1);
|
||||
[DatabaseField("Action")]
|
||||
private System.String m_Action = "";
|
||||
[DatabaseField("SubAction")]
|
||||
private System.String m_SubAction = "";
|
||||
[DatabaseField("Transfersize")]
|
||||
private System.Int64 m_Transfersize = long.MinValue;
|
||||
[DatabaseField("ParsedStatus")]
|
||||
private System.String m_ParsedStatus = "";
|
||||
[DatabaseField("ParsedMessage")]
|
||||
private System.String m_ParsedMessage = "";
|
||||
[Relation("LogBlob", typeof(LogBlob), "ID"), DatabaseField("LogBlobID")]
|
||||
private System.Int64 m_LogBlobID = long.MinValue;
|
||||
#endregion
|
||||
|
||||
#region " properties "
|
||||
|
||||
public System.Int64 ID
|
||||
{
|
||||
get{return m_ID;}
|
||||
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.Int64 TaskID
|
||||
{
|
||||
get{return m_TaskID;}
|
||||
set{object oldvalue = m_TaskID;OnBeforeDataChange(this, "TaskID", oldvalue, value);m_TaskID = value;OnAfterDataChange(this, "TaskID", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.DateTime EndTime
|
||||
{
|
||||
get{return m_EndTime;}
|
||||
set{object oldvalue = m_EndTime;OnBeforeDataChange(this, "EndTime", oldvalue, value);m_EndTime = value;OnAfterDataChange(this, "EndTime", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.DateTime BeginTime
|
||||
{
|
||||
get{return m_BeginTime;}
|
||||
set{object oldvalue = m_BeginTime;OnBeforeDataChange(this, "BeginTime", oldvalue, value);m_BeginTime = value;OnAfterDataChange(this, "BeginTime", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String Action
|
||||
{
|
||||
get{return m_Action;}
|
||||
set{object oldvalue = m_Action;OnBeforeDataChange(this, "Action", oldvalue, value);m_Action = value;OnAfterDataChange(this, "Action", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String SubAction
|
||||
{
|
||||
get{return m_SubAction;}
|
||||
set{object oldvalue = m_SubAction;OnBeforeDataChange(this, "SubAction", oldvalue, value);m_SubAction = value;OnAfterDataChange(this, "SubAction", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.Int64 Transfersize
|
||||
{
|
||||
get{return m_Transfersize;}
|
||||
set{object oldvalue = m_Transfersize;OnBeforeDataChange(this, "Transfersize", oldvalue, value);m_Transfersize = value;OnAfterDataChange(this, "Transfersize", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String ParsedStatus
|
||||
{
|
||||
get{return m_ParsedStatus;}
|
||||
set{object oldvalue = m_ParsedStatus;OnBeforeDataChange(this, "ParsedStatus", oldvalue, value);m_ParsedStatus = value;OnAfterDataChange(this, "ParsedStatus", oldvalue, value);}
|
||||
}
|
||||
|
||||
public System.String ParsedMessage
|
||||
{
|
||||
get { return m_ParsedMessage; }
|
||||
set { object oldvalue = m_ParsedMessage; OnBeforeDataChange(this, "ParsedMessage", oldvalue, value); m_ParsedMessage = value; OnAfterDataChange(this, "ParsedMessage", oldvalue, value); }
|
||||
}
|
||||
|
||||
public System.Int64 LogBlobID
|
||||
{
|
||||
get{return m_LogBlobID;}
|
||||
set{object oldvalue = m_LogBlobID;OnBeforeDataChange(this, "LogBlobID", oldvalue, value);m_LogBlobID = value;OnAfterDataChange(this, "LogBlobID", oldvalue, value);}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " referenced properties "
|
||||
|
||||
[Affects(typeof(Task))]
|
||||
public Task OwnerTask
|
||||
{
|
||||
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<Task>("LogTask", this); }
|
||||
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("LogTask", this, value); }
|
||||
}
|
||||
|
||||
[Affects(typeof(LogBlob))]
|
||||
public LogBlob Blob
|
||||
{
|
||||
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<LogBlob>("LogBlob", this); }
|
||||
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("LogBlob", this, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user