コード例 #1
0
        public object GetView(IPackageContent selectedFile, IReadOnlyList <IPackageContent> peerFiles)
        {
            var tempFile = Path.GetTempFileName();

            try
            {
                using (var str = selectedFile.GetStream())
                    using (var fileStream = File.OpenWrite(tempFile))
                    {
                        str.CopyTo(fileStream);
                    }

                var assemblyMetadata = AssemblyMetadataReader.ReadMetaData(tempFile);
                AssemblyDebugDataViewModel debugDataViewModel = null;
                if (assemblyMetadata.DebugData != null)
                {
                    debugDataViewModel = new AssemblyDebugDataViewModel(assemblyMetadata.DebugData);
                }

                // No debug data to display
                if (assemblyMetadata != null && debugDataViewModel == null)
                {
                    var orderedAssemblyDataEntries = assemblyMetadata.GetMetadataEntriesOrderedByImportance();

                    var grid = CreateAssemblyMetadataGrid(orderedAssemblyDataEntries);

                    return(new ScrollViewer
                    {
                        HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                        VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                        Content = grid,
                    });
                }
                else if (assemblyMetadata != null && debugDataViewModel != null)
                {
                    var orderedAssemblyDataEntries = assemblyMetadata.GetMetadataEntriesOrderedByImportance();

                    // Tab control with two pages
                    var tc = new TabControl()
                    {
                        Items =
                        {
                            new TabItem
                            {
                                Header  = "Assembly Attributes",
                                Content = new ScrollViewer()
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = CreateAssemblyMetadataGrid(orderedAssemblyDataEntries)
                                }
                            },
                            new TabItem
                            {
                                Header  = "Embedded PDB Data",
                                Content = new ScrollViewer
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = new Controls.PdbFileViewer
                                    {
                                        DataContext = debugDataViewModel
                                    }
                                }
                            }
                        }
                    };

                    return(tc);
                }
            }
            catch { }
            finally
            {
                if (File.Exists(tempFile))
                {
                    try
                    {
                        File.Delete(tempFile);
                    }
                    catch
                    {
                    }
                }
            }

            return(new Grid());
        }
コード例 #2
0
        public object GetView(IPackageContent selectedFile, IReadOnlyList <IPackageContent> peerFiles)
        {
            DiagnosticsClient.TrackEvent("AssemblyFileViewer");



            try
            {
                using var str      = selectedFile.GetStream();
                using var tempFile = new TemporaryFile(str);

                var debugData        = (selectedFile as PackageFile)?.DebugData;
                var assemblyMetadata = AssemblyMetadataReader.ReadMetaData(tempFile.FileName);

                if (debugData == null)
                {
                    if (assemblyMetadata?.DebugData.HasDebugInfo == true)
                    {
                        debugData = assemblyMetadata.DebugData;
                    }
                }

                AssemblyDebugDataViewModel?debugDataViewModel = null;

                if (debugData != null)
                {
                    debugDataViewModel = new AssemblyDebugDataViewModel(Task.FromResult(debugData));
                }

                // No debug data to display
                if (assemblyMetadata != null && debugDataViewModel == null)
                {
                    var orderedAssemblyDataEntries = GetMetadataEntriesOrderedByImportance(assemblyMetadata);

                    var grid = CreateAssemblyMetadataGrid(orderedAssemblyDataEntries);

                    return(new ScrollViewer
                    {
                        HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                        VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                        Content = grid,
                    });
                }
                else if (assemblyMetadata != null && debugDataViewModel != null)
                {
                    var orderedAssemblyDataEntries = GetMetadataEntriesOrderedByImportance(assemblyMetadata);

                    // Tab control with three pages
                    var tc = new TabControl()
                    {
                        Items =
                        {
                            new TabItem
                            {
                                Header  = "Assembly Attributes",
                                Content = new ScrollViewer()
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = CreateAssemblyMetadataGrid(orderedAssemblyDataEntries)
                                }
                            },
                            new TabItem
                            {
                                Header  = "PDB Info",
                                Content = new ScrollViewer
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = new Controls.PdbInfoViewer
                                    {
                                        DataContext = debugDataViewModel
                                    }
                                }
                            },
                            new TabItem
                            {
                                Header  = "PDB Sources",
                                Content = new ScrollViewer
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = new Controls.PdbSourcesViewer
                                    {
                                        DataContext = debugDataViewModel
                                    }
                                }
                            }
                        }
                    };

                    return(tc);
                }
            }
            catch { }

            return(new Grid());
        }
