Skip to content

Commit

Permalink
Merge branch 'release/1.0.5'
Browse files Browse the repository at this point in the history
* release/1.0.5: (45 commits)
  Bump version
  Update changelog
  More README tweaks
  Don't log empty lines from Syncthing
  Try and close Syncthing gracefully on application exit
  Tweak installer
  Tweak README
  Tweak build configurations
  Improve ConfigurationProvider logging
  Copy syncthing.exe from backup if newer than version in AppData
  Add logging to ConfigurationProvider
  Move to providing the title in the Window, not the VM
  Finish adding open source licenses window
  Don't allow saving settings to set autostart in Debug
  Make a start on a Third Party Components page
  Remove SyncthingPath from Configuration
  Correct initialisation order in ConfigurationProvider
  Add instructions to install .net 4.5 to standalone bit of REAMDE
  Add locking so ConfigurationProvider
  Fix Rakefile
  ...
  • Loading branch information
canton7 committed Mar 7, 2015
2 parents 2b37034 + b3ff0a8 commit 5443097
Show file tree
Hide file tree
Showing 58 changed files with 2,185 additions and 266 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ installer/syncthing.exe
*.tmp
Coverage
RefitStubs.cs
SyncTrayzorPortable
10 changes: 10 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Changelog
=========

v1.0.5
------

- Replace syncthing.exe in APPDATA if it goes missing for some reason
- Add option to run Syncthing with a custom home directory
- Add portable build
- Add 'Minimize to Tray' option
- Improve error messages and logging
- Close Synchthing gracefully on application exit

v1.0.4
------

Expand Down
52 changes: 47 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,65 @@ Features include:

- Has a built-in web browser, so you don't need to fire up an external browser.
- Optionally starts on login, so you don't need to set up Syncthing as a service.
- Can watch your folders for changes, and informs Syncthing about them instantly. This means you can have large polling intervals, but still have changes propagated straight await.
- Optional tray messages when folders have finished syncing.
- Can watch your folders for changes, so you don't have to poll them frequently:
- Syncthing on its own has to poll your folders, in order to see if any files have changed.
- SyncTrayzor will watch your folders for changes, and alert Syncthing the second anything changes.
- This means you can increase the polling interval in Syncthing, avoiding the resource usage of high-frequency polling, but still have any changes propagated straight away.
- Folder watching respects the ignores configured in Syncthing.
- Tray icon indicates when synchronization is occurring.
- Optional tray messages when folders have finished syncing.


![Screenshot](readme/screenshot.png)

Installation
------------

