Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f52c7908d7 | ||
|
|
abcbf06493 | ||
|
|
f56bcb3627 | ||
|
|
f789c7904a | ||
|
|
e04709637c | ||
|
|
e39f976607 | ||
|
|
0d9ec0ad44 | ||
|
|
122ada92d9 | ||
|
|
d571729c89 | ||
|
|
351e1e97c3 | ||
|
|
cff4c39e8c | ||
|
|
5f41f57e8d | ||
|
|
f2756ddbd8 | ||
|
|
d7a90ca422 | ||
|
|
7404bdfb5d | ||
|
|
5e8de310df | ||
|
|
f3cca9b3a1 | ||
|
|
2154f465b7 | ||
|
|
99bbda4668 | ||
|
|
d1d69da3e3 | ||
|
|
4c8cb807d9 | ||
|
|
1ad64feab9 | ||
|
|
ef7c582c50 |
@@ -57,7 +57,7 @@ namespace AppStore
|
|||||||
|
|
||||||
// 初始化并添加应用信息
|
// 初始化并添加应用信息
|
||||||
infoLabel = new Label();
|
infoLabel = new Label();
|
||||||
infoLabel.Text = "kortapp-z\n版本: 1.1.4\n作者: zs-yg\n一个简单、开源的应用商店\nkortapp-z是完全免费\n基于.NET8和C/C++的软件";
|
infoLabel.Text = "kortapp-z\n版本: 1.2.1\n作者: zs-yg\n一个简单、开源的应用商店\nkortapp-z是完全免费\n基于.NET8和C/C++的软件";
|
||||||
infoLabel.Font = new Font("Microsoft YaHei", 12);
|
infoLabel.Font = new Font("Microsoft YaHei", 12);
|
||||||
infoLabel.AutoSize = false;
|
infoLabel.AutoSize = false;
|
||||||
infoLabel.Width = 300;
|
infoLabel.Width = 300;
|
||||||
|
|||||||
1018
DownloadManager.cs
101
MainForm.cs
@@ -248,6 +248,7 @@ namespace AppStore
|
|||||||
contentPanel.Dock = DockStyle.Fill;
|
contentPanel.Dock = DockStyle.Fill;
|
||||||
contentPanel.BackColor = ThemeManager.BackgroundColor;
|
contentPanel.BackColor = ThemeManager.BackgroundColor;
|
||||||
contentPanel.Padding = new Padding(20);
|
contentPanel.Padding = new Padding(20);
|
||||||
|
contentPanel.AutoScroll = true;
|
||||||
this.Controls.Add(contentPanel);
|
this.Controls.Add(contentPanel);
|
||||||
|
|
||||||
// 添加分隔线
|
// 添加分隔线
|
||||||
@@ -464,44 +465,6 @@ namespace AppStore
|
|||||||
};
|
};
|
||||||
flowPanel.Controls.Add(systemInfoCard);
|
flowPanel.Controls.Add(systemInfoCard);
|
||||||
|
|
||||||
// 视频压缩工具卡片
|
|
||||||
var videoCompressorCard = new ToolCard();
|
|
||||||
videoCompressorCard.ToolName = "视频压缩工具";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "video_compressor.png");
|
|
||||||
if (File.Exists(iconPath))
|
|
||||||
{
|
|
||||||
videoCompressorCard.ToolIcon = Image.FromFile(iconPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
videoCompressorCard.ToolIcon = SystemIcons.Shield.ToBitmap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
videoCompressorCard.ToolIcon = SystemIcons.Shield.ToBitmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
videoCompressorCard.UpdateDisplay();
|
|
||||||
videoCompressorCard.ToolCardClicked += (s, e) => {
|
|
||||||
try {
|
|
||||||
string toolPath = Path.Combine(Application.StartupPath, "resource", "video_compressor.exe");
|
|
||||||
if (File.Exists(toolPath)) {
|
|
||||||
Process.Start(toolPath);
|
|
||||||
} else {
|
|
||||||
MessageBox.Show("视频压缩工具未找到,请确保已正确安装", "错误",
|
|
||||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
MessageBox.Show($"启动视频压缩工具失败: {ex.Message}", "错误",
|
|
||||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
flowPanel.Controls.Add(videoCompressorCard);
|
|
||||||
|
|
||||||
// 计算器工具卡片
|
// 计算器工具卡片
|
||||||
var calculatorCard = new CalculatorToolCard();
|
var calculatorCard = new CalculatorToolCard();
|
||||||
try
|
try
|
||||||
@@ -589,6 +552,23 @@ namespace AppStore
|
|||||||
}
|
}
|
||||||
flowPanel.Controls.Add(selfStartingManagerCard);
|
flowPanel.Controls.Add(selfStartingManagerCard);
|
||||||
|
|
||||||
|
// 图标提取器工具卡片
|
||||||
|
var iconExtractorCard = new AppStore.Tools.IconExtractor.IconExtractorToolCard();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "ico_extractor.png");
|
||||||
|
if (File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
iconExtractorCard.ToolIcon = Image.FromFile(iconPath);
|
||||||
|
}
|
||||||
|
iconExtractorCard.UpdateDisplay();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("加载图标提取器图标失败", ex);
|
||||||
|
}
|
||||||
|
flowPanel.Controls.Add(iconExtractorCard);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -656,11 +636,11 @@ namespace AppStore
|
|||||||
flowPanel.Dock = DockStyle.Fill;
|
flowPanel.Dock = DockStyle.Fill;
|
||||||
flowPanel.AutoScroll = true;
|
flowPanel.AutoScroll = true;
|
||||||
flowPanel.Padding = new Padding(15, 15, 15, 15);
|
flowPanel.Padding = new Padding(15, 15, 15, 15);
|
||||||
flowPanel.WrapContents = true;
|
flowPanel.WrapContents = false;
|
||||||
flowPanel.Margin = new Padding(0);
|
flowPanel.Margin = new Padding(0);
|
||||||
flowPanel.AutoSize = true;
|
flowPanel.AutoSize = true;
|
||||||
flowPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
flowPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||||
flowPanel.AutoScrollMinSize = new Size(0, 3350);
|
flowPanel.AutoScrollMinSize = new Size(0, 5000);
|
||||||
|
|
||||||
// 创建搜索框
|
// 创建搜索框
|
||||||
TextBox searchBox = new TextBox();
|
TextBox searchBox = new TextBox();
|
||||||
@@ -688,11 +668,11 @@ namespace AppStore
|
|||||||
flowPanel.Dock = DockStyle.Fill;
|
flowPanel.Dock = DockStyle.Fill;
|
||||||
flowPanel.AutoScroll = true;
|
flowPanel.AutoScroll = true;
|
||||||
flowPanel.Padding = new Padding(15, 60, 15, 15);
|
flowPanel.Padding = new Padding(15, 60, 15, 15);
|
||||||
flowPanel.WrapContents = true;
|
flowPanel.WrapContents = false;
|
||||||
flowPanel.Margin = new Padding(0);
|
flowPanel.Margin = new Padding(0);
|
||||||
flowPanel.AutoSize = true;
|
flowPanel.AutoSize = true;
|
||||||
flowPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
flowPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||||
flowPanel.AutoScrollMinSize = new Size(0, 3350);
|
flowPanel.AutoScrollMinSize = new Size(0, 5000);
|
||||||
contentPanel.Controls.Add(flowPanel);
|
contentPanel.Controls.Add(flowPanel);
|
||||||
|
|
||||||
// 添加窗体关闭事件处理
|
// 添加窗体关闭事件处理
|
||||||
@@ -730,7 +710,7 @@ namespace AppStore
|
|||||||
flowPanel.Margin = new Padding(0);
|
flowPanel.Margin = new Padding(0);
|
||||||
flowPanel.AutoSize = true;
|
flowPanel.AutoSize = true;
|
||||||
flowPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
flowPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||||
flowPanel.AutoScrollMinSize = new Size(0, 3350);
|
flowPanel.AutoScrollMinSize = new Size(0, 3550);
|
||||||
contentPanel.Controls.Add(flowPanel);
|
contentPanel.Controls.Add(flowPanel);
|
||||||
|
|
||||||
// 添加所有应用卡片并恢复位置
|
// 添加所有应用卡片并恢复位置
|
||||||
@@ -806,6 +786,11 @@ namespace AppStore
|
|||||||
"https://ghproxy.net/https://github.com/msys2/msys2-installer/releases/download/2025-02-21/msys2-x86_64-20250221.exe",
|
"https://ghproxy.net/https://github.com/msys2/msys2-installer/releases/download/2025-02-21/msys2-x86_64-20250221.exe",
|
||||||
"img/png/MSYS2.png"));
|
"img/png/MSYS2.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"OpenJDK by Azul JDKs",
|
||||||
|
"https://cdn.azul.com/zulu/bin/zulu21.42.19-ca-jdk21.0.7-win_x64.msi",
|
||||||
|
"img/png/Azul_JDKs.png"));
|
||||||
|
|
||||||
flowPanel.Controls.Add(CreateAppCard(
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
".NET SDK 8.0",
|
".NET SDK 8.0",
|
||||||
"https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.411-windows-x64-installer",
|
"https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.411-windows-x64-installer",
|
||||||
@@ -841,6 +826,16 @@ namespace AppStore
|
|||||||
"https://ghproxy.net/https://github.com/game1024/OpenSpeedy/releases/download/v1.7.1/OpenSpeedy-v1.7.1.zip",
|
"https://ghproxy.net/https://github.com/game1024/OpenSpeedy/releases/download/v1.7.1/OpenSpeedy-v1.7.1.zip",
|
||||||
"img/png/openspeedy.png"));
|
"img/png/openspeedy.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"Final2x",
|
||||||
|
"https://ghproxy.net/https://github.com/Tohrusky/Final2x/releases/download/2024-12-14/Final2x-windows-x64-setup.exe",
|
||||||
|
"img/png/Final2x.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"Pixpin",
|
||||||
|
"https://download.pixpin.cn/PixPin_2.0.0.3.exe",
|
||||||
|
"img/png/pixpin.png"));
|
||||||
|
|
||||||
flowPanel.Controls.Add(CreateAppCard(
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
"QuickLook",
|
"QuickLook",
|
||||||
"https://ghproxy.net/https://github.com/QL-Win/QuickLook/releases/download/4.0.2/QuickLook-4.0.2.exe",
|
"https://ghproxy.net/https://github.com/QL-Win/QuickLook/releases/download/4.0.2/QuickLook-4.0.2.exe",
|
||||||
@@ -1027,6 +1022,11 @@ namespace AppStore
|
|||||||
"https://ghproxy.net/https://github.com/vnotex/vnote/releases/download/v3.19.2/VNote-3.19.2-win64.zip",
|
"https://ghproxy.net/https://github.com/vnotex/vnote/releases/download/v3.19.2/VNote-3.19.2-win64.zip",
|
||||||
"img/png/vnote.png"));
|
"img/png/vnote.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"notepad--",
|
||||||
|
"https://www.ghproxy.cn/https://github.com/cxasm/notepad--/releases/download/notepad-v3.3/Notepad--v3.3-plugin-Installer.exe",
|
||||||
|
"img/png/notepad--.png"));
|
||||||
|
|
||||||
flowPanel.Controls.Add(CreateAppCard(
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
"PowerToys",
|
"PowerToys",
|
||||||
"https://ghproxy.net/https://github.com/microsoft/PowerToys/releases/download/v0.91.1/PowerToysSetup-0.91.1-x64.exe",
|
"https://ghproxy.net/https://github.com/microsoft/PowerToys/releases/download/v0.91.1/PowerToysSetup-0.91.1-x64.exe",
|
||||||
@@ -1037,6 +1037,16 @@ namespace AppStore
|
|||||||
"https://ghproxy.net/https://github.com/microsoft/terminal/releases/download/v1.22.11141.0/Microsoft.WindowsTerminal_1.22.11141.0_x64.zip",
|
"https://ghproxy.net/https://github.com/microsoft/terminal/releases/download/v1.22.11141.0/Microsoft.WindowsTerminal_1.22.11141.0_x64.zip",
|
||||||
"img/png/terminal.png"));
|
"img/png/terminal.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"github_cli",
|
||||||
|
"https://ghproxy.cn/https://github.com/cli/cli/releases/download/v2.74.2/gh_2.74.2_windows_arm64.msi",
|
||||||
|
"img/png/github_cli.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"ReactOS",
|
||||||
|
"https://ghproxy.cn/https://github.com/reactos/reactos/releases/download/0.4.15-release/ReactOS-0.4.15-release-1-gdbb43bbaeb2-x86-iso.zip",
|
||||||
|
"img/png/ReactOS.png"));
|
||||||
|
|
||||||
flowPanel.Controls.Add(CreateAppCard(
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
"typescript",
|
"typescript",
|
||||||
"https://ghproxy.net/https://github.com/microsoft/TypeScript/releases/download/v5.8.3/typescript-5.8.3.tgz",
|
"https://ghproxy.net/https://github.com/microsoft/TypeScript/releases/download/v5.8.3/typescript-5.8.3.tgz",
|
||||||
@@ -1202,6 +1212,11 @@ namespace AppStore
|
|||||||
"https://ghproxy.net/https://github.com/cloudreve/cloudreve/releases/download/3.8.3/cloudreve_3.8.3_windows_amd64.zip",
|
"https://ghproxy.net/https://github.com/cloudreve/cloudreve/releases/download/3.8.3/cloudreve_3.8.3_windows_amd64.zip",
|
||||||
"img/png/cloudreve.png"));
|
"img/png/cloudreve.png"));
|
||||||
|
|
||||||
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
|
"ollama",
|
||||||
|
"https://www.ghproxy.cn/https://github.com/ollama/ollama/releases/download/v0.9.5/OllamaSetup.exe",
|
||||||
|
"img/png/ollama.png"));
|
||||||
|
|
||||||
flowPanel.Controls.Add(CreateAppCard(
|
flowPanel.Controls.Add(CreateAppCard(
|
||||||
"SeelenUI",
|
"SeelenUI",
|
||||||
"https://ghproxy.net/https://github.com/eythaann/Seelen-UI/releases/download/v2.3.8/Seelen.UI_2.3.8_x64-setup.exe",
|
"https://ghproxy.net/https://github.com/eythaann/Seelen-UI/releases/download/v2.3.8/Seelen.UI_2.3.8_x64-setup.exe",
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace AppStore
|
|||||||
{
|
{
|
||||||
string jsonString = File.ReadAllText(jsonPath);
|
string jsonString = File.ReadAllText(jsonPath);
|
||||||
var jsonData = JsonSerializer.Deserialize<JsonElement>(jsonString);
|
var jsonData = JsonSerializer.Deserialize<JsonElement>(jsonString);
|
||||||
string customPath = jsonData.GetProperty("DownloadPath").GetString();
|
string customPath = jsonData.GetProperty("DownloadPath").GetString() ?? "";
|
||||||
|
|
||||||
// 如果自定义路径有效则显示,否则显示默认路径
|
// 如果自定义路径有效则显示,否则显示默认路径
|
||||||
txtBox.Text = !string.IsNullOrWhiteSpace(customPath) ? customPath : defaultPath;
|
txtBox.Text = !string.IsNullOrWhiteSpace(customPath) ? customPath : defaultPath;
|
||||||
|
|||||||
BIN
img/png/Azul_JDKs.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
img/png/Final2x.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
img/png/ReactOS.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
img/png/github_cli.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
img/png/notepad--.png
Normal file
|
After Width: | Height: | Size: 766 B |
BIN
img/png/ollama.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
img/png/pixpin.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
img/resource/png/ico_extractor.png
Normal file
|
After Width: | Height: | Size: 523 KiB |
|
Before Width: | Height: | Size: 946 KiB |
@@ -2,7 +2,7 @@
|
|||||||
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
||||||
|
|
||||||
#define MyAppName "kortapp-z"
|
#define MyAppName "kortapp-z"
|
||||||
#define MyAppVersion "1.1.4"
|
#define MyAppVersion "1.2.1"
|
||||||
#define MyAppPublisher "zsyg"
|
#define MyAppPublisher "zsyg"
|
||||||
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
||||||
#define MyAppExeName "kortapp-z.exe"
|
#define MyAppExeName "kortapp-z.exe"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
||||||
|
|
||||||
#define MyAppName "kortapp-z"
|
#define MyAppName "kortapp-z"
|
||||||
#define MyAppVersion "1.1.4"
|
#define MyAppVersion "1.2.1"
|
||||||
#define MyAppPublisher "zsyg"
|
#define MyAppPublisher "zsyg"
|
||||||
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
||||||
#define MyAppExeName "kortapp-z.exe"
|
#define MyAppExeName "kortapp-z.exe"
|
||||||
|
|||||||
@@ -131,29 +131,39 @@ namespace AppStore
|
|||||||
{
|
{
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
Image iconImage = null;
|
Image? iconImage = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(item.Value) && System.IO.File.Exists(item.Value))
|
if (!string.IsNullOrEmpty(item.Value) && System.IO.File.Exists(item.Value))
|
||||||
{
|
{
|
||||||
using (Icon icon = Icon.ExtractAssociatedIcon(item.Value))
|
using (Icon icon = Icon.ExtractAssociatedIcon(item.Value))
|
||||||
{
|
{
|
||||||
iconImage = icon.ToBitmap();
|
iconImage = icon?.ToBitmap() ?? SystemIcons.Application.ToBitmap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 使用默认图标
|
// 使用默认图标
|
||||||
iconImage = SystemIcons.Application.ToBitmap();
|
iconImage = SystemIcons.Application?.ToBitmap() ?? SystemIcons.WinLogo.ToBitmap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogWarning($"无法加载程序图标: {item.Value}", ex);
|
Logger.LogWarning($"无法加载程序图标: {item.Value}", ex);
|
||||||
iconImage = SystemIcons.Warning.ToBitmap();
|
// 确保在任何情况下都有有效的图标
|
||||||
|
iconImage = SystemIcons.Warning?.ToBitmap()
|
||||||
|
?? SystemIcons.Error?.ToBitmap()
|
||||||
|
?? SystemIcons.Application?.ToBitmap()
|
||||||
|
?? SystemIcons.WinLogo?.ToBitmap()
|
||||||
|
?? SystemIcons.Shield?.ToBitmap()
|
||||||
|
?? new Bitmap(16, 16);
|
||||||
|
if (iconImage == null)
|
||||||
|
{
|
||||||
|
iconImage = new Bitmap(16, 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataGridView.Rows.Add(iconImage, item.Key, item.Value);
|
dataGridView.Rows.Add(iconImage!, item.Key, item.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
104
tools/ico_extractor/IconExtractor.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace AppStore.Tools.IconExtractor
|
||||||
|
{
|
||||||
|
public static class IconExtractor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取ICO文件中的实际尺寸列表
|
||||||
|
/// </summary>
|
||||||
|
public static List<int> GetIconDimensions(string filePath)
|
||||||
|
{
|
||||||
|
var sizes = new List<int>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||||
|
using (var reader = new BinaryReader(fs))
|
||||||
|
{
|
||||||
|
// 读取ICO文件头
|
||||||
|
reader.ReadUInt16(); // 保留字段
|
||||||
|
ushort type = reader.ReadUInt16(); // 1=ICO, 2=CUR
|
||||||
|
ushort count = reader.ReadUInt16(); // 图像数量
|
||||||
|
|
||||||
|
if (type != 1) return sizes; // 不是ICO文件
|
||||||
|
|
||||||
|
// 读取每个图像目录项
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
byte width = reader.ReadByte();
|
||||||
|
byte height = reader.ReadByte();
|
||||||
|
reader.ReadBytes(14); // 跳过其他字段
|
||||||
|
|
||||||
|
// 宽度/高度为0表示256像素
|
||||||
|
int size = width == 0 ? 256 : width;
|
||||||
|
sizes.Add(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略所有错误,返回空列表
|
||||||
|
}
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
|
||||||
|
private static extern int ExtractIconEx(
|
||||||
|
string lpszFile,
|
||||||
|
int nIconIndex,
|
||||||
|
[AllowNull] IntPtr[] phiconLarge,
|
||||||
|
[AllowNull] IntPtr[] phiconSmall,
|
||||||
|
int nIcons);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
|
private static extern bool DestroyIcon(IntPtr handle);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从文件中提取图标
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">文件路径</param>
|
||||||
|
/// <param name="iconIndex">图标索引</param>
|
||||||
|
/// <param name="largeIcon">是否提取大图标</param>
|
||||||
|
/// <returns>提取的图标</returns>
|
||||||
|
public static Icon ExtractIconFromFile(string filePath, int iconIndex = 0)
|
||||||
|
{
|
||||||
|
IntPtr[] hIcons = new IntPtr[1];
|
||||||
|
int extractedCount = ExtractIconEx(filePath, iconIndex, hIcons, null, 1);
|
||||||
|
|
||||||
|
if (extractedCount <= 0 || hIcons[0] == IntPtr.Zero)
|
||||||
|
throw new FileNotFoundException("无法从文件中提取图标");
|
||||||
|
|
||||||
|
// 直接返回原始图标
|
||||||
|
Icon icon = (Icon)Icon.FromHandle(hIcons[0]).Clone();
|
||||||
|
DestroyIcon(hIcons[0]);
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将图标保存为文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="icon">图标对象</param>
|
||||||
|
/// <param name="outputPath">输出路径</param>
|
||||||
|
public static void SaveIconToFile(Icon icon, string outputPath)
|
||||||
|
{
|
||||||
|
using (FileStream fs = new FileStream(outputPath, FileMode.Create))
|
||||||
|
{
|
||||||
|
icon.Save(fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件中的图标数量
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">文件路径</param>
|
||||||
|
/// <returns>图标数量</returns>
|
||||||
|
public static int GetIconCount(string filePath)
|
||||||
|
{
|
||||||
|
return ExtractIconEx(filePath, -1, null, null, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
tools/ico_extractor/IconExtractorConstants.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
namespace AppStore.Tools.IconExtractor
|
||||||
|
{
|
||||||
|
public static class IconExtractorConstants
|
||||||
|
{
|
||||||
|
public const string FileFilter = "可执行文件|*.exe;*.dll;*.ocx;*.cpl|所有文件|*.*";
|
||||||
|
public const string SaveFilter = "图标文件|*.ico|位图文件|*.bmp|PNG文件|*.png";
|
||||||
|
|
||||||
|
public static readonly int[] SupportedSizes = { 16, 24, 32, 48, 64, 128, 256, 512 };
|
||||||
|
public static readonly int DefaultExtractSize = 256;
|
||||||
|
|
||||||
|
public const string ErrorNoIconsFound = "文件不包含任何图标";
|
||||||
|
public const string ErrorExtractionFailed = "图标提取失败";
|
||||||
|
public const string ErrorInvalidIndex = "无效的图标索引";
|
||||||
|
public const string ErrorFileNotFound = "文件未找到";
|
||||||
|
|
||||||
|
public const int MaxRecentFiles = 5;
|
||||||
|
public const int DefaultPreviewSize = 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
186
tools/ico_extractor/IconExtractorForm.cs
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using AppStore.Tools.IconExtractor;
|
||||||
|
|
||||||
|
namespace AppStore.Tools.IconExtractor
|
||||||
|
{
|
||||||
|
public class IconExtractorForm : Form
|
||||||
|
{
|
||||||
|
private Button btnBrowse = new Button();
|
||||||
|
private Button btnSave = new Button();
|
||||||
|
private NumericUpDown numIconIndex = new NumericUpDown();
|
||||||
|
private PictureBox picIcon = new PictureBox();
|
||||||
|
private Label lblStatus = new Label();
|
||||||
|
private TextBox txtFilePath = new TextBox();
|
||||||
|
private ComboBox cmbIconSize = new ComboBox();
|
||||||
|
private string currentFilePath = string.Empty;
|
||||||
|
|
||||||
|
public IconExtractorForm()
|
||||||
|
{
|
||||||
|
this.Text = "图标提取器";
|
||||||
|
this.Size = new Size(500, 550);
|
||||||
|
this.StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
InitializeComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponents()
|
||||||
|
{
|
||||||
|
// 文件路径文本框
|
||||||
|
txtFilePath.Location = new Point(20, 20);
|
||||||
|
txtFilePath.Size = new Size(300, 25);
|
||||||
|
txtFilePath.ReadOnly = true;
|
||||||
|
this.Controls.Add(txtFilePath);
|
||||||
|
|
||||||
|
// 浏览按钮
|
||||||
|
btnBrowse.Text = "浏览...";
|
||||||
|
btnBrowse.Location = new Point(330, 20);
|
||||||
|
btnBrowse.Size = new Size(80, 25);
|
||||||
|
btnBrowse.Click += BtnBrowse_Click;
|
||||||
|
this.Controls.Add(btnBrowse);
|
||||||
|
|
||||||
|
// 图标索引标签
|
||||||
|
Label lblIndex = new Label();
|
||||||
|
lblIndex.Text = "图标索引:";
|
||||||
|
lblIndex.Location = new Point(20, 60);
|
||||||
|
lblIndex.Size = new Size(80, 20);
|
||||||
|
this.Controls.Add(lblIndex);
|
||||||
|
|
||||||
|
// 图标索引选择器
|
||||||
|
numIconIndex.Location = new Point(100, 60);
|
||||||
|
numIconIndex.Size = new Size(80, 20);
|
||||||
|
numIconIndex.Minimum = 0;
|
||||||
|
numIconIndex.ValueChanged += NumIconIndex_ValueChanged;
|
||||||
|
this.Controls.Add(numIconIndex);
|
||||||
|
|
||||||
|
// 图标预览区域
|
||||||
|
picIcon.Location = new Point(20, 100);
|
||||||
|
picIcon.Size = new Size(256, 256);
|
||||||
|
picIcon.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
picIcon.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
this.Controls.Add(picIcon);
|
||||||
|
|
||||||
|
// 索引说明
|
||||||
|
Label lblIndexHelp = new Label();
|
||||||
|
lblIndexHelp.Text = "索引号表示文件中的第几个图标,从0开始";
|
||||||
|
lblIndexHelp.Location = new Point(20, 240);
|
||||||
|
lblIndexHelp.Size = new Size(300, 20);
|
||||||
|
this.Controls.Add(lblIndexHelp);
|
||||||
|
|
||||||
|
// 保存按钮
|
||||||
|
btnSave.Text = "保存图标";
|
||||||
|
btnSave.Location = new Point(20, 450);
|
||||||
|
btnSave.Size = new Size(100, 30);
|
||||||
|
btnSave.Click += BtnSave_Click;
|
||||||
|
this.Controls.Add(btnSave);
|
||||||
|
|
||||||
|
// 状态标签
|
||||||
|
lblStatus.Location = new Point(20, 490);
|
||||||
|
lblStatus.Size = new Size(400, 20);
|
||||||
|
lblStatus.Text = "请选择包含图标的文件";
|
||||||
|
this.Controls.Add(lblStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnBrowse_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (OpenFileDialog ofd = new OpenFileDialog())
|
||||||
|
{
|
||||||
|
ofd.Filter = "可执行文件|*.exe;*.dll;*.ocx;*.cpl|所有文件|*.*";
|
||||||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
currentFilePath = ofd.FileName;
|
||||||
|
txtFilePath.Text = currentFilePath;
|
||||||
|
LoadIconInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadIconInfo()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int iconCount = IconExtractor.GetIconCount(currentFilePath);
|
||||||
|
numIconIndex.Maximum = Math.Max(0, iconCount - 1);
|
||||||
|
|
||||||
|
// 如果是ICO文件,获取实际包含的尺寸
|
||||||
|
if (currentFilePath.EndsWith(".ico", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var sizes = IconExtractor.GetIconDimensions(currentFilePath);
|
||||||
|
if (sizes.Count > 0)
|
||||||
|
{
|
||||||
|
cmbIconSize.Items.Clear();
|
||||||
|
foreach (var size in sizes)
|
||||||
|
{
|
||||||
|
cmbIconSize.Items.Add($"{size}x{size}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认选择最接近256的尺寸
|
||||||
|
int closest = sizes.OrderBy(s => Math.Abs(s - 256)).First();
|
||||||
|
cmbIconSize.SelectedIndex = sizes.IndexOf(closest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"找到 {iconCount} 个图标";
|
||||||
|
ExtractAndDisplayIcon();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
lblStatus.Text = $"错误: {ex.Message}";
|
||||||
|
picIcon.Image = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NumIconIndex_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(currentFilePath))
|
||||||
|
{
|
||||||
|
ExtractAndDisplayIcon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractAndDisplayIcon()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Icon icon = IconExtractor.ExtractIconFromFile(currentFilePath, (int)numIconIndex.Value);
|
||||||
|
picIcon.Image = icon.ToBitmap();
|
||||||
|
lblStatus.Text = $"显示原始图标 #{numIconIndex.Value}";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
lblStatus.Text = $"提取图标失败: {ex.Message}";
|
||||||
|
picIcon.Image = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (picIcon.Image == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("没有可保存的图标", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (SaveFileDialog sfd = new SaveFileDialog())
|
||||||
|
{
|
||||||
|
sfd.Filter = "图标文件|*.ico|位图文件|*.bmp|PNG文件|*.png";
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Icon icon = IconExtractor.ExtractIconFromFile(currentFilePath, (int)numIconIndex.Value))
|
||||||
|
{
|
||||||
|
IconExtractor.SaveIconToFile(icon, sfd.FileName);
|
||||||
|
lblStatus.Text = $"已保存原始图标到 {sfd.FileName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"保存图标失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
tools/ico_extractor/IconExtractorHelper.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AppStore.Tools.IconExtractor
|
||||||
|
{
|
||||||
|
public static class IconExtractorHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将图标转换为位图
|
||||||
|
/// </summary>
|
||||||
|
public static Bitmap ConvertIconToBitmap(Icon icon, Size size)
|
||||||
|
{
|
||||||
|
Bitmap bitmap = new Bitmap(size.Width, size.Height);
|
||||||
|
using (Graphics g = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
g.DrawIcon(icon, new Rectangle(0, 0, size.Width, size.Height));
|
||||||
|
}
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量提取文件中的所有图标
|
||||||
|
/// </summary>
|
||||||
|
public static List<Icon> ExtractAllIcons(string filePath)
|
||||||
|
{
|
||||||
|
List<Icon> icons = new List<Icon>();
|
||||||
|
int count = IconExtractor.GetIconCount(filePath);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Icon icon = IconExtractor.ExtractIconFromFile(filePath, i);
|
||||||
|
icons.Add(icon);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略提取失败的图标
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将图标保存为PNG格式
|
||||||
|
/// </summary>
|
||||||
|
public static void SaveIconAsPng(Icon icon, string outputPath)
|
||||||
|
{
|
||||||
|
using (Bitmap bitmap = icon.ToBitmap())
|
||||||
|
{
|
||||||
|
bitmap.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查文件是否包含图标
|
||||||
|
/// </summary>
|
||||||
|
public static bool HasIcons(string filePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return IconExtractor.GetIconCount(filePath) > 0;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
123
tools/ico_extractor/IconExtractorSettings.cs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace AppStore.Tools.IconExtractor
|
||||||
|
{
|
||||||
|
public static class IconExtractorSettings
|
||||||
|
{
|
||||||
|
private static readonly string SettingsPath = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||||
|
"kortapp-z", "icon_extractor_settings.json");
|
||||||
|
|
||||||
|
public static SettingsData CurrentSettings { get; private set; } = new SettingsData();
|
||||||
|
|
||||||
|
public class SettingsData
|
||||||
|
{
|
||||||
|
public string LastUsedDirectory { get; set; } = string.Empty;
|
||||||
|
public string DefaultSaveFormat { get; set; } = "ico";
|
||||||
|
public int DefaultIconSize { get; set; } = 128;
|
||||||
|
public string[] RecentFiles { get; set; } = Array.Empty<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载设置
|
||||||
|
/// </summary>
|
||||||
|
public static void LoadSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(SettingsPath))
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(SettingsPath);
|
||||||
|
if (!string.IsNullOrWhiteSpace(json))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (JsonDocument doc = JsonDocument.Parse(json))
|
||||||
|
{
|
||||||
|
var root = doc.RootElement;
|
||||||
|
CurrentSettings = new SettingsData
|
||||||
|
{
|
||||||
|
LastUsedDirectory = root.TryGetProperty("LastUsedDirectory", out var dir) ? dir.GetString() ?? string.Empty : string.Empty,
|
||||||
|
DefaultSaveFormat = root.TryGetProperty("DefaultSaveFormat", out var format) ? format.GetString() ?? "ico" : "ico",
|
||||||
|
DefaultIconSize = root.TryGetProperty("DefaultIconSize", out var size) ? size.GetInt32() : 128,
|
||||||
|
RecentFiles = root.TryGetProperty("RecentFiles", out var files) ?
|
||||||
|
JsonSerializer.Deserialize<string[]>(files.GetRawText()) ?? Array.Empty<string>() :
|
||||||
|
Array.Empty<string>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
CurrentSettings = new SettingsData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 加载失败时使用默认设置
|
||||||
|
CurrentSettings = new SettingsData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存设置
|
||||||
|
/// </summary>
|
||||||
|
public static void SaveSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SettingsPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string directory = Path.GetDirectoryName(SettingsPath);
|
||||||
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
string json = JsonSerializer.Serialize(CurrentSettings);
|
||||||
|
File.WriteAllText(SettingsPath, json);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略保存错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加最近使用的文件
|
||||||
|
/// </summary>
|
||||||
|
public static void AddRecentFile(string filePath)
|
||||||
|
{
|
||||||
|
if (CurrentSettings.RecentFiles.Length >= 5)
|
||||||
|
{
|
||||||
|
var list = new List<string>(CurrentSettings.RecentFiles);
|
||||||
|
list.RemoveAt(0);
|
||||||
|
CurrentSettings.RecentFiles = list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
var newList = new List<string>(CurrentSettings.RecentFiles);
|
||||||
|
if (!newList.Contains(filePath))
|
||||||
|
{
|
||||||
|
newList.Add(filePath);
|
||||||
|
CurrentSettings.RecentFiles = newList.ToArray();
|
||||||
|
SaveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新最后使用的目录
|
||||||
|
/// </summary>
|
||||||
|
public static void UpdateLastUsedDirectory(string directory)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(directory) && CurrentSettings.LastUsedDirectory != directory)
|
||||||
|
{
|
||||||
|
CurrentSettings.LastUsedDirectory = directory;
|
||||||
|
SaveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
tools/ico_extractor/IconExtractorToolCard.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace AppStore.Tools.IconExtractor
|
||||||
|
{
|
||||||
|
public class IconExtractorToolCard : ToolCard
|
||||||
|
{
|
||||||
|
public IconExtractorToolCard()
|
||||||
|
{
|
||||||
|
ToolName = "图标提取器";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "QRcode.png");
|
||||||
|
if (File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
ToolIcon = Image.FromFile(iconPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ToolIcon = SystemIcons.Application.ToBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
ToolIcon = SystemIcons.Application.ToBitmap();
|
||||||
|
}
|
||||||
|
this.ToolCardClicked += OnIconExtractorCardClicked;
|
||||||
|
UpdateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnIconExtractorCardClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var iconExtractorForm = new IconExtractorForm();
|
||||||
|
iconExtractorForm.ShowDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||