</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
- <PostBuildEvent>nunit-console.exe "$(TargetPath)"</PostBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
</PropertyGroup>
<!-- 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.
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Configuration" />
+ <Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
+ <Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Project>{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}</Project>
<Name>Pithos.Network</Name>
</ProjectReference>
+ <ProjectReference Include="..\Pithos.ShellExtensions\Pithos.ShellExtensions.csproj">
+ <Project>{240B432F-1030-4623-BCC3-FF351D6C1B63}</Project>
+ <Name>Pithos.ShellExtensions</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="App_Code\LICENSE.txt" />
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabAccount = new System.Windows.Forms.TabPage();
this.btnAccountVerify = new System.Windows.Forms.Button();
- this.txtApiKey = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
- this.textBox1 = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnRemoveAccount = new System.Windows.Forms.Button();
this.btnAddAccount = new System.Windows.Forms.Button();
this.tabAdvanced = new System.Windows.Forms.TabPage();
this.btnBrowsePithosPath = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
- this.txtPithosPath = new System.Windows.Forms.TextBox();
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.systemMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.openPithosFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.btnCancel = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.pithosFolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
+ this.checkActivateExtensions = new System.Windows.Forms.CheckBox();
+ this.txtApiKey = new System.Windows.Forms.TextBox();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.txtPithosPath = new System.Windows.Forms.TextBox();
this.tabControl1.SuspendLayout();
this.tabAccount.SuspendLayout();
this.tabAdvanced.SuspendLayout();
this.btnAccountVerify.Text = "Verify";
this.btnAccountVerify.UseVisualStyleBackColor = true;
//
- // txtApiKey
- //
- this.txtApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.txtApiKey.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "ApiKey", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
- this.txtApiKey.Location = new System.Drawing.Point(208, 63);
- this.txtApiKey.Name = "txtApiKey";
- this.txtApiKey.Size = new System.Drawing.Size(234, 20);
- this.txtApiKey.TabIndex = 6;
- this.txtApiKey.Text = global::Pithos.Client.Properties.Settings.Default.ApiKey;
- //
// label2
//
this.label2.AutoSize = true;
this.label2.TabIndex = 5;
this.label2.Text = "API 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.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "UserName", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
- this.textBox1.Location = new System.Drawing.Point(208, 22);
- this.textBox1.Name = "textBox1";
- this.textBox1.Size = new System.Drawing.Size(234, 20);
- this.textBox1.TabIndex = 4;
- this.textBox1.Text = global::Pithos.Client.Properties.Settings.Default.UserName;
- //
// label1
//
this.label1.AutoSize = true;
//
// tabAdvanced
//
+ this.tabAdvanced.Controls.Add(this.checkActivateExtensions);
this.tabAdvanced.Controls.Add(this.btnBrowsePithosPath);
this.tabAdvanced.Controls.Add(this.label3);
this.tabAdvanced.Controls.Add(this.txtPithosPath);
this.label3.TabIndex = 0;
this.label3.Text = "Pithos Folder";
//
- // txtPithosPath
- //
- this.txtPithosPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "PithosPath", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
- this.txtPithosPath.Location = new System.Drawing.Point(11, 28);
- this.txtPithosPath.Name = "txtPithosPath";
- this.txtPithosPath.Size = new System.Drawing.Size(279, 20);
- this.txtPithosPath.TabIndex = 1;
- this.txtPithosPath.Text = global::Pithos.Client.Properties.Settings.Default.PithosPath;
- //
// notifyIcon
//
this.notifyIcon.BalloonTipText = "All Files Up to Date";
this.pithosFolderBrowser.Description = "Select a folder to synchronize with Pithos";
this.pithosFolderBrowser.RootFolder = System.Environment.SpecialFolder.Personal;
//
+ // checkActivateExtensions
+ //
+ this.checkActivateExtensions.AutoSize = true;
+ this.checkActivateExtensions.Checked = global::Pithos.Client.Properties.Settings.Default.ExtensionsActivated;
+ this.checkActivateExtensions.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.checkActivateExtensions.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Pithos.Client.Properties.Settings.Default, "ExtensionsActivated", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+ this.checkActivateExtensions.Location = new System.Drawing.Point(11, 67);
+ this.checkActivateExtensions.Name = "checkActivateExtensions";
+ this.checkActivateExtensions.Size = new System.Drawing.Size(151, 17);
+ this.checkActivateExtensions.TabIndex = 3;
+ this.checkActivateExtensions.Text = "Shell Extensions Activated";
+ this.checkActivateExtensions.UseVisualStyleBackColor = true;
+ this.checkActivateExtensions.CheckedChanged += new System.EventHandler(this.checkActivateExtensions_CheckedChanged);
+ //
+ // txtApiKey
+ //
+ this.txtApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtApiKey.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "ApiKey", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+ this.txtApiKey.Location = new System.Drawing.Point(208, 63);
+ this.txtApiKey.Name = "txtApiKey";
+ this.txtApiKey.Size = new System.Drawing.Size(234, 20);
+ this.txtApiKey.TabIndex = 6;
+ this.txtApiKey.Text = global::Pithos.Client.Properties.Settings.Default.ApiKey;
+ //
+ // 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.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "UserName", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+ this.textBox1.Location = new System.Drawing.Point(208, 22);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(234, 20);
+ this.textBox1.TabIndex = 4;
+ this.textBox1.Text = global::Pithos.Client.Properties.Settings.Default.UserName;
+ //
+ // txtPithosPath
+ //
+ this.txtPithosPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "PithosPath", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+ this.txtPithosPath.Location = new System.Drawing.Point(11, 28);
+ this.txtPithosPath.Name = "txtPithosPath";
+ this.txtPithosPath.Size = new System.Drawing.Size(279, 20);
+ this.txtPithosPath.TabIndex = 1;
+ this.txtPithosPath.Text = global::Pithos.Client.Properties.Settings.Default.PithosPath;
+ //
// Preferences
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
private System.Windows.Forms.TextBox txtPithosPath;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.FolderBrowserDialog pithosFolderBrowser;
+ private System.Windows.Forms.CheckBox checkActivateExtensions;
}
}
\ No newline at end of file
using System;
+using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Data;
using System.Diagnostics;
using System.Drawing;
+using System.IO;
+using System.IO.IsolatedStorage;
using System.Linq;
using System.Reflection;
+using System.Runtime.Serialization;
using System.Text;
using System.Windows.Forms;
using Pithos.Client.Properties;
using Pithos.Core;
using Pithos.Interfaces;
+using Pithos.ShellExtensions;
namespace Pithos.Client
{
{
}
+
+ private void checkActivateExtensions_CheckedChanged(object sender, EventArgs e)
+ {
+ var box = (CheckBox) sender;
+ if (box.Checked)
+ RegisterExtensions();
+ else
+ UnregisterExtensions();
+ }
+
+ private void UnregisterExtensions()
+ {
+ using (var installer = new ProjectInstaller())
+ {
+ IDictionary state = LoadState();
+ installer.Uninstall(state);
+ }
+ }
+
+ private void RegisterExtensions()
+ {
+ using (var installer = new ProjectInstaller())
+ {
+ IDictionary state = new Dictionary<object, object>();
+ installer.Install(state);
+ SaveState(state);
+
+ }
+ }
+
+ private static void SaveState(IDictionary state)
+ {
+ using(var store= IsolatedStorageFile.GetUserStoreForApplication())
+ using(var file=store.CreateFile("PithosManualInstallFile"))
+ {
+ var serializer = new NetDataContractSerializer();
+ serializer.Serialize(file,state);
+ }
+ }
+
+ private static IDictionary LoadState()
+ {
+ using (var store = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ if (!store.FileExists("PithosManualInstallFile"))
+ return new Dictionary<object, object>();
+
+ using (var file = store.OpenFile("PithosManualInstallFile", FileMode.Open))
+ {
+ var serializer = new NetDataContractSerializer();
+ var state = serializer.Deserialize(file);
+ return (IDictionary) state;
+ }
+ }
+ }
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string Setting {
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool ExtensionsActivated {
get {
- return ((string)(this["Setting"]));
+ return ((bool)(this["ExtensionsActivated"]));
}
set {
- this["Setting"] = value;
+ this["ExtensionsActivated"] = value;
}
}
<Setting Name="ProxyAuthentication" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
- <Setting Name="Setting" Type="System.String" Scope="User">
- <Value Profile="(Default)" />
+ <Setting Name="ExtensionsActivated" Type="System.Boolean" Scope="User">
+ <Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="UserName" Type="System.String" Scope="User">
<Value Profile="(Default)">pkanavos</Value>
<setting name="ProxyAuthentication" serializeAs="String">
<value>False</value>
</setting>
- <setting name="Setting" serializeAs="String">
- <value />
+ <setting name="ExtensionsActivated" serializeAs="String">
+ <value>True</value>
</setting>
<setting name="UserName" serializeAs="String">
<value>pkanavos</value>
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
+using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
CancellationTokenSource _cancellationSource;
- BlockingCollection<WorkflowState> _fileEvents = new BlockingCollection<WorkflowState>();
+ readonly BlockingCollection<WorkflowState> _fileEvents = new BlockingCollection<WorkflowState>();
+ readonly BlockingCollection<WorkflowState> _uploadEvents = new BlockingCollection<WorkflowState>();
public void Start()
{
- string path = Settings.PithosPath;
-
- CloudClient.Authenticate(Settings.UserName,Settings.ApiKey);
if (_cancellationSource != null)
{
if (!_cancellationSource.IsCancellationRequested)
return;
}
- _cancellationSource=new CancellationTokenSource();
- StartListening();
- StartSending();
+ _cancellationSource = new CancellationTokenSource();
+ string path = Settings.PithosPath;
+ StartMonitoringFiles(path);
- _watcher = new FileSystemWatcher(path);
- _watcher.Changed += OnFileEvent;
- _watcher.Created += OnFileEvent;
- _watcher.Deleted += OnFileEvent;
- _watcher.Renamed += OnRenameEvent;
- _watcher.EnableRaisingEvents = true;
+ StartNetwork();
+ }
+
+ private void StartNetwork()
+ {
+ bool connected = NetworkInterface.GetIsNetworkAvailable();
+ //If we are not connected retry later
+ if (!connected)
+ {
+ Task.Factory.StartNewDelayed(10000, StartNetwork);
+ return;
+ }
+
+ try
+ {
+ CloudClient.Authenticate(Settings.UserName, Settings.ApiKey);
+
+ StartListening();
+ StartSending();
+ }
+ catch (Exception)
+ {
+ //Faild to authenticate due to network or account error
+ //Retry after a while
+ Task.Factory.StartNewDelayed(10000, StartNetwork);
+ }
}
internal enum CloudActionType
}
}
- private void StartSending()
+ private void StartMonitoringFiles(string path)
{
+ _watcher = new FileSystemWatcher(path);
+ _watcher.Changed += OnFileEvent;
+ _watcher.Created += OnFileEvent;
+ _watcher.Deleted += OnFileEvent;
+ _watcher.Renamed += OnRenameEvent;
+ _watcher.EnableRaisingEvents = true;
+
Task.Factory.StartNew(() =>
{
foreach (var state in _fileEvents.GetConsumingEnumerable())
UpdateFileStatus(state);
UpdateOverlayStatus(state);
UpdateFileChecksum(state);
+ _uploadEvents.Add(state);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch(Exception ex)
+ {}
+ }
+
+ },_cancellationSource.Token);
+ }
+
+ private void StartSending()
+ {
+ Task.Factory.StartNew(() =>
+ {
+ foreach (var state in _uploadEvents.GetConsumingEnumerable())
+ {
+ try
+ {
SynchToCloud(state);
}
catch (OperationCanceledException)
using System;
+using System.Collections;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
+using Microsoft.Win32;
using NUnit.Framework;
using Pithos.ShellExtensions.Overlays;
*/
}
+
+ [Test]
+ public void TestRegister()
+ {
+ var installer = new ProjectInstaller();
+ IDictionary state=new Dictionary<object,object>();
+ installer.Install(state);
+
+ using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\TortoiseOverlays\Normal"))
+ {
+ var values = key.GetValueNames();
+ Assert.Contains("Pithos",values);
+ }
+
+ installer.Uninstall(state);
+ }
+
[Test]
+ public void TestUnRegister()
+ {
+ var installer = new ProjectInstaller();
+ IDictionary state = new Dictionary<object, object>();
+ installer.Install(state);
+ installer.Uninstall(state);
+
+
+ using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\TortoiseOverlays\Normal"))
+ {
+ var values = key.GetValueNames();
+ Assert.IsFalse(values.Contains("Pithos"));
+ }
+
+
+ }
+
+
+ /*[Test]
public void CreateOverlayTest()
{
var normalOverlay=new NormalIconOverlay();
var synchOverlay = new SynchIconOverlay();
Assert.AreEqual(Path.Combine(iconPath, "SynchIcon.ico"), synchOverlay.IconPath);
- }
+ }*/
[Test]
public void TestMembership()
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
+ <Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
{
try
{
- string overlayName = PithosPrefix + iconName;
- ShellExtReg.RegisterIconOverlayIdentifier(t.GUID, overlayName);
+
+ ShellExtReg.RegisterIconOverlayIdentifier(t.GUID, iconName);
NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST,
IntPtr.Zero, IntPtr.Zero);
public static void UnregisterOverlay(Type t,string iconName)
{
try
- {
- string overlayName = PithosPrefix + iconName;
- ShellExtReg.UnregisterIconOverlayIdentifier(t.GUID, overlayName);
+ {
+ ShellExtReg.UnregisterIconOverlayIdentifier(t.GUID, iconName);
Trace.Write("UnRegistered icon handler");
}
catch (Exception ex)
namespace Pithos.ShellExtensions.Overlays
{
- [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
+ /* [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
[Guid("20FCF62D-E553-48FA-99B8-6C0A4E1C5D55")]
public class SynchIconOverlay: IconOverlayBase
{
#endregion
- }
+ }*/
}
\ No newline at end of file
<Compile Include="TestPithosSettings.cs" />
<Compile Include="TestStatusChecker.cs" />
</ItemGroup>
- <ItemGroup />
<ItemGroup>
<None Include="app.config" />
<None Include="pithos.snk" />
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>if exist "$(TargetPath).locked" del "$(TargetPath).locked"
+if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"
+
+if exist "$(TargetDir)Pithos.Interfaces.dll.locked" del "$(TargetDir)Pithos.Interfaces.dll.locked"
+if exist "$(TargetDir)Pithos.Interfaces.dll" if not exist "$(TargetDir)Pithos.Interfaces.dll.locked" move "$(TargetDir)Pithos.Interfaces.dll" "$(TargetDir)Pithos.Interfaces.dll.locked"</PreBuildEvent>
+ </PropertyGroup>
<!-- 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">
throw new ArgumentException("friendlyName must not be null or empty");
}
- // Create the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
- string keyName = string.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\{0}",
+ // Create the key HKLM\SOFTWARE\TortoiseOverlays\<IconName>\Pithos={<CLSID>}.
+ string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}",
friendlyName);
- using (RegistryKey key = Registry.LocalMachine.CreateSubKey(keyName))
+ using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName,true))
{
// Set the default value of the key.
if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
{
- key.SetValue(null, clsid.ToString("B"));
+ key.SetValue("Pithos", clsid.ToString("B"),RegistryValueKind.String);
}
}
}
}
- // Remove the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
- string keyName = string.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\{0}",
+ string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}",
friendlyName);
- Registry.ClassesRoot.DeleteSubKeyTree(keyName, false);
+ using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true))
+ {
+ // Set the default value of the key.
+ if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
+ {
+ key.DeleteValue("Pithos");
+ }
+ }
}
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|x86.ActiveCfg = Debug|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Any CPU.Build.0 = Release|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|x86.ActiveCfg = Debug|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Any CPU.Build.0 = Release|Any CPU