Ejemplo n.º 1
0
        public IDecompileResult Decompile(string path, Action <string> msgSetter, CancellationToken?token = null, params string[] referlib)
        {
            PreDecompileCallback?.Invoke();
            IDecompileResult result = RunDecompiler(path, msgSetter, token, referlib);

            AfterDecompileCallback?.Invoke();
            return(result);
        }
Ejemplo n.º 2
0
        protected override IDecompileResult RunDecompiler(string path, Action <string> msgSetter, CancellationToken?token, params string[] referlib)
        {
            string           output = null;
            IDecompileResult result = Container.Resolve <IDecompileResult>();

            //check if path is a directory
            if (Directory.Exists(path))
            {
                output = Path.Combine(path, "decompiled");
                path  += "\\\\";//add backslash for fernflower
                Directory.CreateDirectory(output);
            }
            else if (File.Exists(path))
            {
                output = Path.Combine(Path.GetDirectoryName(path), "decompiled");
                Directory.CreateDirectory(output);
            }
            else
            {
                throw new ArgumentException($"Error:\"{path}\" is not a valid path!");
            }
            string executePath = GlobalUtils.GlobalConfig.JavaPath;

            using (Process process = new Process())
            {
                bool IsCancelled() => token.HasValue && token.Value.IsCancellationRequested == true;

                process.StartInfo.FileName        = executePath;
                process.StartInfo.ErrorDialog     = true;
                process.StartInfo.UseShellExecute = false;
                System.Windows.Application.Current.Dispatcher.Invoke(() =>
                {
                    var interop = new System.Windows.Interop.WindowInteropHelper(System.Windows.Application.Current.MainWindow);
                    process.StartInfo.ErrorDialogParentHandle = interop.Handle;
                });
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;
                process.StartInfo.Arguments      = "-jar " + Options.GetDecompilerPath() + Options.GetArgumentsString(path, output, referlib);
                process.StartInfo.CreateNoWindow = true;
                process.OutputDataReceived      += (s, e) =>
                {
                    if (!IsCancelled())
                    {
                        msgSetter.Invoke(e.Data);
                    }
                    else
                    {
                        process.Kill();
                    }
                };
                process.ErrorDataReceived += (s, e) =>
                {
                    if (!string.IsNullOrWhiteSpace(e.Data))
                    {
                        result.HasError = true;
                    }
                    if (!IsCancelled())
                    {
                        if (!string.IsNullOrWhiteSpace(e.Data))
                        {
                            msgSetter.Invoke(e.Data);
                        }
                    }
                    else
                    {
                        process.Kill();
                    }
                };
                process.Start();
                try
                {
                    if (!IsCancelled())
                    {
                        try
                        {
                            process.ProcessorAffinity = (IntPtr)1;
                        }
                        catch (Exception)
                        {
                        }
                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();
                    }
                    else
                    {
                        process.Kill();
                    }
                }
                catch (Exception e)
                {
                    if (!process.HasExited)
                    {
                        throw e;
                    }
                }
                if (IsCancelled())
                {
                    throw new OperationCanceledException();
                }
                else
                {
                    result.OutputDir  = output;
                    result.ResultCode = result.HasError ? DecompileResultEnum.WithJavaException : DecompileResultEnum.Success;
                    result.ReturnCode = process.ExitCode;
                    return(result);
                }
            }
        }
