none
Как открыть My Computer C# WPF RRS feed

Ответы

  • Например так:

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Runtime.InteropServices;
    using System.Threading.Tasks;
    using System.Net;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            const string prefix = "MyComputer";
            const int port = 8080;
            ShellItemsHttpListener listener;
            public static Guid FOLDERID_ComputerFolder = new Guid("0AC0837C-BBF8-452A-850D-79D08E667CA7");        
    
            public MainWindow()
            {         
                InitializeComponent();
                List<ShellItem> items = GetItems(FOLDERID_ComputerFolder); //получаем список элементов каталога
                listener = new ShellItemsHttpListener(items, prefix, port);
                listener.Start(); //запускаем HTTP-сервер
                webbrowser.Navigate("http://localhost:" + port.ToString() + "/" + prefix + "/"); //открываем страницу в WebBrowser
                webbrowser.Navigating += webbrowser_Navigating;
            }
    
            void webbrowser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
            {
                //обработка перенаправлений URL с http:// на file://
                Uri uri = listener.ProcessRedirect(e.Uri.AbsoluteUri);
                if (uri != null) { webbrowser.Navigate(uri); e.Cancel = true; }            
            }
    
            private void bHome_Click(object sender, RoutedEventArgs e)
            {            
                webbrowser.Navigate("http://localhost:" + port.ToString() + "/" + prefix + "/");    
            }
    
            public static List<ShellItem> GetItems(Guid FolderID) //Получает список элементов каталога по GUID
            {            
                IntPtr p = IntPtr.Zero;
                IShellFolder pFolder = null;
                IEnumIDList pEnum = null;
                IntPtr pItem = IntPtr.Zero;                      
                IntPtr lpStr = IntPtr.Zero;
                STRRET strret;
                Guid guid = typeof(IShellFolder).GUID;
                List<ShellItem> items = new List<ShellItem>();
                ShellItem si;          
    
                try
                {
                    int hr = SHGetKnownFolderIDList(ref FolderID, 0, IntPtr.Zero, out p);
                    if (hr != 0) throw Marshal.GetExceptionForHR(hr);
    
                    hr = SHBindToObject(null, p, null, ref guid, out pFolder);
                    if (hr != 0) throw Marshal.GetExceptionForHR(hr);
                                    
                    pFolder.EnumObjects(IntPtr.Zero, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, out pEnum); 
    
                    while (true)
                    {
                        pItem = IntPtr.Zero; 
                        uint res = pEnum.Next(1, out pItem, IntPtr.Zero);
                        if (res != 0) break;
                        si = new ShellItem();
    
                        //display name
                        lpStr = IntPtr.Zero;
                        strret = new STRRET();
                        pFolder.GetDisplayNameOf(pItem, SHGDN_NORMAL, out strret); 
                        hr = StrRetToStr(ref strret, pItem, out lpStr);
                        if (hr != 0) throw Marshal.GetExceptionForHR(hr);
                        string s = Marshal.PtrToStringUni(lpStr);
                        si.DisplayName = s;
                        CoTaskMemFree(lpStr);
    
                        //path
                        lpStr = IntPtr.Zero;
                        strret = new STRRET();
                        pFolder.GetDisplayNameOf(pItem, SHGDN_FORPARSING, out strret);
                        hr = StrRetToStr(ref strret, pItem, out lpStr);
                        if (hr != 0) throw Marshal.GetExceptionForHR(hr);
                        s = Marshal.PtrToStringUni(lpStr);
                        try { si.Path = new Uri(s); }
                        catch (UriFormatException) { si.Path = new Uri("file://localhost/"); }
                        CoTaskMemFree(lpStr);
    
                        //icon
                        Guid iid_IIExtractIcon = typeof(IExtractIcon).GUID;
                        IExtractIcon pExtract;
                        pFolder.GetUIObjectOf(IntPtr.Zero, 1, new IntPtr[] { pItem }, ref iid_IIExtractIcon, 0, out pExtract);
                        
                        StringBuilder sbIcon = new StringBuilder(260);
                        int index=0;
                        uint flags; 
                        hr = pExtract.GetIconLocation(GIL_FORSHELL, sbIcon, 260, out index, out flags);
                        if (hr == 0)
                        {
                            IntPtr hIconSmall = IntPtr.Zero, hIconLarge = IntPtr.Zero;
                            hr = pExtract.Extract(sbIcon.ToString(), (uint)index, out hIconLarge, out hIconSmall, 0x00140014);
                            if (hr == 0 && hIconSmall != IntPtr.Zero)
                            {
                                var icon = System.Drawing.Icon.FromHandle(hIconSmall);
                                var bitmap = icon.ToBitmap();
    
                                using (bitmap)
                                {
                                    MemoryStream ms = new MemoryStream();
                                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                                    si.Image = ms.ToArray();
                                }
    
                                DestroyIcon(hIconSmall);
                                DestroyIcon(hIconLarge);
                            }
                            else { si.Image = new byte[0]; }                       
                        }
                        else
                        {
                            si.Image = new byte[0];
                        }
                        items.Add(si);
                        CoTaskMemFree(pItem);
                    }
    
                    return items;
                }
                finally
                {
                    if (p != IntPtr.Zero) CoTaskMemFree(p);
                    if (pFolder != null) Marshal.ReleaseComObject(pFolder);
                    if (pEnum != null) Marshal.ReleaseComObject(pEnum);
                }
    
            }                     
    
            public const uint SHGFI_DISPLAYNAME = 0x000000200;
            public const uint SHGFI_ICON = 0x000000100;
            public const uint SHGFI_PIDL = 0x000000008;
            public const uint GIL_FORSHELL = 0x0002;
            public const int SHGDN_NORMAL = 0x0000;
            public const int SHGDN_FORPARSING = 0x8000;
            public const int SHCONTF_FOLDERS = 0x0020;
            public const int SHCONTF_NONFOLDERS = 0x0040;                
    
            [DllImport("shell32.dll")]
            public static extern int SHGetKnownFolderIDList(ref Guid rfid, int dwFlags, IntPtr hToken, out IntPtr ppidl);
            
            [DllImport("ole32.dll")]
            static extern void CoTaskMemFree(IntPtr pv);
            
            [DllImport("shell32.dll")]        
            static extern int SHBindToObject(
                IShellFolder psf,
                IntPtr pidl,
                [MarshalAs(UnmanagedType.IUnknown)] object pbc,
                ref Guid riid,
                out IShellFolder ppv);
    
            [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
            static extern int StrRetToStr( ref STRRET pstr,  IntPtr pidl, out IntPtr ppsz);
            
            [DllImport("user32.dll")]
            static extern bool DestroyIcon(IntPtr hIcon);
        }
    
        public struct ShellItem
        {
            public string DisplayName { get; set; }
            public Uri Path { get; set; }
            public byte[] Image { get; set; }
        }
    
        public class ShellItemsHttpListener //возвращает содержимое каталога в виде веб-страницы
        {
            Dictionary<string, byte[]> images; //таблица изображений
            Dictionary<string, Uri> redirects; //таблица редиректов
            string html;
            string urlprefix;
            int httpport;
            HttpListener listener;        
    
            public ShellItemsHttpListener(List<ShellItem> items, string prefix, int port)
            {
                StringBuilder sb = new StringBuilder();
                int n = 1;
    
                //генерируем веб-страницу...
                //устанавливаем режим IE8, чтобы работали стили
                sb.Append("<html><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\" /><style>");
    
                //устанавливаем стили, имитирующий внешний вид проводника (в режиме просмотра "Список")
                sb.Append("a { color: black; text-decoration: none;  } a:hover { color: black; text-decoration: underline;} ");
                sb.Append("tr:hover { background-color: lightblue;} img {border:none;}");
                sb.Append("</style></head><body>");
    
                //формируем список элементов
                sb.Append("<table cellspacing=\"0\" border=\"0\">");
                images = new Dictionary<string, byte[]>();
                redirects = new Dictionary<string, Uri>();
                
                foreach (ShellItem item in items)
                {                
                    sb.Append("<tr><td><a href=\"" + n.ToString() + ".html\" >");
                    sb.Append("<img width=\"20\" height=\"20\" src=\"" + n.ToString() + ".png\"/></a></td>");  
                    sb.Append("<td><a href=\"" + n.ToString() + ".html\" >");
                    sb.Append(item.DisplayName + "</a></td></tr>");
                    images[n.ToString() + ".png"] = item.Image;
                    redirects[n.ToString() + ".html"] = item.Path;
                    n++;
                }
                sb.Append("</table></body></html>");
                html = sb.ToString();
    
                //инициализация HttpListener...
                listener = new HttpListener();            
                listener.Prefixes.Add("http://localhost:"+port.ToString()+"/" + prefix+"/");
                urlprefix = prefix;
                httpport = port;
            }
    
            public void Start() //запускает HTTP-сервер     
            {           
                Task.Run(() =>
                {
                    try
                    {
                        listener.Start();
                        while (true)
                        {                        
                            HttpListenerContext context = listener.GetContext(); //ожидаем запроса
                            HttpListenerRequest request = context.Request;
                            HttpListenerResponse response = context.Response;
    
                            //анализ URL...
                            byte[] buffer = new byte[0];
                            string urlbegin = "/" + urlprefix + "/";
                            string urlfile = request.RawUrl.Substring(urlbegin.Length);
                            if (urlfile == "" || urlfile.StartsWith("index") || urlfile.StartsWith("default"))
                            {
                                //отдаем основную страницу
                                buffer = System.Text.Encoding.UTF8.GetBytes(html);
                                response.ContentLength64 = buffer.Length;
                                response.ContentEncoding = Encoding.UTF8;
                            }
                            else if (urlfile.EndsWith(".png"))
                            {
                                //отдаем изображение
                                buffer = images[urlfile];
                                response.ContentLength64 = buffer.Length;
                                response.ContentType = "image/png";
                            }
                            else
                            {
                                buffer = System.Text.Encoding.UTF8.GetBytes("Ошибка: Страница не найдена");
                                response.StatusCode = 404;
                                response.ContentType = "text/plain";
                            }
    
                            //возвращаем ответ
                            System.IO.Stream output = response.OutputStream;
                            output.Write(buffer, 0, buffer.Length);
                            output.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "HttpListener error");
                    }
                });
            }
    
            public Uri ProcessRedirect(string inputurl)
            {
                //обработка перенаправлений...            
                string urlbegin = "http://localhost:" + httpport.ToString() + "/" + urlprefix + "/";
    
                if (inputurl.StartsWith(urlbegin))
                {
                    string urlfile = inputurl.Substring(urlbegin.Length);
                    if (!urlfile.EndsWith(".html")) return null;
    
                    if (redirects.ContainsKey(urlfile))
                    {
                        return redirects[urlfile];
                    }
                    else return null;
                }
                else return null;
            }
        }    
        
        /* COM Interfaces */
    
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214E6-0000-0000-C000-000000000046")]
        public interface IShellFolder
        {
            void ParseDisplayName(IntPtr hwnd, IntPtr pbc, String pszDisplayName, UInt32 pchEaten, out IntPtr ppidl, UInt32 pdwAttributes);
            void EnumObjects(IntPtr hwnd, int grfFlags, out IEnumIDList ppenumIDList);
            void BindToObject(IntPtr pidl, IntPtr pbc, [In]ref Guid riid, out IntPtr ppv);
            void BindToStorage(IntPtr pidl, IntPtr pbc, [In]ref Guid riid, out IntPtr ppv);
            [PreserveSig]  Int32 CompareIDs(Int32 lParam, IntPtr pidl1, IntPtr pidl2);
            void CreateViewObject(IntPtr hwndOwner, [In] ref Guid riid, out IntPtr ppv);
            void GetAttributesOf(UInt32 cidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]IntPtr[] apidl, ref uint rgfInOut);
            void GetUIObjectOf(IntPtr hwndOwner, UInt32 cidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]IntPtr[] apidl, 
                [In] ref Guid riid, UInt32 rgfReserved, out IExtractIcon ppv);
            void GetDisplayNameOf(IntPtr pidl, int uFlags, out STRRET pName);
            void SetNameOf(IntPtr hwnd, IntPtr pidl, String pszName, int uFlags, out IntPtr ppidlOut);
        }   
        
        [StructLayout(LayoutKind.Explicit, Size = 520)]
        public struct STRRETinternal
        {
            [FieldOffset(0)] public IntPtr pOleStr;
    
            [FieldOffset(0)] public IntPtr pStr;  
    
            [FieldOffset(0)] public uint uOffset;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct STRRET
        {
            public uint uType;
            public STRRETinternal data;
        }
    
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214F2-0000-0000-C000-000000000046")]
        public interface IEnumIDList
        {
            [PreserveSig()] uint Next(uint celt, out IntPtr rgelt, IntPtr pceltFetched);
            [PreserveSig()] uint Skip(uint celt);
            [PreserveSig()] uint Reset();
            [PreserveSig()] uint Clone(out IEnumIDList ppenum);
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }
    
        [ComImport()]
        [Guid("000214fa-0000-0000-c000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IExtractIcon
        {
            [PreserveSig] int GetIconLocation(
                uint uFlags,
                [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 2)] StringBuilder szIconFile,
                int cchMax,
                out int piIndex,
                out uint pwFlags);
    
    
            [PreserveSig] int Extract(
                [MarshalAs(UnmanagedType.LPWStr)] string pszFile, uint nIconIndex, out IntPtr phiconLarge,
                out IntPtr phiconSmall, uint nIconSize);
        }   
    }
    

    Источник: https://devblogs.microsoft.com/oldnewthing/?p=9773

    Это, конечно, не настоящий "Мой компьютер", но подделано довольно качественно:

    mycomputer

    Картину только портит багнутый "Мои веб-узлы MSN", который ведет в никуда и для которого не работает извлечение иконки. Извращения с обработкой webbrowser_Navigating здесь нужны из-за того, что настройки безопасности не позволяют просто так переходить с http://localhost/ на file://localhost/

    26 августа 2019 г. 12:14

Все ответы

  • Здравствуйте,

    Попробуйте такой вариант:

     OpenFileDialog d = new OpenFileDialog();
     d.InitialDirectory = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
     d.ShowDialog();


    Если Вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение" Мнения, высказанные здесь, являются отражение моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.

    23 августа 2019 г. 13:47
    Модератор
  • Это откроет мой компьютер в диалоговом окне мне нужно открыть его в WebBrowser
    24 августа 2019 г. 9:02
  • Например так:

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Runtime.InteropServices;
    using System.Threading.Tasks;
    using System.Net;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            const string prefix = "MyComputer";
            const int port = 8080;
            ShellItemsHttpListener listener;
            public static Guid FOLDERID_ComputerFolder = new Guid("0AC0837C-BBF8-452A-850D-79D08E667CA7");        
    
            public MainWindow()
            {         
                InitializeComponent();
                List<ShellItem> items = GetItems(FOLDERID_ComputerFolder); //получаем список элементов каталога
                listener = new ShellItemsHttpListener(items, prefix, port);
                listener.Start(); //запускаем HTTP-сервер
                webbrowser.Navigate("http://localhost:" + port.ToString() + "/" + prefix + "/"); //открываем страницу в WebBrowser
                webbrowser.Navigating += webbrowser_Navigating;
            }
    
            void webbrowser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
            {
                //обработка перенаправлений URL с http:// на file://
                Uri uri = listener.ProcessRedirect(e.Uri.AbsoluteUri);
                if (uri != null) { webbrowser.Navigate(uri); e.Cancel = true; }            
            }
    
            private void bHome_Click(object sender, RoutedEventArgs e)
            {            
                webbrowser.Navigate("http://localhost:" + port.ToString() + "/" + prefix + "/");    
            }
    
            public static List<ShellItem> GetItems(Guid FolderID) //Получает список элементов каталога по GUID
            {            
                IntPtr p = IntPtr.Zero;
                IShellFolder pFolder = null;
                IEnumIDList pEnum = null;
                IntPtr pItem = IntPtr.Zero;                      
                IntPtr lpStr = IntPtr.Zero;
                STRRET strret;
                Guid guid = typeof(IShellFolder).GUID;
                List<ShellItem> items = new List<ShellItem>();
                ShellItem si;          
    
                try
                {
                    int hr = SHGetKnownFolderIDList(ref FolderID, 0, IntPtr.Zero, out p);
                    if (hr != 0) throw Marshal.GetExceptionForHR(hr);
    
                    hr = SHBindToObject(null, p, null, ref guid, out pFolder);
                    if (hr != 0) throw Marshal.GetExceptionForHR(hr);
                                    
                    pFolder.EnumObjects(IntPtr.Zero, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, out pEnum); 
    
                    while (true)
                    {
                        pItem = IntPtr.Zero; 
                        uint res = pEnum.Next(1, out pItem, IntPtr.Zero);
                        if (res != 0) break;
                        si = new ShellItem();
    
                        //display name
                        lpStr = IntPtr.Zero;
                        strret = new STRRET();
                        pFolder.GetDisplayNameOf(pItem, SHGDN_NORMAL, out strret); 
                        hr = StrRetToStr(ref strret, pItem, out lpStr);
                        if (hr != 0) throw Marshal.GetExceptionForHR(hr);
                        string s = Marshal.PtrToStringUni(lpStr);
                        si.DisplayName = s;
                        CoTaskMemFree(lpStr);
    
                        //path
                        lpStr = IntPtr.Zero;
                        strret = new STRRET();
                        pFolder.GetDisplayNameOf(pItem, SHGDN_FORPARSING, out strret);
                        hr = StrRetToStr(ref strret, pItem, out lpStr);
                        if (hr != 0) throw Marshal.GetExceptionForHR(hr);
                        s = Marshal.PtrToStringUni(lpStr);
                        try { si.Path = new Uri(s); }
                        catch (UriFormatException) { si.Path = new Uri("file://localhost/"); }
                        CoTaskMemFree(lpStr);
    
                        //icon
                        Guid iid_IIExtractIcon = typeof(IExtractIcon).GUID;
                        IExtractIcon pExtract;
                        pFolder.GetUIObjectOf(IntPtr.Zero, 1, new IntPtr[] { pItem }, ref iid_IIExtractIcon, 0, out pExtract);
                        
                        StringBuilder sbIcon = new StringBuilder(260);
                        int index=0;
                        uint flags; 
                        hr = pExtract.GetIconLocation(GIL_FORSHELL, sbIcon, 260, out index, out flags);
                        if (hr == 0)
                        {
                            IntPtr hIconSmall = IntPtr.Zero, hIconLarge = IntPtr.Zero;
                            hr = pExtract.Extract(sbIcon.ToString(), (uint)index, out hIconLarge, out hIconSmall, 0x00140014);
                            if (hr == 0 && hIconSmall != IntPtr.Zero)
                            {
                                var icon = System.Drawing.Icon.FromHandle(hIconSmall);
                                var bitmap = icon.ToBitmap();
    
                                using (bitmap)
                                {
                                    MemoryStream ms = new MemoryStream();
                                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                                    si.Image = ms.ToArray();
                                }
    
                                DestroyIcon(hIconSmall);
                                DestroyIcon(hIconLarge);
                            }
                            else { si.Image = new byte[0]; }                       
                        }
                        else
                        {
                            si.Image = new byte[0];
                        }
                        items.Add(si);
                        CoTaskMemFree(pItem);
                    }
    
                    return items;
                }
                finally
                {
                    if (p != IntPtr.Zero) CoTaskMemFree(p);
                    if (pFolder != null) Marshal.ReleaseComObject(pFolder);
                    if (pEnum != null) Marshal.ReleaseComObject(pEnum);
                }
    
            }                     
    
            public const uint SHGFI_DISPLAYNAME = 0x000000200;
            public const uint SHGFI_ICON = 0x000000100;
            public const uint SHGFI_PIDL = 0x000000008;
            public const uint GIL_FORSHELL = 0x0002;
            public const int SHGDN_NORMAL = 0x0000;
            public const int SHGDN_FORPARSING = 0x8000;
            public const int SHCONTF_FOLDERS = 0x0020;
            public const int SHCONTF_NONFOLDERS = 0x0040;                
    
            [DllImport("shell32.dll")]
            public static extern int SHGetKnownFolderIDList(ref Guid rfid, int dwFlags, IntPtr hToken, out IntPtr ppidl);
            
            [DllImport("ole32.dll")]
            static extern void CoTaskMemFree(IntPtr pv);
            
            [DllImport("shell32.dll")]        
            static extern int SHBindToObject(
                IShellFolder psf,
                IntPtr pidl,
                [MarshalAs(UnmanagedType.IUnknown)] object pbc,
                ref Guid riid,
                out IShellFolder ppv);
    
            [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
            static extern int StrRetToStr( ref STRRET pstr,  IntPtr pidl, out IntPtr ppsz);
            
            [DllImport("user32.dll")]
            static extern bool DestroyIcon(IntPtr hIcon);
        }
    
        public struct ShellItem
        {
            public string DisplayName { get; set; }
            public Uri Path { get; set; }
            public byte[] Image { get; set; }
        }
    
        public class ShellItemsHttpListener //возвращает содержимое каталога в виде веб-страницы
        {
            Dictionary<string, byte[]> images; //таблица изображений
            Dictionary<string, Uri> redirects; //таблица редиректов
            string html;
            string urlprefix;
            int httpport;
            HttpListener listener;        
    
            public ShellItemsHttpListener(List<ShellItem> items, string prefix, int port)
            {
                StringBuilder sb = new StringBuilder();
                int n = 1;
    
                //генерируем веб-страницу...
                //устанавливаем режим IE8, чтобы работали стили
                sb.Append("<html><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\" /><style>");
    
                //устанавливаем стили, имитирующий внешний вид проводника (в режиме просмотра "Список")
                sb.Append("a { color: black; text-decoration: none;  } a:hover { color: black; text-decoration: underline;} ");
                sb.Append("tr:hover { background-color: lightblue;} img {border:none;}");
                sb.Append("</style></head><body>");
    
                //формируем список элементов
                sb.Append("<table cellspacing=\"0\" border=\"0\">");
                images = new Dictionary<string, byte[]>();
                redirects = new Dictionary<string, Uri>();
                
                foreach (ShellItem item in items)
                {                
                    sb.Append("<tr><td><a href=\"" + n.ToString() + ".html\" >");
                    sb.Append("<img width=\"20\" height=\"20\" src=\"" + n.ToString() + ".png\"/></a></td>");  
                    sb.Append("<td><a href=\"" + n.ToString() + ".html\" >");
                    sb.Append(item.DisplayName + "</a></td></tr>");
                    images[n.ToString() + ".png"] = item.Image;
                    redirects[n.ToString() + ".html"] = item.Path;
                    n++;
                }
                sb.Append("</table></body></html>");
                html = sb.ToString();
    
                //инициализация HttpListener...
                listener = new HttpListener();            
                listener.Prefixes.Add("http://localhost:"+port.ToString()+"/" + prefix+"/");
                urlprefix = prefix;
                httpport = port;
            }
    
            public void Start() //запускает HTTP-сервер     
            {           
                Task.Run(() =>
                {
                    try
                    {
                        listener.Start();
                        while (true)
                        {                        
                            HttpListenerContext context = listener.GetContext(); //ожидаем запроса
                            HttpListenerRequest request = context.Request;
                            HttpListenerResponse response = context.Response;
    
                            //анализ URL...
                            byte[] buffer = new byte[0];
                            string urlbegin = "/" + urlprefix + "/";
                            string urlfile = request.RawUrl.Substring(urlbegin.Length);
                            if (urlfile == "" || urlfile.StartsWith("index") || urlfile.StartsWith("default"))
                            {
                                //отдаем основную страницу
                                buffer = System.Text.Encoding.UTF8.GetBytes(html);
                                response.ContentLength64 = buffer.Length;
                                response.ContentEncoding = Encoding.UTF8;
                            }
                            else if (urlfile.EndsWith(".png"))
                            {
                                //отдаем изображение
                                buffer = images[urlfile];
                                response.ContentLength64 = buffer.Length;
                                response.ContentType = "image/png";
                            }
                            else
                            {
                                buffer = System.Text.Encoding.UTF8.GetBytes("Ошибка: Страница не найдена");
                                response.StatusCode = 404;
                                response.ContentType = "text/plain";
                            }
    
                            //возвращаем ответ
                            System.IO.Stream output = response.OutputStream;
                            output.Write(buffer, 0, buffer.Length);
                            output.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "HttpListener error");
                    }
                });
            }
    
            public Uri ProcessRedirect(string inputurl)
            {
                //обработка перенаправлений...            
                string urlbegin = "http://localhost:" + httpport.ToString() + "/" + urlprefix + "/";
    
                if (inputurl.StartsWith(urlbegin))
                {
                    string urlfile = inputurl.Substring(urlbegin.Length);
                    if (!urlfile.EndsWith(".html")) return null;
    
                    if (redirects.ContainsKey(urlfile))
                    {
                        return redirects[urlfile];
                    }
                    else return null;
                }
                else return null;
            }
        }    
        
        /* COM Interfaces */
    
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214E6-0000-0000-C000-000000000046")]
        public interface IShellFolder
        {
            void ParseDisplayName(IntPtr hwnd, IntPtr pbc, String pszDisplayName, UInt32 pchEaten, out IntPtr ppidl, UInt32 pdwAttributes);
            void EnumObjects(IntPtr hwnd, int grfFlags, out IEnumIDList ppenumIDList);
            void BindToObject(IntPtr pidl, IntPtr pbc, [In]ref Guid riid, out IntPtr ppv);
            void BindToStorage(IntPtr pidl, IntPtr pbc, [In]ref Guid riid, out IntPtr ppv);
            [PreserveSig]  Int32 CompareIDs(Int32 lParam, IntPtr pidl1, IntPtr pidl2);
            void CreateViewObject(IntPtr hwndOwner, [In] ref Guid riid, out IntPtr ppv);
            void GetAttributesOf(UInt32 cidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]IntPtr[] apidl, ref uint rgfInOut);
            void GetUIObjectOf(IntPtr hwndOwner, UInt32 cidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]IntPtr[] apidl, 
                [In] ref Guid riid, UInt32 rgfReserved, out IExtractIcon ppv);
            void GetDisplayNameOf(IntPtr pidl, int uFlags, out STRRET pName);
            void SetNameOf(IntPtr hwnd, IntPtr pidl, String pszName, int uFlags, out IntPtr ppidlOut);
        }   
        
        [StructLayout(LayoutKind.Explicit, Size = 520)]
        public struct STRRETinternal
        {
            [FieldOffset(0)] public IntPtr pOleStr;
    
            [FieldOffset(0)] public IntPtr pStr;  
    
            [FieldOffset(0)] public uint uOffset;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct STRRET
        {
            public uint uType;
            public STRRETinternal data;
        }
    
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214F2-0000-0000-C000-000000000046")]
        public interface IEnumIDList
        {
            [PreserveSig()] uint Next(uint celt, out IntPtr rgelt, IntPtr pceltFetched);
            [PreserveSig()] uint Skip(uint celt);
            [PreserveSig()] uint Reset();
            [PreserveSig()] uint Clone(out IEnumIDList ppenum);
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }
    
        [ComImport()]
        [Guid("000214fa-0000-0000-c000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IExtractIcon
        {
            [PreserveSig] int GetIconLocation(
                uint uFlags,
                [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 2)] StringBuilder szIconFile,
                int cchMax,
                out int piIndex,
                out uint pwFlags);
    
    
            [PreserveSig] int Extract(
                [MarshalAs(UnmanagedType.LPWStr)] string pszFile, uint nIconIndex, out IntPtr phiconLarge,
                out IntPtr phiconSmall, uint nIconSize);
        }   
    }
    

    Источник: https://devblogs.microsoft.com/oldnewthing/?p=9773

    Это, конечно, не настоящий "Мой компьютер", но подделано довольно качественно:

    mycomputer

    Картину только портит багнутый "Мои веб-узлы MSN", который ведет в никуда и для которого не работает извлечение иконки. Извращения с обработкой webbrowser_Navigating здесь нужны из-за того, что настройки безопасности не позволяют просто так переходить с http://localhost/ на file://localhost/

    26 августа 2019 г. 12:14