コード例 #3
0
        public object GetView(string extension, Stream stream)
        {
            var tempFile = Path.GetTempFileName();

            var grid = new Grid();

            grid.ColumnDefinitions.Add(new ColumnDefinition {
                Width = new GridLength(1, GridUnitType.Auto)
            });
            grid.ColumnDefinitions.Add(new ColumnDefinition {
                Width = new GridLength(1, GridUnitType.Auto)
            });

            try
            {
                using (var fileStream = File.OpenWrite(tempFile))
                {
                    stream.CopyTo(fileStream);
                }

                var assemblyMetadata = AssemblyMetadataReader.ReadMetaData(tempFile);


                if (assemblyMetadata != null)
                {
                    var orderedAssemblyDataEntries = assemblyMetadata.GetMetadataEntriesOrderedByImportance();

                    foreach (var data in orderedAssemblyDataEntries)
                    {
                        var label = new TextBlock
                        {
                            Text       = data.Key + ':',
                            FontWeight = FontWeights.SemiBold,
                            Margin     = new Thickness(3, 3, 10, 0)
                        };
                        Grid.SetRow(label, grid.RowDefinitions.Count);
                        Grid.SetColumn(label, 0);

                        var value = new TextBlock
                        {
                            Text   = data.Value,
                            Margin = new Thickness(0, 3, 3, 0)
                        };
                        Grid.SetRow(value, grid.RowDefinitions.Count);
                        Grid.SetColumn(value, 1);

                        grid.RowDefinitions.Add(new RowDefinition {
                            Height = new GridLength(1, GridUnitType.Auto)
                        });
                        grid.Children.Add(label);
                        grid.Children.Add(value);
                    }
                }
            }
            catch { }
            finally
            {
                if (File.Exists(tempFile))
                {
                    try
                    {
                        File.Delete(tempFile);
                    }
                    catch
                    {
                    }
                }
            }

            return(grid);
        }