Grab the latest installer from the [releases](https://github.com/canton7/SyncTrayzor/releases) tab.
SyncTrayzor is packged as both an installer and a standalone zip.

### Installer

Grab and run the latest installer from the [releases](https://github.com/canton7/SyncTrayzor/releases) tab.
If you already have SyncTrayzor installed, this will update it.

### Standalone

First, you'll need .net 4.5. [Download the offline](http://www.microsoft.com/en-gb/download/details.aspx?id=42642) or
[web installer](http://www.microsoft.com/en-gb/download/details.aspx?id=42643) if you don't have it installed already.

Grab the latest standalone .zip from the [releases](https://github.com/canton7/SyncTrayzor/releases) tab.
Unzip, and run `SyncTrayzor.exe`. If you're updating, you'll need to copy the `data` folder across from your previous standalone installation.


What will SyncTrayzor do to my system?
--------------------------------------

Good question. The answer depends on whether you installed SyncTrayzor using the installer, or are running it standalone.

### Installer

SyncTrayzor will install itself into `C:\Program Files\SyncTrayzor`.

By default, SyncTrayzor will put its own configuration in `C:\Users\<You>\AppData\Roaming\SyncTrayor`, and let Syncthing use its default folder for its database, which is `C:\Users\<You>\AppData\Local\Syncthing`.
It will also create a registry key at `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\SyncTrayzor` the first time that it is run, which will let it start when you log in.

You can delete this registry key by unchecking "Automatically start on login" in the settings.

If you check "Use custom home directory or Syncthing" in the settings, then SyncTrayzor will tell Syncthing to use `C:\Users\<You>\AppData\Local\SyncTrayzor\syncthing` for its database.
This is useful if you want to keep the copy of Syncthing managed by SyncTrayzor separate from another copy running on your machine.

### Standalone

SyncTrayzor will put its own configuration in `SyncTrayzorPortable\data`, and tell Syncthing to use `SyncTrayzorPortable\data\syncthing` for its database.
This means that, when upgrading, you can simply move the 'data' folder over to move all your settings, and database.
If you uncheck "Use custom home directory or Syncthing" in the settings, then Syncthing will use its default folder for its database, which is `C:\Users\<You>\AppData\Local\Syncthing`.

The portable version won't start on login by default. If you check "Automatically start on login" in the settings, then a registry key will be created at `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\SyncTrayzor`.


Building from Source
--------------------

You'll need [Visual Studio 2013](http://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx).
Clone/download the repository, open `src\SyncTrayzor.sln`, and compile.
For Debug builds, you'll need to [download syncthing.exe](https://github.com/syncthing/syncthing/releases) and place it in the `bin\x86\Debug` or `bin\x64\Debug` folder, as appropriate.
For Release builds, you'll need to place it in `%APPDATA%\SyncTrayzor`.
You'll also need to [download syncthing.exe](https://github.com/syncthing/syncthing/releases) and place it in the `bin\x86\Debug`, `bin\x64\Debug`, `bin\x86\Release`, or `bin\x64\Release` folder as appropriate.
92 changes: 92 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
require 'rexml/document'
begin
require 'albacore'
rescue LoadError
warn "Please run 'gem install albacore --pre'"
exit 1
end

ISCC = '"C:\Program Files (x86)\Inno Setup 5\ISCC.exe"'

BIN_DIR = 'bin/x64/Release'
SRC_DIR = 'src/SyncTrayzor'
INSTALLER_DIR = 'installer'
INSTALLER = File.join(INSTALLER_DIR, 'SyncTrayzorSetup.exe')

PORTABLE_OUTPUT_DIR = File.absolute_path('SyncTrayzorPortable')

CONFIG = ENV['CONFIG'] || 'Release'
PLATFORM = ENV['PLATFORM'] || 'x64'

def cp_to_portable(src)
dest = File.join(PORTABLE_OUTPUT_DIR, src)
mkdir_p File.dirname(dest) unless File.exist?(File.dirname(dest))
cp src, dest
end

desc 'Build the project'
build :build do |b|
b.sln = 'src/SyncTrayzor.sln'
b.target = [:Clean, :Build]
b.prop 'Configuration', CONFIG
b.prop 'Platform', PLATFORM
end

task :installer do
rm INSTALLER if File.exist?(INSTALLER)
sh ISCC, File.join(INSTALLER_DIR, 'installer.iss')
end

desc 'Create the portable release directory'
task :portable do
rm_rf PORTABLE_OUTPUT_DIR
mkdir_p PORTABLE_OUTPUT_DIR

Dir.chdir(BIN_DIR) do
files = FileList[
'*.exe',
'*.exe.config',
'*.dll',
'*.pdb',
'*.pak',
'*.dat',
File.join('locales', '*'),
].exclude('*.vshost.*')

files.each do |file|
cp_to_portable(file)
end
end

cp File.join(SRC_DIR, 'Icons', 'default.ico'), PORTABLE_OUTPUT_DIR

FileList['*.md', '*.txt'].each do |file|
cp_to_portable(file)
end

Dir.chdir(INSTALLER_DIR) do
FileList['syncthing.exe', '*.dll'].each do |file|
cp_to_portable(file)
end
end

puts 'Rewriting app.config'
config_path = File.join(PORTABLE_OUTPUT_DIR, 'SyncTrayzor.exe.config')
doc = File.open(config_path, 'r') do |f|
doc = REXML::Document.new(f)
REXML::XPath.first(doc, '/configuration/applicationSettings//setting[@name="PortableMode"]/value').text = 'True'
doc
end
File.open(config_path, 'w') do |f|
doc.write(f)
end
end

desc 'Build and package everything'
task :package => [:build, :installer, :portable]

desc 'Remove portable and installer'
task :clean do
rm_rf PORTABLE_OUTPUT_DIR if File.exist?(PORTABLE_OUTPUT_DIR)
rm INSTALLER if File.exist?(INSTALLER)
end
19 changes: 3 additions & 16 deletions installer/installer.iss
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Source: "{#AppSrc}\Icons\default.ico"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#AppRoot}\*.md"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#AppRoot}\*.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "syncthing.exe"; DestDir: "{userappdata}\{#AppDataFolder}"
Source: "syncthing.exe"; DestDir: "{app}"
Source: "dotNet451Setup.exe"; DestDir: {tmp}; Flags: deleteafterinstall; Check: FrameworkIsNotInstalled

[Icons]
Expand All @@ -76,19 +76,6 @@ begin
result := not exists or (release < 378758);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then begin
{ Since we're shifting from 32-bit to 64-bit, clean up the 32-bit installation dir }
if DirExists(ExpandConstant('{pf32}\SyncTrayzor')) then
DelTree(ExpandConstant('{pf32}\SyncTrayzor'), True, True, True);
{ If we mistakenly wrote to the admin user's registry before, undo that now }
if RegValueExists(HKCU64, ExpandConstant('{#RunRegKey}'), 'SyncTrayzor') then
RegDeleteValue(HKCU64, ExpandConstant('{#RunRegKey}'), 'SyncTrayzor');
end;
end;
[UninstallDelete]
Type: files; Name: "{userappdata}\{#AppDataFolder}\config.xml"
Type: dirifempty; Name: "{userappdata}\{#AppDataFolder}"
Type: filesandordirs; Name: "{userappdata}\{#AppDataFolder}"
Type: filesandordirs; Name: "{userappdata}\{#AppDataFolder}"
4 changes: 2 additions & 2 deletions src/SyncTrayzor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ Global
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Debug|x86.Build.0 = Debug|x86
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Release|x64.ActiveCfg = Release|x64
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Release|x64.Build.0 = Release|x64
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Release|x86.ActiveCfg = Release|x64
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Release|x86.Build.0 = Release|x64
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Release|x86.ActiveCfg = Release|x86
{D1F89B3D-7967-4DC6-AE45-50A7817FE54F}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
14 changes: 14 additions & 0 deletions src/SyncTrayzor/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<section name="SyncTrayzor.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>

</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
Expand All @@ -27,6 +28,9 @@
<setting name="IssuesUrl" serializeAs="String">
<value>http://github.com/canton7/SyncTrayzor/issues</value>
</setting>
<setting name="PortableMode" serializeAs="String">
<value>False</value>
</setting>
</SyncTrayzor.Properties.Settings>
</applicationSettings>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Expand All @@ -41,10 +45,20 @@
layout="${longdate} [${level}] ${logger}: ${message} ${exception:format=type,message,method,stacktrace,tostring:maxInnerExceptionLevel=10:innerFormat=shortType,message,method}"/>
<target name="debugger" type="Debugger"
layout="${time} [${level}] ${logger:shortName=true} ${message}"/>
<target name="syncthinglogfile" type="file"
fileName="${gdc:item=LogFilePath}\syncthing.log"
createDirs="True"
archiveFileName="${gdc:item=LogFilePath}\logs archive\syncthing.{#}.log"
archiveEvery="Day"
archiveNumbering="Date"
maxArchiveFiles="7"
layout="${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile"/>
<logger name="*" minlevel="Debug" writeTo="debugger"/>
<logger name="SyncTrayzor.SyncThing.SyncThingProcessRunner" min="Debug" writeTo="syncthinglogfile"/>
</rules>
</nlog>

</configuration>
2 changes: 1 addition & 1 deletion src/SyncTrayzor/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<s:ApplicationLoader.MergedDictionaries>
<ResourceDictionary Source="NotifyIcon/TaskbarIconResources.xaml"/>
<ResourceDictionary Source="Xaml/Styles.xaml"/>
<ResourceDictionary Source="Xaml/Resources.xaml"/>
</s:ApplicationLoader.MergedDictionaries>
</s:ApplicationLoader>
</Application.Resources>
Expand Down
36 changes: 32 additions & 4 deletions src/SyncTrayzor/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using StyletIoC;
using SyncTrayzor.NotifyIcon;
using SyncTrayzor.Pages;
using SyncTrayzor.Properties;
using SyncTrayzor.Services;
using SyncTrayzor.Services.UpdateChecker;
using SyncTrayzor.SyncThing;
Expand All @@ -12,6 +13,7 @@
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
Expand Down Expand Up @@ -39,13 +41,32 @@ protected override void ConfigureIoC(IStyletIoCBuilder builder)

protected override void Configure()
{
GlobalDiagnosticsContext.Set("LogFilePath", this.Container.Get<IConfigurationProvider>().BasePath);
var configurationProvider = this.Container.Get<IConfigurationProvider>();
// Debug builds are always 'portable'
#if DEBUG
configurationProvider.IsPortableMode = true;
#else
configurationProvider.IsPortableMode = Settings.Default.PortableMode;
#endif
configurationProvider.EnsureEnvironmentConsistency();

GlobalDiagnosticsContext.Set("LogFilePath", configurationProvider.LogFilePath);

// Must be done before ConfigurationApplicator.ApplyConfiguration
var autostartProvider = this.Container.Get<IAutostartProvider>();
#if DEBUG
this.Container.Get<IAutostartProvider>().IsEnabled = false;
autostartProvider.IsEnabled = false;
#endif

if (autostartProvider.CanWrite)
{
// If it's not in portable mode, and if we had to create config (i.e. it's the first start ever), then enable autostart
// Else, keep the config as it was, but update the path to us (if we're not in debug)
if (!configurationProvider.IsPortableMode && configurationProvider.HadToCreateConfiguration)
autostartProvider.SetAutoStart(new AutostartConfiguration() { AutoStart = true, StartMinimized = true });
else
autostartProvider.UpdatePathToSelf();
}

var notifyIconManager = this.Container.Get<INotifyIconManager>();
notifyIconManager.Setup((INotifyIconDelegate)this.RootViewModel);
this.Container.Get<ConfigurationApplicator>().ApplyConfiguration();
Expand All @@ -70,7 +91,8 @@ protected override void OnLaunch()
((ShellViewModel)this.RootViewModel).Start();

// We don't care if this fails
this.Container.Get<IUpdateChecker>().CheckForUpdatesAsync();
if (config.NotifyOfNewVersions)
this.Container.Get<IUpdateChecker>().CheckForUpdatesAsync();
}

protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e)
Expand All @@ -92,5 +114,11 @@ protected override void OnUnhandledException(DispatcherUnhandledExceptionEventAr
windowManager.ShowDialog(vm);
}
}

protected override void OnExit(ExitEventArgs e)
{
// Try and be nice and close SyncTrayzor gracefully, before the Dispose call on SyncThingProcessRunning kills it dead
this.Container.Get<ISyncThingManager>().StopAsync().Wait(500);
}
}
}
Loading

0 comments on commit 5443097

Please sign in to comment.