25
26
using Canonical.UbuntuOne.Common.Container;
26
27
using Canonical.UbuntuOne.Common.Update;
27
28
using Canonical.UbuntuOne.Common.Utils;
29
using Canonical.UbuntuOne.ProcessDispatcher;
30
32
namespace UbuntuOneClient
96
98
/// Allows to get and set the presenter that knows how to deal with the settings.
98
100
internal IPreferencesDialogPresenter PreferencesDialogPresenter { get; set; }
103
/// Gets and sets the listener that will be used to listen to messages from the python code.
105
internal IPipeListener PipeListener { get; set; }
101
109
#region Helper methods
110
118
if (!Updater.UpdatesArePresent()) return;
111
119
_logger.Info("Updates are available.");
112
120
Updater.PerformUpdate();
113
}catch(SelfUpdateException ex)
122
catch (SelfUpdateException ex)
115
124
_logger.WarnFormat("Application could not be update {0}", ex);
134
143
// we are goign to load the current settings
135
144
// TODO: using the presenter here is very ugly.
136
145
PreferencesDialogPresenter.LoadPreferences();
146
PipeListener.StartListening(string.Format("PythonMessages{0}", WindowsIdentity.GetCurrent().Name));
137
147
// we do not worry about looping to allow the other thread to finish, we no that app should take longer
138
148
Application.Run(NotifyIcon as Window);
158
169
static void Main()
160
// HACK: This technique is quite interesting although it is a hack. The idea is the following,
161
// due to the fact that we want to run a WCF service per user and not per machine, we have to be able
162
// to determine at runtime the users pipe names. To do so we would use a config file per user
163
// but ofcourse we cannot do that at install time becuase we do not know all the user.
165
// Ideally we would not have to do this hack and the ConfiguratonManager would allow to refrest the app
166
// condifuration, but it is not the case!! On top of that you cannot do so by using reflection :(
168
// The trick is simple, we use the normal app.config to start the program, once the program is started we create
169
// a new app domain where we will be doing all the work. Because we are the ones starting the app domain, we can
170
// tell him to use a diff configuration, which means that we poit to a new config for this user that points to
171
// the correct pipe names :D
172
// This is not cheap, now we have a dummy app domain, the one that start this program, and a second app domain that
173
// is used to load the spring context plus all the WCT setting. The SeriesAppDomain is the one that really does
175
171
_logger.Info("Updating config");
176
172
// init the objects container
177
173
// Setup information for the new appdomain.
178
var setup = new AppDomainSetup
180
ConfigurationFile = _configLocator.GetCurrentUserClientConfiguration()
183
// Create the new appdomain with the new config.
184
var executionAppDomain = AppDomain.CreateDomain("ClientAppDomain", AppDomain.CurrentDomain.Evidence, setup);
186
// Call the write config method in that appdomain.
187
executionAppDomain.DoCallBack(() =>
189
ObjectsContainer.Initialize(new SpringContainer());
190
var program = ObjectsContainer.GetImplementationOf<Program>();
191
program.StartApplication();
175
ObjectsContainer.Initialize(new SpringContainer());
176
var program = ObjectsContainer.GetImplementationOf<Program>();
177
program.StartApplication();