コード例 #4
0
        private async Task CalculateValidity(IReadOnlyList <PackageFile> files)
        {
            var filesWithPdb = (from pf in files
                                let ext = Path.GetExtension(pf.Path)
                                          where ".dll".Equals(ext, StringComparison.OrdinalIgnoreCase) ||
                                          ".exe".Equals(ext, StringComparison.OrdinalIgnoreCase) ||
                                          ".winmd".Equals(ext, StringComparison.OrdinalIgnoreCase)
                                          select new FileWithPdb
            {
                Primary = pf,
                Pdb = pf.GetAssociatedFiles().FirstOrDefault(af => ".pdb".Equals(Path.GetExtension(af.Path), StringComparison.OrdinalIgnoreCase))
            })
                               .ToList();


            var sourceLinkErrors = new List <(PackageFile file, string errors)>();
            var noSourceLink     = new List <PackageFile>();
            var noSymbols        = new List <FileWithDebugData>();
            var untrackedSources = new List <FileWithDebugData>();
            var nonDeterministic = new List <PackageFile>();

            var allFilePaths = filesWithPdb.ToDictionary(pf => pf.Primary.Path);

            var pdbChecksumValid = true;

            foreach (var file in filesWithPdb.ToArray()) // work on array as we'll remove items that are satellite assemblies as we go
            {
                // Skip satellite assemblies
                if (IsSatelliteAssembly(file.Primary.Path))
                {
                    filesWithPdb.Remove(allFilePaths[file.Primary.Path]);
                    continue;
                }

                // If we have a PDB, try loading that first. If not, may be embedded.
                // Local checks first
                if (file.Pdb != null)
                {
                    var filePair = new FileWithDebugData(file.Primary, null);
                    if (!ValidatePdb(filePair, file.Pdb.GetStream(), noSourceLink, sourceLinkErrors, untrackedSources, nonDeterministic))
                    {
                        pdbChecksumValid = false;
                        noSymbols.Add(filePair);
                    }
                }
                else // No PDB, see if it's embedded
                {
                    try
                    {
                        using var str      = file.Primary.GetStream();
                        using var tempFile = new TemporaryFile(str);

                        var assemblyMetadata = AssemblyMetadataReader.ReadMetaData(tempFile.FileName);

                        if (assemblyMetadata?.DebugData.HasDebugInfo == true)
                        {
                            // we have an embedded pdb
                            if (!assemblyMetadata.DebugData.HasSourceLink)
                            {
                                noSourceLink.Add(file.Primary);
                            }

                            if (assemblyMetadata.DebugData.SourceLinkErrors.Count > 0)
                            {
                                // Has source link errors
                                sourceLinkErrors.Add((file.Primary, string.Join("\n", assemblyMetadata.DebugData.SourceLinkErrors)));
                            }

                            // Check for non-embedded sources
                            if (assemblyMetadata.DebugData.UntrackedSources.Count > 0)
                            {
                                var filePair = new FileWithDebugData(file.Primary, assemblyMetadata.DebugData);
                                untrackedSources.Add(filePair);
                            }

                            // Check for deterministic sources
                            if (!assemblyMetadata.DebugData.SourcesAreDeterministic)
                            {
                                nonDeterministic.Add(file.Primary);
                            }
                        }
                        else // no embedded pdb, try to look for it elsewhere
                        {
                            noSymbols.Add(new FileWithDebugData(file.Primary, assemblyMetadata?.DebugData));
                        }
                    }
                    catch // an error occured, no symbols
                    {
                        noSymbols.Add(new FileWithDebugData(file.Primary, null));
                    }
                }
            }


            var requireExternal = false;

            // See if any pdb's are missing and check for a snupkg on NuGet.org.
            if (noSymbols.Count > 0 && _publishedOnNuGetOrg)
            {
                // try to get on NuGet.org
                // https://www.nuget.org/api/v2/symbolpackage/Newtonsoft.Json/12.0.3 -- Will redirect


                try
                {
#pragma warning disable CA2234 // Pass system uri objects instead of strings
                    var response = await _httpClient.GetAsync($"https://www.nuget.org/api/v2/symbolpackage/{_package.Id}/{_package.Version.ToNormalizedString()}").ConfigureAwait(false);

#pragma warning restore CA2234                        // Pass system uri objects instead of strings

                    if (response.IsSuccessStatusCode) // we'll get a 404 if none
                    {
                        requireExternal = true;

                        using var getStream = await response.Content.ReadAsStreamAsync();

                        using var tempFile = new TemporaryFile(getStream, ".snupkg");
                        using var package  = new ZipPackage(tempFile.FileName);

                        // Look for pdb's for the missing files
                        var dict = package.GetFiles().ToDictionary(k => k.Path);

                        foreach (var file in noSymbols.ToArray()) // from a copy so we can remove as we go
                        {
                            // file to look for
                            var pdbpath = Path.ChangeExtension(file.File.Path, ".pdb");

                            if (dict.TryGetValue(pdbpath, out var pdbfile))
                            {
                                // Validate
                                if (ValidatePdb(file, pdbfile.GetStream(), noSourceLink, sourceLinkErrors, untrackedSources, nonDeterministic))
                                {
                                    noSymbols.Remove(file);
                                }
                                else
                                {
                                    pdbChecksumValid = false;
                                }
                            }
                        }
                    }
                }
                catch // Could not check, leave status as-is
                {
                }
            }

            // Check for Microsoft assemblies on the Microsoft symbol server
            if (noSymbols.Count > 0)
            {
                var microsoftFiles = noSymbols.Where(f => f.DebugData != null && IsMicrosoftFile(f.File)).ToList();

                foreach (var file in microsoftFiles)
                {
                    var pdbStream = await GetSymbolsAsync(file.DebugData !.SymbolKeys);

                    if (pdbStream != null)
                    {
                        requireExternal = true;

                        // Found a PDB for it
                        if (ValidatePdb(file, pdbStream, noSourceLink, sourceLinkErrors, untrackedSources, nonDeterministic))
                        {
                            noSymbols.Remove(file);
                        }
                        else
                        {
                            pdbChecksumValid = false;
                        }
                    }
                }
            }

            if (noSymbols.Count == 0 && noSourceLink.Count == 0 && sourceLinkErrors.Count == 0)
            {
                if (untrackedSources.Count > 0)
                {
                    SourceLinkResult = SymbolValidationResult.HasUntrackedSources;

                    var sb = new StringBuilder("Contains untracked sources:\n");
                    sb.AppendLine("To Fix:");
                    sb.AppendLine("<EmbedUntrackedSources>true</EmbedUntrackedSources>");

                    foreach (var untracked in untrackedSources)
                    {
                        sb.AppendLine($"Assembly: {untracked.File.Path}");

                        foreach (var source in untracked.DebugData !.UntrackedSources)
                        {
                            sb.AppendLine($"  {source}");
                        }

                        sb.AppendLine();
                    }

                    SourceLinkErrorMessage = sb.ToString();
                }
                else if (filesWithPdb.Count == 0)
                {
                    SourceLinkResult       = SymbolValidationResult.NothingToValidate;
                    SourceLinkErrorMessage = "No files found to validate";
                }
                else if (requireExternal)
                {
                    SourceLinkResult       = SymbolValidationResult.ValidExternal;
                    SourceLinkErrorMessage = null;
                }
                else
                {
                    SourceLinkResult       = SymbolValidationResult.Valid;
                    SourceLinkErrorMessage = null;
                }
            }
            else
            {
                var found = false;
                var sb    = new StringBuilder();
                if (noSourceLink.Count > 0)
                {
                    SourceLinkResult = SymbolValidationResult.NoSourceLink;

                    sb.AppendLine($"Missing Source Link for:\n{string.Join("\n", noSourceLink.Select(p => p.Path)) }");
                    found = true;
                }

                if (sourceLinkErrors.Count > 0)
                {
                    SourceLinkResult = SymbolValidationResult.InvalidSourceLink;

                    if (found)
                    {
                        sb.AppendLine();
                    }

                    foreach (var(file, errors) in sourceLinkErrors)
                    {
                        sb.AppendLine($"Source Link errors for {file.Path}:\n{string.Join("\n", errors) }");
                    }

                    found = true;
                }

                if (noSymbols.Count > 0) // No symbols "wins" as it's more severe
                {
                    SourceLinkResult = SymbolValidationResult.NoSymbols;

                    if (found)
                    {
                        sb.AppendLine();
                    }

                    if (!pdbChecksumValid)
                    {
                        sb.AppendLine("Some PDB's checksums do not match their PE files and are shown as missing.");
                    }

                    sb.AppendLine($"Missing Symbols for:\n{string.Join("\n", noSymbols.Select(p => p.File.Path)) }");
                }

                SourceLinkErrorMessage = sb.ToString();
            }

            if (SourceLinkResult == SymbolValidationResult.NothingToValidate)
            {
                DeterministicResult       = DeterministicResult.NothingToValidate;
                DeterministicErrorMessage = null;
            }
            else if (SourceLinkResult == SymbolValidationResult.NoSymbols)
            {
                DeterministicResult       = DeterministicResult.NonDeterministic;
                DeterministicErrorMessage = "Missing Symbols";
            }
            else if (nonDeterministic.Count > 0)
            {
                DeterministicResult = DeterministicResult.NonDeterministic;

                var sb = new StringBuilder();
                sb.AppendLine("Ensure that the following properties are enabled for CI builds\nand you're using at least the 2.1.300 SDK:");
                sb.AppendLine("<Deterministic>true</Deterministic>");
                sb.AppendLine("<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>");
                sb.AppendLine();
                sb.AppendLine("The following assemblies have not been compiled with deterministic settings:");

                foreach (var file in nonDeterministic)
                {
                    sb.AppendLine(file.Path);
                }

                DeterministicErrorMessage = sb.ToString();
            }
            else if (SourceLinkResult == SymbolValidationResult.HasUntrackedSources)
            {
                DeterministicResult       = DeterministicResult.HasUntrackedSources;
                DeterministicErrorMessage = null;
            }
            else
            {
                DeterministicResult       = DeterministicResult.Valid;
                DeterministicErrorMessage = null;
            }
        }
