mirror of
https://github.com/QL-Win/QuickLook.git
synced 2026-05-08 03:06:29 +08:00
Add NuGet (.nupkg/.snupkg) info panel and parser
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
<UserControl x:Class="QuickLook.Plugin.AppViewer.InfoPanels.NugetInfoPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:QuickLook.Plugin.AppViewer"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
FontSize="14"
|
||||
UseLayoutRounding="True"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="GroupBox.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="15" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="image"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Width="120"
|
||||
Height="120"
|
||||
Margin="8"
|
||||
VerticalAlignment="Top"
|
||||
Source="/QuickLook.Plugin.AppViewer;component/Resources/nuget.png"
|
||||
Stretch="Uniform" />
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
MaxHeight="60"
|
||||
Padding="3"
|
||||
FontSize="19"
|
||||
FontWeight="SemiBold"
|
||||
LineHeight="25"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock.Inlines>
|
||||
<Run x:Name="filename" Text="PackageName.nupkg" />
|
||||
</TextBlock.Inlines>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<!-- Package ID -->
|
||||
<TextBlock x:Name="packageIdTitle"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Package ID" />
|
||||
<TextBlock x:Name="packageId"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
<!-- Version -->
|
||||
<TextBlock x:Name="versionTitle"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Version" />
|
||||
<TextBlock x:Name="version"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
<!-- Authors -->
|
||||
<TextBlock x:Name="authorsTitle"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Authors" />
|
||||
<TextBlock x:Name="authors"
|
||||
Grid.Row="5"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
<!-- License -->
|
||||
<TextBlock x:Name="licenseTitle"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="License" />
|
||||
<TextBlock x:Name="licenseBlock"
|
||||
Grid.Row="6"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
<!-- Project URL -->
|
||||
<TextBlock x:Name="projectUrlTitle"
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Visibility="Collapsed"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Project Website" />
|
||||
<TextBlock x:Name="projectUrlBlock"
|
||||
Grid.Row="7"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Visibility="Collapsed"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<Hyperlink x:Name="projectUrlLink"
|
||||
RequestNavigate="OnHyperlinkNavigate">
|
||||
<Run x:Name="projectUrlText" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<!-- Source Repository -->
|
||||
<TextBlock x:Name="repoUrlTitle"
|
||||
Grid.Row="8"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Visibility="Collapsed"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Source Repository" />
|
||||
<TextBlock x:Name="repoUrlBlock"
|
||||
Grid.Row="8"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Visibility="Collapsed"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<Hyperlink x:Name="repoUrlLink"
|
||||
RequestNavigate="OnHyperlinkNavigate">
|
||||
<Run x:Name="repoUrlText" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<!-- Target Frameworks -->
|
||||
<TextBlock x:Name="frameworksTitle"
|
||||
Grid.Row="9"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Target Frameworks" />
|
||||
<TextBlock x:Name="frameworks"
|
||||
Grid.Row="9"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
<!-- Total Size -->
|
||||
<TextBlock x:Name="totalSizeTitle"
|
||||
Grid.Row="10"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Total Size" />
|
||||
<TextBlock x:Name="totalSize"
|
||||
Grid.Row="10"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Calculating size..." />
|
||||
<!-- Last Modified -->
|
||||
<TextBlock x:Name="modDateTitle"
|
||||
Grid.Row="11"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Last Modified" />
|
||||
<TextBlock x:Name="modDate"
|
||||
Grid.Row="11"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<!-- Dependencies -->
|
||||
<GroupBox x:Name="dependenciesGroupBox"
|
||||
Grid.Row="12"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="3,3,16,16"
|
||||
Padding="3"
|
||||
Background="{DynamicResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Header="Dependencies">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Resources>
|
||||
<Style TargetType="{x:Type TextBox}">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
</Style>
|
||||
</ScrollViewer.Resources>
|
||||
<ItemsControl x:Name="dependencies">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Margin="4,1,4,1"
|
||||
IsReadOnly="True"
|
||||
Text="{Binding ., Mode=OneTime}" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,138 @@
|
||||
// Copyright © 2017-2026 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using QuickLook.Common.ExtensionMethods;
|
||||
using QuickLook.Common.Helpers;
|
||||
using QuickLook.Common.Plugin;
|
||||
using QuickLook.Plugin.AppViewer.PackageParsers.Nuget;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
namespace QuickLook.Plugin.AppViewer.InfoPanels;
|
||||
|
||||
public partial class NugetInfoPanel : UserControl, IAppInfoPanel
|
||||
{
|
||||
private readonly ContextObject _context;
|
||||
|
||||
public NugetInfoPanel(ContextObject context)
|
||||
{
|
||||
_context = context;
|
||||
|
||||
DataContext = this;
|
||||
InitializeComponent();
|
||||
|
||||
string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config");
|
||||
packageIdTitle.Text = TranslationHelper.Get("NUGET_PACKAGE_ID", translationFile);
|
||||
versionTitle.Text = TranslationHelper.Get("APP_VERSION", translationFile);
|
||||
authorsTitle.Text = TranslationHelper.Get("NUGET_AUTHORS", translationFile);
|
||||
licenseTitle.Text = TranslationHelper.Get("NUGET_LICENSE", translationFile);
|
||||
projectUrlTitle.Text = TranslationHelper.Get("NUGET_PROJECT_URL", translationFile);
|
||||
repoUrlTitle.Text = TranslationHelper.Get("NUGET_REPO_URL", translationFile);
|
||||
frameworksTitle.Text = TranslationHelper.Get("NUGET_FRAMEWORKS", translationFile);
|
||||
totalSizeTitle.Text = TranslationHelper.Get("TOTAL_SIZE", translationFile);
|
||||
modDateTitle.Text = TranslationHelper.Get("LAST_MODIFIED", translationFile);
|
||||
dependenciesGroupBox.Header = TranslationHelper.Get("NUGET_DEPENDENCIES", translationFile);
|
||||
}
|
||||
|
||||
public void DisplayInfo(string path)
|
||||
{
|
||||
var name = Path.GetFileName(path);
|
||||
filename.Text = string.IsNullOrEmpty(name) ? path : name;
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
if (!File.Exists(path)) return;
|
||||
|
||||
var size = new FileInfo(path).Length;
|
||||
NugetInfo nugetInfo = NugetParser.Parse(path);
|
||||
var last = File.GetLastWriteTime(path);
|
||||
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
packageId.Text = nugetInfo.PackageId ?? string.Empty;
|
||||
version.Text = nugetInfo.Version ?? string.Empty;
|
||||
authors.Text = nugetInfo.Authors ?? string.Empty;
|
||||
|
||||
// License
|
||||
licenseBlock.Text = nugetInfo.License ?? string.Empty;
|
||||
|
||||
// Project URL
|
||||
if (!string.IsNullOrWhiteSpace(nugetInfo.ProjectUrl) &&
|
||||
Uri.TryCreate(nugetInfo.ProjectUrl, UriKind.Absolute, out var projectUri))
|
||||
{
|
||||
projectUrlText.Text = nugetInfo.ProjectUrl;
|
||||
projectUrlLink.NavigateUri = projectUri;
|
||||
projectUrlTitle.Visibility = Visibility.Visible;
|
||||
projectUrlBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
// Source Repository URL
|
||||
if (!string.IsNullOrWhiteSpace(nugetInfo.RepositoryUrl) &&
|
||||
Uri.TryCreate(nugetInfo.RepositoryUrl, UriKind.Absolute, out var repoUri))
|
||||
{
|
||||
repoUrlText.Text = nugetInfo.RepositoryUrl;
|
||||
repoUrlLink.NavigateUri = repoUri;
|
||||
repoUrlTitle.Visibility = Visibility.Visible;
|
||||
repoUrlBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
// Target Frameworks
|
||||
frameworks.Text = nugetInfo.TargetFrameworks?.Length > 0
|
||||
? string.Join(", ", nugetInfo.TargetFrameworks)
|
||||
: string.Empty;
|
||||
|
||||
totalSize.Text = size.ToPrettySize(2);
|
||||
modDate.Text = last.ToString(CultureInfo.CurrentCulture);
|
||||
|
||||
// Dependencies
|
||||
if (nugetInfo.Dependencies?.Length > 0)
|
||||
{
|
||||
dependencies.ItemsSource = nugetInfo.Dependencies;
|
||||
}
|
||||
|
||||
// Icon — use embedded icon if available, otherwise keep default nuget.png
|
||||
if (nugetInfo.Icon != null)
|
||||
{
|
||||
using var icon = nugetInfo.Icon;
|
||||
image.Source = icon.ToBitmapSource();
|
||||
}
|
||||
|
||||
_context.IsBusy = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void OnHyperlinkNavigate(object sender, RequestNavigateEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore if the browser cannot be launched
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright © 2017-2026 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace QuickLook.Plugin.AppViewer.PackageParsers.Nuget;
|
||||
|
||||
public class NugetInfo
|
||||
{
|
||||
public string PackageId { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public string Authors { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string ProjectUrl { get; set; }
|
||||
|
||||
public string RepositoryUrl { get; set; }
|
||||
|
||||
public string License { get; set; }
|
||||
|
||||
public Bitmap Icon { get; set; }
|
||||
|
||||
public string[] TargetFrameworks { get; set; } = [];
|
||||
|
||||
public string[] Dependencies { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright © 2017-2026 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace QuickLook.Plugin.AppViewer.PackageParsers.Nuget;
|
||||
|
||||
public static class NugetParser
|
||||
{
|
||||
public static NugetInfo Parse(string path)
|
||||
{
|
||||
NugetInfo info = new();
|
||||
|
||||
try
|
||||
{
|
||||
using var zip = new ZipFile(path);
|
||||
|
||||
// Find .nuspec entry (only one should exist at the root or in a subdirectory)
|
||||
ZipEntry nuspecEntry = null;
|
||||
foreach (ZipEntry entry in zip)
|
||||
{
|
||||
if (!entry.IsDirectory && entry.Name.EndsWith(".nuspec", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
nuspecEntry = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nuspecEntry == null) return info;
|
||||
|
||||
// Parse nuspec XML
|
||||
XDocument doc;
|
||||
using (var stream = zip.GetInputStream(nuspecEntry))
|
||||
{
|
||||
doc = XDocument.Load(stream);
|
||||
}
|
||||
|
||||
// Handle XML namespace (nuspec uses versioned namespace)
|
||||
XNamespace ns = doc.Root?.GetDefaultNamespace() ?? XNamespace.None;
|
||||
var metadata = doc.Root?.Element(ns + "metadata");
|
||||
if (metadata == null) return info;
|
||||
|
||||
info.PackageId = metadata.Element(ns + "id")?.Value?.Trim();
|
||||
info.Version = metadata.Element(ns + "version")?.Value?.Trim();
|
||||
info.Authors = metadata.Element(ns + "authors")?.Value?.Trim();
|
||||
info.Description = metadata.Element(ns + "description")?.Value?.Trim();
|
||||
info.ProjectUrl = metadata.Element(ns + "projectUrl")?.Value?.Trim();
|
||||
|
||||
// Repository URL
|
||||
var repoEl = metadata.Element(ns + "repository");
|
||||
if (repoEl != null)
|
||||
{
|
||||
info.RepositoryUrl = repoEl.Attribute("url")?.Value?.Trim();
|
||||
}
|
||||
|
||||
// License: prefer <license> element, fall back to <licenseUrl>
|
||||
var licenseEl = metadata.Element(ns + "license");
|
||||
if (licenseEl != null)
|
||||
{
|
||||
info.License = licenseEl.Value?.Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
info.License = metadata.Element(ns + "licenseUrl")?.Value?.Trim();
|
||||
}
|
||||
|
||||
// Icon — look up the embedded icon file in the zip
|
||||
var iconPath = metadata.Element(ns + "icon")?.Value?.Trim();
|
||||
if (!string.IsNullOrEmpty(iconPath))
|
||||
{
|
||||
// Normalize path separators for comparison
|
||||
string normalizedIconPath = iconPath.Replace('\\', '/');
|
||||
foreach (ZipEntry entry in zip)
|
||||
{
|
||||
if (!entry.IsDirectory &&
|
||||
string.Equals(entry.Name.Replace('\\', '/'), normalizedIconPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
using var iconStream = zip.GetInputStream(entry);
|
||||
using var ms = new MemoryStream();
|
||||
iconStream.CopyTo(ms);
|
||||
ms.Position = 0;
|
||||
// Clone the bitmap so it doesn't depend on the stream
|
||||
using var tmpBitmap = new Bitmap(ms);
|
||||
info.Icon = new Bitmap(tmpBitmap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Target Frameworks and Dependencies
|
||||
var depsEl = metadata.Element(ns + "dependencies");
|
||||
if (depsEl != null)
|
||||
{
|
||||
var groups = depsEl.Elements(ns + "group").ToList();
|
||||
|
||||
if (groups.Count > 0)
|
||||
{
|
||||
// Collect distinct target frameworks
|
||||
info.TargetFrameworks = groups
|
||||
.Select(g => g.Attribute("targetFramework")?.Value?.Trim())
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
// Format all dependencies grouped by framework
|
||||
var depLines = new List<string>();
|
||||
foreach (var group in groups)
|
||||
{
|
||||
string fw = group.Attribute("targetFramework")?.Value?.Trim();
|
||||
var deps = group.Elements(ns + "dependency").ToList();
|
||||
if (deps.Count == 0) continue;
|
||||
|
||||
if (!string.IsNullOrEmpty(fw))
|
||||
depLines.Add($"[{fw}]");
|
||||
|
||||
foreach (var dep in deps)
|
||||
{
|
||||
string id = dep.Attribute("id")?.Value?.Trim() ?? string.Empty;
|
||||
string ver = dep.Attribute("version")?.Value?.Trim() ?? string.Empty;
|
||||
string exclude = dep.Attribute("exclude")?.Value?.Trim();
|
||||
string line = string.IsNullOrEmpty(ver) ? id : $"{id} ({ver})";
|
||||
depLines.Add($" {line}");
|
||||
}
|
||||
}
|
||||
info.Dependencies = depLines.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No groups — direct top-level dependencies
|
||||
info.Dependencies = depsEl.Elements(ns + "dependency")
|
||||
.Select(d =>
|
||||
{
|
||||
string id = d.Attribute("id")?.Value?.Trim() ?? string.Empty;
|
||||
string ver = d.Attribute("version")?.Value?.Trim() ?? string.Empty;
|
||||
return string.IsNullOrEmpty(ver) ? id : $"{id} ({ver})";
|
||||
})
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Return whatever partial info was collected
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,10 @@ public sealed class Plugin : IViewer
|
||||
|
||||
// Others
|
||||
".wgt", ".wgtu", // UniApp Widget
|
||||
|
||||
// NuGet
|
||||
".nupkg", // NuGet Package
|
||||
".snupkg", // NuGet Symbol Package
|
||||
];
|
||||
|
||||
private IAppInfoPanel _ip;
|
||||
@@ -87,6 +91,7 @@ public sealed class Plugin : IViewer
|
||||
".appimage" => new Size { Width = 600, Height = 300 },
|
||||
".rpm" => new Size { Width = 600, Height = 260 },
|
||||
".wgt" or ".wgtu" => new Size { Width = 600, Height = 345 },
|
||||
".nupkg" or ".snupkg" => new Size { Width = 660, Height = 580 },
|
||||
_ => throw new NotSupportedException("Extension is not supported."),
|
||||
};
|
||||
context.Title = string.Empty;
|
||||
@@ -112,6 +117,7 @@ public sealed class Plugin : IViewer
|
||||
".appimage" => new AppImageInfoPanel(context),
|
||||
".rpm" => new RpmInfoPanel(context),
|
||||
".wgt" or ".wgtu" => new WgtInfoPanel(context),
|
||||
".nupkg" or ".snupkg" => new NugetInfoPanel(context),
|
||||
_ => throw new NotSupportedException("Extension is not supported."),
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,13 @@
|
||||
<TYPE>النوع</TYPE>
|
||||
<TERMINAL>طرفية</TERMINAL>
|
||||
<VENDOR>المورد</VENDOR>
|
||||
<NUGET_PACKAGE_ID>معرّف الحزمة</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>المؤلفون</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>موقع المشروع</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>مستودع المصدر</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>الترخيص</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>أطر العمل المستهدفة</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>التبعيات</NUGET_DEPENDENCIES>
|
||||
</ar>
|
||||
<hu-HU>
|
||||
<PRODUCT_VERSION>Termékverzió</PRODUCT_VERSION>
|
||||
@@ -66,6 +73,13 @@
|
||||
<TYPE>Típus</TYPE>
|
||||
<TERMINAL>Terminál</TERMINAL>
|
||||
<VENDOR>Szállító</VENDOR>
|
||||
<NUGET_PACKAGE_ID>Csomag azonosítója</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Szerzők</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Projekt webhelye</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Forrástár</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Licenc</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Cél keretrendszerek</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Függőségek</NUGET_DEPENDENCIES>
|
||||
</hu-HU>
|
||||
<sk>
|
||||
<PRODUCT_VERSION>Verzia produktu</PRODUCT_VERSION>
|
||||
@@ -99,6 +113,13 @@
|
||||
<TYPE>Typ</TYPE>
|
||||
<TERMINAL>Terminál</TERMINAL>
|
||||
<VENDOR>Dodávateľ</VENDOR>
|
||||
<NUGET_PACKAGE_ID>ID balíka</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Autori</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Webová stránka projektu</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Zdrojové úložisko</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Licencia</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Cieľové rámce</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Závislosti</NUGET_DEPENDENCIES>
|
||||
</sk>
|
||||
<id-ID>
|
||||
<PRODUCT_VERSION>Versi produk</PRODUCT_VERSION>
|
||||
@@ -132,6 +153,13 @@
|
||||
<TYPE>Jenis</TYPE>
|
||||
<TERMINAL>Terminal</TERMINAL>
|
||||
<VENDOR>Vendor</VENDOR>
|
||||
<NUGET_PACKAGE_ID>ID Paket</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Penulis</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Situs Proyek</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Repositori Sumber</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Lisensi</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Target Framework</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Dependensi</NUGET_DEPENDENCIES>
|
||||
</id-ID>
|
||||
<en>
|
||||
<PRODUCT_VERSION>Product Version</PRODUCT_VERSION>
|
||||
@@ -165,6 +193,13 @@
|
||||
<TYPE>Type</TYPE>
|
||||
<TERMINAL>Terminal</TERMINAL>
|
||||
<VENDOR>Vendor</VENDOR>
|
||||
<NUGET_PACKAGE_ID>Package ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Authors</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Project Website</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Source Repository</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>License</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Target Frameworks</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Dependencies</NUGET_DEPENDENCIES>
|
||||
</en>
|
||||
<ko>
|
||||
<PRODUCT_VERSION>제품 버전</PRODUCT_VERSION>
|
||||
@@ -198,6 +233,13 @@
|
||||
<TYPE>유형</TYPE>
|
||||
<TERMINAL>터미널</TERMINAL>
|
||||
<VENDOR>공급업체</VENDOR>
|
||||
<NUGET_PACKAGE_ID>패키지 ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>작성자</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>프로젝트 웹사이트</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>소스 저장소</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>라이선스</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>대상 프레임워크</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>종속성</NUGET_DEPENDENCIES>
|
||||
</ko>
|
||||
<pt-BR>
|
||||
<PRODUCT_VERSION>Versão do produto</PRODUCT_VERSION>
|
||||
@@ -231,6 +273,13 @@
|
||||
<TYPE>Tipo</TYPE>
|
||||
<TERMINAL>Terminal</TERMINAL>
|
||||
<VENDOR>Fornecedor</VENDOR>
|
||||
<NUGET_PACKAGE_ID>ID do pacote</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Autores</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Website do projeto</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Repositório de origem</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Licença</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Frameworks de destino</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Dependências</NUGET_DEPENDENCIES>
|
||||
</pt-BR>
|
||||
<zh-CN>
|
||||
<PRODUCT_VERSION>产品版本</PRODUCT_VERSION>
|
||||
@@ -264,6 +313,13 @@
|
||||
<TYPE>类型</TYPE>
|
||||
<TERMINAL>终端</TERMINAL>
|
||||
<VENDOR>供应商</VENDOR>
|
||||
<NUGET_PACKAGE_ID>包 ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>作者</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>项目网站</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>源代码仓库</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>许可证</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>目标框架</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>依赖项</NUGET_DEPENDENCIES>
|
||||
</zh-CN>
|
||||
<zh-TW>
|
||||
<PRODUCT_VERSION>產品版本</PRODUCT_VERSION>
|
||||
@@ -297,6 +353,13 @@
|
||||
<TYPE>類型</TYPE>
|
||||
<TERMINAL>終端機</TERMINAL>
|
||||
<VENDOR>供應商</VENDOR>
|
||||
<NUGET_PACKAGE_ID>套件 ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>作者</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>專案網站</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>原始碼存放庫</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>授權條款</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>目標架構</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>相依性</NUGET_DEPENDENCIES>
|
||||
</zh-TW>
|
||||
<ja>
|
||||
<PRODUCT_VERSION>製品バージョン</PRODUCT_VERSION>
|
||||
@@ -330,6 +393,13 @@
|
||||
<TYPE>種類</TYPE>
|
||||
<TERMINAL>ターミナル</TERMINAL>
|
||||
<VENDOR>ベンダー</VENDOR>
|
||||
<NUGET_PACKAGE_ID>パッケージ ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>作者</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>プロジェクトのウェブサイト</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>ソースリポジトリ</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>ライセンス</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>対応フレームワーク</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>依存関係</NUGET_DEPENDENCIES>
|
||||
</ja>
|
||||
<de>
|
||||
<PRODUCT_VERSION>Produktversion</PRODUCT_VERSION>
|
||||
@@ -363,6 +433,13 @@
|
||||
<TYPE>Typ</TYPE>
|
||||
<TERMINAL>Terminal</TERMINAL>
|
||||
<VENDOR>Anbieter</VENDOR>
|
||||
<NUGET_PACKAGE_ID>Paket-ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Autoren</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Projekt-Website</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Quell-Repository</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Lizenz</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Ziel-Frameworks</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Abhängigkeiten</NUGET_DEPENDENCIES>
|
||||
</de>
|
||||
<sv>
|
||||
<PRODUCT_VERSION>Produktversion</PRODUCT_VERSION>
|
||||
@@ -396,6 +473,13 @@
|
||||
<TYPE>Typ</TYPE>
|
||||
<TERMINAL>Terminal</TERMINAL>
|
||||
<VENDOR>Leverantör</VENDOR>
|
||||
<NUGET_PACKAGE_ID>Paket-ID</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Upphovsmän</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Projektets webbplats</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Källkodsförvar</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Licens</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Målramverk</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Beroenden</NUGET_DEPENDENCIES>
|
||||
</sv>
|
||||
<ro>
|
||||
<PRODUCT_VERSION>Versiune produs</PRODUCT_VERSION>
|
||||
@@ -429,5 +513,12 @@
|
||||
<TYPE>Tip</TYPE>
|
||||
<TERMINAL>Terminal</TERMINAL>
|
||||
<VENDOR>Furnizor</VENDOR>
|
||||
<NUGET_PACKAGE_ID>ID pachet</NUGET_PACKAGE_ID>
|
||||
<NUGET_AUTHORS>Autori</NUGET_AUTHORS>
|
||||
<NUGET_PROJECT_URL>Site-ul proiectului</NUGET_PROJECT_URL>
|
||||
<NUGET_REPO_URL>Depozit sursă</NUGET_REPO_URL>
|
||||
<NUGET_LICENSE>Licență</NUGET_LICENSE>
|
||||
<NUGET_FRAMEWORKS>Framework-uri țintă</NUGET_FRAMEWORKS>
|
||||
<NUGET_DEPENDENCIES>Dependențe</NUGET_DEPENDENCIES>
|
||||
</ro>
|
||||
</Translations>
|
||||
|
||||
Reference in New Issue
Block a user