Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal:The AppWindow.SetIcon() set icon supports exe or dll files, as does the IExplorerCommand.GetIcon() method. #10036

Open
Gaoyifei1011 opened this issue Oct 4, 2024 · 3 comments
Labels
feature proposal New feature proposal needs-triage Issue needs to be triaged by the area owners

Comments

@Gaoyifei1011
Copy link

Gaoyifei1011 commented Oct 4, 2024

Proposal: The AppWindow.SetIcon() set icon supports exe or dll files, as does the IExplorerCommand.GetIcon() method.

AppWindow.SetIcon() 设置图标支持 exe 或者 dll 文件,就像 IExplorerCommand.GetIcon() 方法那样。


Summary

AppWindow.SetIcon() method currently only supports two ways to set icons, one is to directly add ico file path, the other is to add loaded icon handle, hopefully in the future can support more ways, such as GetIcon() method in IExplorerCommand,We can just add the dll file path and the index to display the icon. Hopefully, this will work for AppWindow.SetIcon() as well

----------------------

AppWindow.SetIcon() 方法设置图标目前仅支持两种方式,一种直接添加 ico 的文件路径,另一种是添加已加载的图标句柄,希望未来可以支持更多方式,比如在 IExplorerCommand 的 GetIcon() 方法,我们可以直接添加 dll 的文件路径和图标对应的索引来显示对应的图标,希望这个方法也能运用在 AppWindow.SetIcon() 上


Reference links(参考链接)
IExplorerCommand.GetIcon(): https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-geticon
AppWindow.SetIcon: https://learn.microsoft.com/zh-cn/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindow.seticon?view=windows-app-sdk-1.6


Rationale

This allows us to directly use the application's icon as the window icon

----------------------

这样我们可以直接使用应用程序的图标作为窗口图标

Scope

Capability Priority
This proposal will allow developers to accomplish W Must
This proposal will allow end users to accomplish X Should
This proposal will allow developers to accomplish Y Could
This proposal will allow end users to accomplish Z Won't

Important Notes

Open Questions

@Gaoyifei1011 Gaoyifei1011 added the feature proposal New feature proposal label Oct 4, 2024
Copy link

github-actions bot commented Oct 4, 2024

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one. Thank you!

Open similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Oct 4, 2024
@Gaoyifei1011 Gaoyifei1011 changed the title Proposal: Proposal:The AppWindow.SetIcon() set icon supports exe or dll files, as does the IExplorerCommand.SetIocn() method. Oct 4, 2024
@Gaoyifei1011 Gaoyifei1011 changed the title Proposal:The AppWindow.SetIcon() set icon supports exe or dll files, as does the IExplorerCommand.SetIocn() method. Proposal:The AppWindow.SetIcon() set icon supports exe or dll files, as does the IExplorerCommand.GetIcon() method. Oct 4, 2024
@castorix
Copy link

castorix commented Oct 4, 2024

You can use ExtractIconEx
A test :

                string sDllPath = @"C:\WINDOWS\System32\SHELL32.dll";
                int nIconIndex = 43; // Star             
                IntPtr hIcon = GetIconHandle(sDllPath, nIconIndex);
                if (hIcon != IntPtr.Zero)
                {
                    this.AppWindow.SetIcon(Microsoft.UI.Win32Interop.GetIconIdFromIcon(hIcon));
                }

with

        [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, int nIcons);

        public static IntPtr GetIconHandle(string sDllPath, int nIconIndex)
        {
            IntPtr[] largeIcons = new IntPtr[1];
            IntPtr[] smallIcons = new IntPtr[1];            
            int nExtractedIcons = ExtractIconEx(sDllPath, nIconIndex, largeIcons, smallIcons, 1);
            if (nExtractedIcons > 0 && largeIcons[0] != IntPtr.Zero)
            {               
                return largeIcons[0];
            }
            return IntPtr.Zero;
        }

@Gaoyifei1011
Copy link
Author

Gaoyifei1011 commented Oct 6, 2024

You can use ExtractIconEx A test :

                string sDllPath = @"C:\WINDOWS\System32\SHELL32.dll";
                int nIconIndex = 43; // Star             
                IntPtr hIcon = GetIconHandle(sDllPath, nIconIndex);
                if (hIcon != IntPtr.Zero)
                {
                    this.AppWindow.SetIcon(Microsoft.UI.Win32Interop.GetIconIdFromIcon(hIcon));
                }

with

        [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, int nIcons);

        public static IntPtr GetIconHandle(string sDllPath, int nIconIndex)
        {
            IntPtr[] largeIcons = new IntPtr[1];
            IntPtr[] smallIcons = new IntPtr[1];            
            int nExtractedIcons = ExtractIconEx(sDllPath, nIconIndex, largeIcons, smallIcons, 1);
            if (nExtractedIcons > 0 && largeIcons[0] != IntPtr.Zero)
            {               
                return largeIcons[0];
            }
            return IntPtr.Zero;
        }
        [LibraryImport(User32, EntryPoint = "PrivateExtractIconsW", SetLastError = false, StringMarshalling = StringMarshalling.Utf16), PreserveSig]
        public static partial int PrivateExtractIcons([MarshalAs(UnmanagedType.LPWStr)] string lpszFile, int nIconIndex, int cxIcon, int cyIcon, [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] phicon, [Out, MarshalAs(UnmanagedType.LPArray)] int[] piconid, int nIcons, int flags);

        private void SetAppIcon()
        {
            int iconTotalCount = PrivateExtractIcons(Environment.ProcessPath, 0, 0, 0, null, null, 0, 0);

            hIcons = new IntPtr[iconTotalCount];

            int[] ids = new int[iconTotalCount];

            int successCount = PrivateExtractIcons(Environment.ProcessPath, 0, 256, 256, hIcons, ids, iconTotalCount, 0);

            if (successCount >= 1 && hIcons[0] != IntPtr.Zero)
            {
                AppWindow.SetIcon(Win32Interop.GetIconIdFromIcon(hIcons[0]));
            }
    }

感谢您的回答,我已经使用 PrivateExtractIcons 从 exe 文件中获取图标并作为窗口图标显示,但我希望 Windows App SDK 或 WinUI 团队能扩展一下这个方法,可以直接从 exe 文件中读取图标,而不只是仅限于 ico 文件
Thanks for your answer, I already use PrivateExtractIcons to get ICONS from exe files and display them as window ICONS, but I would like the Windows App SDK or WinUI team to extend this method to read ICONS directly from exe files. And not just limited to ico files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature proposal New feature proposal needs-triage Issue needs to be triaged by the area owners
Projects
None yet
Development

No branches or pull requests

2 participants