Ejemplo n.º 3
0
        protected override IDocumentViewModel _InnerOpenDocument(IJPath path)
        {
            DecompileDocumentViewModel viewModel;

            viewModel        = Container.Resolve <DecompileDocumentViewModel>();
            viewModel.Parent = this;
            viewModel.Title  = Path.GetFileName(path.Path);
            Documents.Add(viewModel);

            /*viewModel.TokenSource = new CancellationTokenSource();
             * viewModel.DecompileTask = new Task(() =>
             * {
             *    if (MapSourceToMd5.ContainsKey(path.Path))
             *    {
             *        if (APIHelper.GetMd5Of(path.Path) == MapSourceToMd5[path.Path])
             *        {
             *            //TODO
             *        }
             *    }
             *    var basedir = Path.GetDirectoryName(path.Path);
             *    var tempPath = Path.GetTempFileName();
             *    File.Delete(tempPath);
             *    Directory.CreateDirectory(tempPath);
             *    File.Copy(path.Path, Path.Combine(tempPath, Path.GetFileName(path.Path)));
             *    foreach(var p in path.InnerClassPaths)
             *    {
             *        File.Copy(p, Path.Combine(tempPath, Path.GetFileName(p)));
             *    }
             *    var result = Decompiler.Decompile(tempPath, r => MessageWhole = r, viewModel.TokenSource.Token, BaseDirectory + "\\raw.jar");
             *
             *    if (result.ResultCode == CommonDecompiler.DecompileResultEnum.DecompileSuccess)
             *    {
             *        viewModel.Load(result.Output);
             *    }
             * });
             * viewModel.DecompileTask.Start();*/
            viewModel.DecompTaskTokenSource = new CancellationTokenSource();
            IBackgroundTask backgroundTask = null;

            backgroundTask = Container.Resolve <IBackgroundTaskBuilder>()
                             .WithTask(async obj =>
            {
                var token = obj as CancellationToken?;
                if (MapSourceToMd5.ContainsKey(path.Path))
                {
                    if (APIHelper.GetMd5Of(path.Path) == MapSourceToMd5[path.Path])
                    {
                        //TODO
                    }
                }
                var basedir  = Path.GetDirectoryName(path.Path);
                var tempPath = Path.GetTempFileName();
                File.Delete(tempPath);
                Directory.CreateDirectory(tempPath);
                File.Copy(path.Path, Path.Combine(tempPath, Path.GetFileName(path.Path)));
                if (path.InnerClassPaths != null)
                {
                    foreach (var p in path.InnerClassPaths)
                    {
                        File.Copy(p, Path.Combine(tempPath, Path.GetFileName(p)));
                    }
                }
                IDecompileResult result = null;
                try
                {
                    result = Decompiler.Decompile(tempPath,
                                                  r => { if (backgroundTask != null)
                                                         {
                                                             backgroundTask.TaskDescription = r;
                                                         }
                                                  },
                                                  token, BaseDirectory + "\\raw.jar");
                    if (result.ResultCode == DecompileResultEnum.Success)
                    {
                        var files = Directory.GetFiles(result.OutputDir);
#if DEBUG
                        Debug.Assert(files.Length == 1);
#endif
                        string newFileName = files[0];
                        if (EnableDecompiledFileCache)
                        {
                            newFileName = Path.Combine(basedir + '\\', Path.GetFileNameWithoutExtension(files[0]) + ".java");
                            File.Copy(files[0], newFileName, true);
                            MapSourceToMd5.Add(newFileName, APIHelper.GetMd5Of(newFileName));
                        }
                        StatusMessage = backgroundTask.TaskDescription = "Processing " + path.ClassPath;
                        await viewModel.LoadAsync(newFileName, path);

                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            if (!(Manager.ActiveContent is IDocumentViewModel))
                            {
                                ActivateDocument(viewModel);
                            }
                        });
                    }
                    else
                    {
                        Container.Resolve <IDialogService>().ReportError(result.ResultCode.ToString(), _ => { });
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            Documents.Remove(viewModel);
                        });
                    }
                }
                catch (Exception e)
                {
                    if (e is OperationCanceledException)
                    {
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            Documents.Remove(viewModel);
                        });
                    }
                    else
                    {
                        string message = null;
                        if (e is Win32Exception win32Exception)
                        {
                            message = $"Unexpected exception:\n{win32Exception.Message}\nHRESULT is {System.Runtime.InteropServices.Marshal.GetHRForLastWin32Error().ToString("x")}";
                        }
                        else
                        {
                            message = $"Unexpected exception:\n{e.Message}\n";
                        }
                        Container.Resolve <IDialogService>().ReportError(message, r => { }, e.StackTrace);
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            Documents.Remove(viewModel);
                        });
                    }
                }
                if (token.HasValue)
                {
                    token.Value.ThrowIfCancellationRequested();
                }
                Directory.Delete(tempPath, true);
                StatusMessage = "Ready";
            }, viewModel.DecompTaskTokenSource.Token)
                             .WithName($"{Decompiler.GetDecompilerInfo().FriendlyName}:{Path.GetFileName(path.Path)}")
                             .WithDescription($"Decompiler started")
                             .Build();
            viewModel.AttachDecompileTask(backgroundTask);
            viewModel.BackgroundTask.Start();
            return(viewModel);
        }