gpt4 book ai didi

C# - WPF - 添加图标后的项目大小(从资源加载图标或从项目 EXE 中提取)

转载 作者:行者123 更新时间:2023-11-30 12:25:54 30 4
gpt4 key购买 nike

Edit1:编辑标题

Edit2: 添加了方法 3

Edit3: 添加了方法 4


我正在创建一个非常小的应用程序/实用程序,总共只有 20KB。我的包含各种大小的图标文件是 40KB。

我添加图标的方法是在解决方案资源管理器中右键单击我的项目并单击“现有项...”,然后我会再次右键单击我的项目,转到“属性”->“应用程序”在“图标和 list ”下,我为整个项目选择我的新图标。

这样做会在我的所有表单、exe、任务栏等中显示我的图标...除了系统托盘图标。

我加载系统托盘图标的方式是从 EXE 中提取图标:

方法一:

Icon ico = System.Drawing.Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
notifyIcon.Icon = ico;

现在我加载了所有图标后的总项目大小为 20KB + 40KB = 60KB <- 这就是我所追求的。

我想知道这是否是加载我所有图标的正确方式?

我知道我可以在“资源”项目中添加我的图标并执行:

方法二:

notifyIcon.Icon = PROJECTNAME.Properties.Resources.icon;

但是,这只会使图标大小加倍,然后在顶部添加项目大小。所以:

20KB(项目大小)+ 40KB(EXE 图标)+ 40KB(资源图标)= 100KB

方法三

“Discord”在下面的答案中发布了另一种直接从可执行资源中获取文件的方法。

IntPtr hIcon = LoadIcon(GetModuleHandle(null), new IntPtr(32512));
notifyIcon.Icon = Icon.FromHandle(hIcon);

[DllImport("user32.dll")]
static extern IntPtr LoadIcon (IntPtr hInstance, IntPtr iconName);
[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle (string moduleName);

目前方法 1 和方法 3 的唯一问题是图标在 32x32 中提取,然后缩小到 16x16,这在系统托盘中看起来不太好。

此答案由“vanmelle”提供:Avoiding duplicate icon resources in a .NET (C#) project描述了如何获得 16x16 的图标,但不确定这是否会获得 HiDPI 分辨率的 32x32 版本

方法四

从项目 EXE 中提取图标似乎是 16x16 或 32x32,具体取决于所使用的代码。不能两者都做,让操作系统选择它想要的 HiDPI 系统。不幸的是,我要做系统托盘图标的方法是创建另一个图标文件,该文件只有我的应用程序图标的 16x16 和 32x32 版本,然后像这样使用它:(幸运的是我的 16x16、32x32 应用程序图标只有 4KB)

notifyIcon.Icon = new System.Drawing.Icon(Properties.Resources.ico, System.Windows.Forms.SystemInformation.SmallIconSize);

如果需要,此方法将调用 16x16 图标或 32x32 图标。

你可以这样做:

notifyIcon.Icon = new System.Drawing.ico;

但这将始终调用 32x32 图标并将其缩小到 16x16,这在系统托盘中可能看起来不太好。


最初,我的做法是将图标添加到“资源”,然后让 notifyIcon 从那里调用它。然后在 Solution Explorer - Project Name -> "Properties"-> "Application"中我会选择项目图标。这会加载我的图标大小两次,使我的项目从(20KB + 40KB 图标)跳到 100KB

目前,我正在使用方法 1。我想知道是否有更好的方法来加载我的图标并保持我的应用程序较小而不是两次增加图标大小?

虽然我确实知道 60KB 和 100KB 之间的差异并不是什么大问题,但我只是想大致了解一下以备将来引用。另外,想知道我的第一种方法是否有任何注意事项?

我有网络开发背景,对 C# 和 WPF 还很陌生。

最佳答案

您在项目属性中添加的图标会添加到可执行文件的资源(.rsrc 部分),标识符为 32512 (IDI_APPLICATION)。如果您不喜欢依赖 Icon.ExtractAssociatedIcon,您可以使用更直接的方法来提取它 - 使用 LoadIcon 函数。虽然它没有包含在 .NET 中,因此还有更多代码:

IntPtr hIcon = LoadIcon(GetModuleHandle(null), new IntPtr(32512));
notifyIcon.Icon = Icon.FromHandle(hIcon);

[DllImport("user32.dll")]
static extern IntPtr LoadIcon (IntPtr hInstance, IntPtr iconName);
[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle (string moduleName);

参见 Using the same icon for the .exe and a form in a Windows Forms application without duplicating it?有关详细信息的问题。

WPF 包含在 HICONImageSource 之间来回转换图标的方法,所以如果你想在窗体上显示图标,例如,你可以这样做也是(参见 Imaging.CreateBitmapSourceFromHIcon 等)。

如果 Icon.ExtractAssociatedIcon 工作正常,我认为没有理由为此烦恼。不过,可能存在一些问题,此功能可能不会提取所有图标,而只会提取特定尺寸的图标。

另见 Avoiding duplicate icon resources in a .NET C# project问题。

关于C# - WPF - 添加图标后的项目大小(从资源加载图标或从项目 EXE 中提取),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30405818/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com