コード例 #5
0
        public object GetView(IPackageContent selectedFile, IReadOnlyList <IPackageContent> peerFiles)
        {
            DiagnosticsClient.TrackEvent("AssemblyFileViewer");

            try
            {
                using var str      = selectedFile.GetStream();
                using var tempFile = new TemporaryFile(str);

                var debugData        = (selectedFile as PackageFile)?.DebugData;
                var assemblyMetadata = AssemblyMetadataReader.ReadMetaData(tempFile.FileName);

                if (debugData == null)
                {
                    if (assemblyMetadata?.DebugData.HasDebugInfo == true)
                    {
                        debugData = assemblyMetadata.DebugData;
                    }
                }

                AssemblyDebugDataViewModel?debugDataViewModel = null;

                if (debugData != null)
                {
                    debugDataViewModel = new AssemblyDebugDataViewModel(Task.FromResult(debugData));
                }

#if !HAS_UNO
                // No debug data to display
                if (assemblyMetadata != null && debugDataViewModel == null)
                {
                    var orderedAssemblyDataEntries = GetMetadataEntriesOrderedByImportance(assemblyMetadata);

                    var grid = CreateAssemblyMetadataGrid(orderedAssemblyDataEntries);

                    return(new ScrollViewer
                    {
                        HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                        VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                        Content = grid,
                    });
                }
                else if (assemblyMetadata != null && debugDataViewModel != null)
                {
                    var orderedAssemblyDataEntries = GetMetadataEntriesOrderedByImportance(assemblyMetadata);

                    // Tab control with three pages
                    var tc = new TabControl()
                    {
#if HAS_UNO
                        IsAddTabButtonVisible = false,
                        TabItems =
#else
                        Items =
#endif
                        {
                            new TabItem
                            {
                                Header  = "Assembly Attributes",
                                Content = new ScrollViewer()
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = CreateAssemblyMetadataGrid(orderedAssemblyDataEntries)
                                }
                            },
                            new TabItem
                            {
                                Header  = "PDB Info",
                                Content = new ScrollViewer
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = new Controls.PdbInfoViewer
                                    {
                                        DataContext = debugDataViewModel
                                    }
                                }
                            },
                            new TabItem
                            {
                                Header  = "PDB Sources",
                                Content = new ScrollViewer
                                {
                                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                                    VerticalScrollBarVisibility   = ScrollBarVisibility.Auto,
                                    Content = new Controls.PdbSourcesViewer
                                    {
                                        DataContext = debugDataViewModel
                                    }
                                }
                            }
                        }
                    };

                    return(tc);
                }
#else
                // returning UIElement from here works.
                // however due to performance issues, we are just
                // returning the datacontext and letting the xaml to handle the view.
                // also, the ui layout is vastely different compared to the #if-block above
                return(new AssemblyFileContent()
                {
                    Metadata = assemblyMetadata
                               ?.SelectOrDefault(GetMetadataEntriesOrderedByImportance)
                               .ToArray(),
                    DebugData = debugDataViewModel,
                });
#endif
            }
            catch (Exception e)
            {
#if HAS_UNO
                this.Log().Error("Failed to generate view", e);
#endif
            }

#if !HAS_UNO
            return(new Grid());
#else
            // the empty object is needed for branching via type-checking
            return(new AssemblyFileContent());
#endif
        }