diff --git a/Confuser.Core/ConfuserEngine.cs b/Confuser.Core/ConfuserEngine.cs index 3b1d6e1..3b9c342 100644 --- a/Confuser.Core/ConfuserEngine.cs +++ b/Confuser.Core/ConfuserEngine.cs @@ -64,19 +64,19 @@ namespace Confuser.Core { context.token = token; - var asmResolver = new AssemblyResolver(); - asmResolver.EnableTypeDefCache = true; - asmResolver.DefaultModuleContext = new ModuleContext(asmResolver); - context.Resolver = asmResolver; - context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, parameters.Project.BaseDirectory + "\\"); - context.OutputDirectory = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.OutputDirectory + "\\"); - foreach (string probePath in parameters.Project.ProbePaths) - asmResolver.PostSearchPaths.Add(Path.Combine(context.BaseDirectory, probePath)); - PrintInfo(context); bool ok = false; try { + var asmResolver = new AssemblyResolver(); + asmResolver.EnableTypeDefCache = true; + asmResolver.DefaultModuleContext = new ModuleContext(asmResolver); + context.Resolver = asmResolver; + context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, parameters.Project.BaseDirectory + "\\"); + context.OutputDirectory = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.OutputDirectory + "\\"); + foreach (string probePath in parameters.Project.ProbePaths) + asmResolver.PostSearchPaths.Add(Path.Combine(context.BaseDirectory, probePath)); + Marker marker = parameters.GetMarker(); // 2. Discover plugins @@ -94,8 +94,7 @@ namespace Confuser.Core { try { var resolver = new DependencyResolver(prots); prots = resolver.SortDependency(); - } - catch (CircularDependencyException ex) { + } catch (CircularDependencyException ex) { context.Logger.ErrorException("", ex); throw new ConfuserException(ex); } @@ -122,8 +121,7 @@ namespace Confuser.Core { foreach (ConfuserComponent comp in components) { try { comp.Initialize(context); - } - catch (Exception ex) { + } catch (Exception ex) { context.Logger.ErrorException("Error occured during initialization of '" + comp.Name + "'.", ex); throw new ConfuserException(ex); } @@ -143,29 +141,21 @@ namespace Confuser.Core { RunPipeline(pipeline, context); ok = true; - } - catch (AssemblyResolveException ex) { + } catch (AssemblyResolveException ex) { context.Logger.ErrorException("Failed to resolve a assembly, check if all dependencies are of correct version.", ex); - } - catch (TypeResolveException ex) { + } catch (TypeResolveException ex) { context.Logger.ErrorException("Failed to resolve a type, check if all dependencies are of correct version.", ex); - } - catch (MemberRefResolveException ex) { + } catch (MemberRefResolveException ex) { context.Logger.ErrorException("Failed to resolve a member, check if all dependencies are of correct version.", ex); - } - catch (IOException ex) { + } catch (IOException ex) { context.Logger.ErrorException("An IO error occured, check if all input/output locations are read/writable.", ex); - } - catch (OperationCanceledException) { + } catch (OperationCanceledException) { context.Logger.Error("Operation is canceled."); - } - catch (ConfuserException) { + } catch (ConfuserException) { // Exception is already handled/logged, so just ignore and report failure - } - catch (Exception ex) { + } catch (Exception ex) { context.Logger.ErrorException("Unknown error occured.", ex); - } - finally { + } finally { context.Logger.Finish(ok); } } @@ -227,8 +217,7 @@ namespace Confuser.Core { .SelectMany(module => module.GetAssemblyRefs().Select(asmRef => Tuple.Create(asmRef, module)))) { try { AssemblyDef assembly = context.Resolver.ResolveThrow(dependency.Item1, dependency.Item2); - } - catch (AssemblyResolveException ex) { + } catch (AssemblyResolveException ex) { context.Logger.ErrorException("Failed to resolve dependency of '" + dependency.Item2.Name + "'.", ex); throw new ConfuserException(ex); } @@ -361,8 +350,7 @@ namespace Confuser.Core { private static void PrintInfo(ConfuserContext context) { if (context.PackerInitiated) { context.Logger.Info("Protecting packer stub..."); - } - else { + } else { context.Logger.InfoFormat("{0} {1}", Version, Copyright); Type mono = Type.GetType("Mono.Runtime"); diff --git a/ConfuserEx/BrushToColorConverter.cs b/ConfuserEx/BrushToColorConverter.cs new file mode 100644 index 0000000..6ed30a0 --- /dev/null +++ b/ConfuserEx/BrushToColorConverter.cs @@ -0,0 +1,22 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Media; + +namespace ConfuserEx { + public class BrushToColorConverter : IValueConverter { + public static readonly BrushToColorConverter Instance = new BrushToColorConverter(); + private BrushToColorConverter() { } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { + var brush = value as SolidColorBrush; + if (brush != null) + return brush.Color; + return null; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/ConfuserEx/ComponentConverter.cs b/ConfuserEx/ComponentConverter.cs index adcbdf3..e665fb1 100644 --- a/ConfuserEx/ComponentConverter.cs +++ b/ConfuserEx/ComponentConverter.cs @@ -17,15 +17,19 @@ namespace ConfuserEx { } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - Debug.Assert(value is string); + Debug.Assert(value is string || value == null); Debug.Assert(targetType == typeof (ConfuserComponent)); Debug.Assert(Components != null); + + if (value == null) return null; return Components.Single(comp => comp.Id == (string)value); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - Debug.Assert(value is ConfuserComponent); + Debug.Assert(value is ConfuserComponent || value == null); Debug.Assert(targetType == typeof (string)); + + if (value == null) return null; return ((ConfuserComponent)value).Id; } diff --git a/ConfuserEx/ConfuserEx.csproj b/ConfuserEx/ConfuserEx.csproj index 5e3efa6..b4f34c7 100644 --- a/ConfuserEx/ConfuserEx.csproj +++ b/ConfuserEx/ConfuserEx.csproj @@ -57,6 +57,10 @@ ..\deps\Ookii.Dialogs.Wpf.dll + + True + ..\packages\TaskParallelLibrary.1.0.2856.0\lib\Net35\System.Threading.dll + ..\packages\MvvmLightLibs.4.3.31.1\lib\net40\System.Windows.Interactivity.dll @@ -76,6 +80,7 @@ Properties\GlobalAssemblyInfo.cs + CompComboBox.xaml @@ -83,6 +88,7 @@ + @@ -93,6 +99,7 @@ + @@ -130,6 +137,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/ConfuserEx/InvertBoolConverter.cs b/ConfuserEx/InvertBoolConverter.cs new file mode 100644 index 0000000..c1088a1 --- /dev/null +++ b/ConfuserEx/InvertBoolConverter.cs @@ -0,0 +1,21 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.Windows.Data; + +namespace ConfuserEx { + internal class InvertBoolConverter : IValueConverter { + public static readonly InvertBoolConverter Instance = new InvertBoolConverter(); + private InvertBoolConverter() { } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { + Debug.Assert(value is bool); + Debug.Assert(targetType == typeof (bool)); + return !(bool)value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { + throw new NotSupportedException(); + } + } +} \ No newline at end of file diff --git a/ConfuserEx/MainWindow.xaml b/ConfuserEx/MainWindow.xaml index c009c68..204d5b4 100644 --- a/ConfuserEx/MainWindow.xaml +++ b/ConfuserEx/MainWindow.xaml @@ -1,6 +1,7 @@  @@ -47,7 +48,7 @@ + SelectedIndex="0" local:Skin.TabsDisabled="{Binding NavigationDisabled}"> + + + + \ No newline at end of file diff --git a/ConfuserEx/ViewModel/Project/ProjectModuleVM.cs b/ConfuserEx/ViewModel/Project/ProjectModuleVM.cs index c7929d9..47adb08 100644 --- a/ConfuserEx/ViewModel/Project/ProjectModuleVM.cs +++ b/ConfuserEx/ViewModel/Project/ProjectModuleVM.cs @@ -19,6 +19,9 @@ namespace ConfuserEx.ViewModel { ObservableCollection rules = Utils.Wrap(module.Rules, rule => new ProjectRuleVM(parent, rule)); rules.CollectionChanged += (sender, e) => parent.IsModified = true; Rules = rules; + + SimpleName = System.IO.Path.GetFileName(module.Path); + LoadAssemblyName(); } public ProjectModule Module { diff --git a/ConfuserEx/ViewModel/Project/ProjectRuleVM.cs b/ConfuserEx/ViewModel/Project/ProjectRuleVM.cs index e7327f2..cc179b3 100644 --- a/ConfuserEx/ViewModel/Project/ProjectRuleVM.cs +++ b/ConfuserEx/ViewModel/Project/ProjectRuleVM.cs @@ -23,6 +23,8 @@ namespace ConfuserEx.ViewModel { ObservableCollection> protections = Utils.Wrap(rule, setting => new ProjectSettingVM(parent, setting)); protections.CollectionChanged += (sender, e) => parent.IsModified = true; Protections = protections; + + ParseExpression(); } public ProjectVM Project { diff --git a/ConfuserEx/ViewModel/UI/ProtectTabVM.cs b/ConfuserEx/ViewModel/UI/ProtectTabVM.cs new file mode 100644 index 0000000..b1244de --- /dev/null +++ b/ConfuserEx/ViewModel/UI/ProtectTabVM.cs @@ -0,0 +1,131 @@ +using System; +using System.Windows; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using Confuser.Core; +using Confuser.Core.Project; +using GalaSoft.MvvmLight.Command; + +namespace ConfuserEx.ViewModel { + internal class ProtectTabVM : TabViewModel, ILogger { + private readonly Paragraph documentContent; + private double? progress = 0; + private bool? result; + + public ProtectTabVM(AppVM app) + : base(app, "Protect!") { + documentContent = new Paragraph(); + LogDocument = new FlowDocument(); + LogDocument.Blocks.Add(documentContent); + } + + public ICommand ProtectCmd { + get { return new RelayCommand(DoProtect, () => !App.NavigationDisabled); } + } + + public double? Progress { + get { return progress; } + set { SetProperty(ref progress, value, "Progress"); } + } + + public FlowDocument LogDocument { get; private set; } + + public bool? Result { + get { return result; } + set { SetProperty(ref result, value, "Result"); } + } + + private void DoProtect() { + var parameters = new ConfuserParameters(); + parameters.Project = ((IViewModel)App.Project).Model; + parameters.Logger = this; + + documentContent.Inlines.Clear(); + App.NavigationDisabled = true; + Result = null; + begin = DateTime.Now; + + ConfuserEngine.Run(parameters) + .ContinueWith(_ => + Application.Current.Dispatcher.BeginInvoke(new Action(() => { + Progress = 0; + App.NavigationDisabled = false; + CommandManager.InvalidateRequerySuggested(); + }))); + } + + private void AppendLine(string format, Brush foreground, params object[] args) { + Application.Current.Dispatcher.BeginInvoke(new Action(() => { + documentContent.Inlines.Add(new Run(string.Format(format, args)) { Foreground = foreground }); + documentContent.Inlines.Add(new LineBreak()); + })); + } + + #region Logger Impl + + private DateTime begin; + + public void Debug(string msg) { + AppendLine("[DEBUG] {0}", Brushes.Gray, msg); + } + + public void DebugFormat(string format, params object[] args) { + AppendLine("[DEBUG] {0}", Brushes.Gray, string.Format(format, args)); + } + + public void Info(string msg) { + AppendLine(" [INFO] {0}", Brushes.White, msg); + } + + public void InfoFormat(string format, params object[] args) { + AppendLine(" [INFO] {0}", Brushes.White, string.Format(format, args)); + } + + public void Warn(string msg) { + AppendLine(" [WARN] {0}", Brushes.Yellow, msg); + } + + public void WarnFormat(string format, params object[] args) { + AppendLine(" [WARN] {0}", Brushes.Yellow, string.Format(format, args)); + } + + public void WarnException(string msg, Exception ex) { + AppendLine(" [WARN] {0}", Brushes.Yellow, msg); + AppendLine("Exception: {0}", Brushes.Yellow, ex); + } + + public void Error(string msg) { + AppendLine("[ERROR] {0}", Brushes.Red, msg); + } + + public void ErrorFormat(string format, params object[] args) { + AppendLine("[ERROR] {0}", Brushes.Red, string.Format(format, args)); + } + + public void ErrorException(string msg, Exception ex) { + AppendLine("[ERROR] {0}", Brushes.Red, msg); + AppendLine("Exception: {0}", Brushes.Red, ex); + } + + void ILogger.Progress(int overall, int progress) { + Progress = (double)progress / overall; + } + + public void Finish(bool successful) { + DateTime now = DateTime.Now; + string timeString = string.Format( + "at {0}, {1}:{2:d2} elapsed.", + now.ToShortTimeString(), + (int)now.Subtract(begin).TotalMinutes, + now.Subtract(begin).Seconds); + if (successful) + AppendLine("Finished {0}", Brushes.Lime, timeString); + else + AppendLine("Failed {0}", Brushes.Red, timeString); + Result = successful; + } + + #endregion + } +} \ No newline at end of file diff --git a/ConfuserEx/ViewModel/UI/SettingsTabVM.cs b/ConfuserEx/ViewModel/UI/SettingsTabVM.cs index c3389df..cdbc2ae 100644 --- a/ConfuserEx/ViewModel/UI/SettingsTabVM.cs +++ b/ConfuserEx/ViewModel/UI/SettingsTabVM.cs @@ -88,6 +88,8 @@ namespace ConfuserEx.ViewModel { App.Project, new CollectionContainer { Collection = App.Project.Modules } }; + OnPropertyChanged("ModulesView"); + HasPacker = App.Project.Packer != null; } protected override void OnPropertyChanged(string property) { diff --git a/ConfuserEx/Views.xaml b/ConfuserEx/Views.xaml index 92f26b9..ab38891 100644 --- a/ConfuserEx/Views.xaml +++ b/ConfuserEx/Views.xaml @@ -3,5 +3,6 @@ + \ No newline at end of file diff --git a/ConfuserEx/Views/ProtectTabView.xaml b/ConfuserEx/Views/ProtectTabView.xaml new file mode 100644 index 0000000..caab5e4 --- /dev/null +++ b/ConfuserEx/Views/ProtectTabView.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + +