News   Articles   Sources   Code libraries    RSS

Language:

English   Russia  

Current filter:

All   C#   C++   C  



Log in:

Name
Pass

Register

Network Monitor

How to get a files list from a folder?


Language:C#
Category:System
Date: 2008-07-01
Author:Network Monitor
Attachment:Download

It is an excellent question. I recommend using system functions. It is a slightly difficult because you have to declare interfaces and Windows Shell structures, but result will be very powerful. There are a lot of functions and structures. I'll help you to declare and to use all needed objects.

If you need directories and files list only you could use Directory class with helop of File class. But if you need high quality icons, thumbnails and other system functions you have to use Windows system function. Let's talk about that.

Create a new project and place a ListView component on the form. We will load files list from the desktop and place their names in the ListView. First of all we have to describe two interfaces: IShellFolder and IEnumIDList. Create a new Interface file for IShellFolder. To do it, use the right click on the project name in the Solution Explorer window. Select the New Item from the Add menu. The Add New item dialog will be displayed:

Select the Interface item in the Templates list and type a new interface name (IShellFolder) in the name Name field.

Save the file as IShellFolder.cs. The file contets must be like the next code (copy the code from browser):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ShellExample
{
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214E6-0000-0000-C000-000000000046")]
    public interface IShellFolder
    {
        [PreserveSig]
        Int32 ParseDisplayName(
            IntPtr hwnd,
            IntPtr pbc,
            [MarshalAs(UnmanagedType.LPWStr)] 
            string pszDisplayName,
            ref uint pchEaten,
            out IntPtr ppidl,
            ref ShellAPI.SFGAO pdwAttributes);

        [PreserveSig]
        Int32 EnumObjects(
            IntPtr hwnd,
            ShellAPI.SHCONTF grfFlags,
            out IntPtr enumIDList);

        [PreserveSig]
        Int32 BindToObject(
            IntPtr pidl,
            IntPtr pbc,
            ref Guid riid,
            out IntPtr ppv);

        [PreserveSig]
        Int32 BindToStorage(
            IntPtr pidl,
            IntPtr pbc,
            ref Guid riid,
            out IntPtr ppv);

        [PreserveSig]
        Int32 CompareIDs(
            IntPtr lParam,
            IntPtr pidl1,
            IntPtr pidl2);

        [PreserveSig]
        Int32 CreateViewObject(
            IntPtr hwndOwner,
            Guid riid,
            out IntPtr ppv);

        [PreserveSig]
        Int32 GetAttributesOf(
            uint cidl,
            [MarshalAs(UnmanagedType.LPArray)]
            IntPtr[] apidl,
            ref ShellAPI.SFGAO rgfInOut);

        [PreserveSig]
        Int32 GetUIObjectOf(
            IntPtr hwndOwner,
            uint cidl,
            [MarshalAs(UnmanagedType.LPArray)]
            IntPtr[] apidl,
            ref Guid riid,
            IntPtr rgfReserved,
            out IntPtr ppv);

        [PreserveSig()]
        Int32 GetDisplayNameOf(
            IntPtr pidl,
            ShellAPI.SHGNO uFlags,
            IntPtr lpName);

        [PreserveSig]
        Int32 SetNameOf(
            IntPtr hwnd,
            IntPtr pidl,
            [MarshalAs(UnmanagedType.LPWStr)] 
            string pszName,
            ShellAPI.SHGNO uFlags,
            out IntPtr ppidlOut);
    }
}

Now create another one interface with a name IEnumIDList. Save the file as IEnumIDList.cs. The code for the interface (copy the code from browser to your file):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ShellExample
{
    [ComImportAttribute()]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F2-0000-0000-C000-000000000046")]
    public interface IEnumIDList
    {
        [PreserveSig()]
        Int32 Next(
            int celt,
            out IntPtr rgelt,
            out int pceltFetched);

        [PreserveSig()]
        Int32 Skip(
            int celt);

        [PreserveSig()]
        Int32 Reset();


        [PreserveSig()]
        Int32 Clone(
            out IEnumIDList ppenum);
    }
}

Now we have the interfaces but we still interest in functions to work with files. Lets create ShellAPI.cs file to describe the functions. To do it, use the right click on the project name in the Solution Explorer window. Select the New Item from the Add menu. The Add New item dialog will be displayed. Select the Class item in the Templates list and type a new class name (ShellAPI) in the name Name field.

Save new file as ShellAPI.cs. the contents of ShellAPI.pas must be (copy the code from browser):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ShellExample
{
    public class ShellAPI
    {
        public const int S_OK = 0;
        public const int S_FALSE = 1;
        public const int MAX_PATH = 260;

        public static int cbFileInfo = Marshal.SizeOf(typeof(SHFILEINFO));

        [Flags]
        public enum SHCONTF
        {
            FOLDERS = 0x0020,
            NONFOLDERS = 0x0040,
            INCLUDEHIDDEN = 0x0080,
            INIT_ON_FIRST_NEXT = 0x0100,
            NETPRINTERSRCH = 0x0200,
            SHAREABLE = 0x0400,
            STORAGE = 0x0800,
        }

        [Flags]
        public enum SHGNO
        {
            NORMAL = 0x0000,
            INFOLDER = 0x0001,
            FOREDITING = 0x1000,
            FORADDRESSBAR = 0x4000,
            FORPARSING = 0x8000
        }

        [Flags]
        public enum SHGFI : uint
        {
            ADDOVERLAYS = 0x20,
            ATTR_SPECIFIED = 0x20000,
            ATTRIBUTES = 0x800,
            DISPLAYNAME = 0x200,
            EXETYPE = 0x2000,
            ICON = 0x100,
            ICONLOCATION = 0x1000,
            LARGEICON = 0,
            LINKOVERLAY = 0x8000,
            OPENICON = 2,
            OVERLAYINDEX = 0x40,
            PIDL = 8,
            SELECTED = 0x10000,
            SHELLICONSIZE = 4,
            SMALLICON = 1,
            SYSICONINDEX = 0x4000,
            TYPENAME = 0x400,
            USEFILEATTRIBUTES = 0x10
        }

        [Flags]
        public enum SFGAO : uint
        {
            BROWSABLE = 0x8000000,
            CANCOPY = 1,
            CANDELETE = 0x20,
            CANLINK = 4,
            CANMONIKER = 0x400000,
            CANMOVE = 2,
            CANRENAME = 0x10,
            CAPABILITYMASK = 0x177,
            COMPRESSED = 0x4000000,
            CONTENTSMASK = 0x80000000,
            DISPLAYATTRMASK = 0xfc000,
            DROPTARGET = 0x100,
            ENCRYPTED = 0x2000,
            FILESYSANCESTOR = 0x10000000,
            FILESYSTEM = 0x40000000,
            FOLDER = 0x20000000,
            GHOSTED = 0x8000,
            HASPROPSHEET = 0x40,
            HASSTORAGE = 0x400000,
            HASSUBFOLDER = 0x80000000,
            HIDDEN = 0x80000,
            ISSLOW = 0x4000,
            LINK = 0x10000,
            NEWCONTENT = 0x200000,
            NONENUMERATED = 0x100000,
            READONLY = 0x40000,
            REMOVABLE = 0x2000000,
            SHARE = 0x20000,
            STORAGE = 8,
            STORAGEANCESTOR = 0x800000,
            STORAGECAPMASK = 0x70c50008,
            STREAM = 0x400000,
            VALIDATE = 0x1000000
        }

        [Flags]
        public enum FILE_ATTRIBUTE
        {
            READONLY = 0x00000001,
            HIDDEN = 0x00000002,
            SYSTEM = 0x00000004,
            DIRECTORY = 0x00000010,
            ARCHIVE = 0x00000020,
            DEVICE = 0x00000040,
            NORMAL = 0x00000080,
            TEMPORARY = 0x00000100,
            SPARSE_FILE = 0x00000200,
            REPARSE_POINT = 0x00000400,
            COMPRESSED = 0x00000800,
            OFFLINE = 0x00001000,
            NOT_CONTENT_INDEXED = 0x00002000,
            ENCRYPTED = 0x00004000
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public SFGAO dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }


        [DllImport("shell32.dll")]
        public static extern Int32 SHGetDesktopFolder(
              out IntPtr ppshf
        );

        [DllImport("shell32", EntryPoint = "SHGetFileInfo", 
         ExactSpelling = false, CharSet = CharSet.Auto, 
         SetLastError = true)]
        public static extern IntPtr SHGetFileInfo(
              string pszPath, 
              FILE_ATTRIBUTE dwFileAttributes, 
              ref SHFILEINFO sfi, 
              int cbFileInfo, 
              SHGFI uFlags);

        [DllImport("shell32", EntryPoint = "SHGetFileInfo", 
          ExactSpelling = false, CharSet = CharSet.Auto, 
          SetLastError = true)]
        public static extern IntPtr SHGetFileInfo( 
              IntPtr ppidl, 
              FILE_ATTRIBUTE dwFileAttributes, 
              ref SHFILEINFO sfi, 
              int cbFileInfo, 
              SHGFI uFlags);
    }
}

Now we have all we need to get files list. Comments will help you to understand the code.

// get desktop folder
IntPtr shellFolderPtr;
ShellAPI.SHGetDesktopFolder(out shellFolderPtr);


IShellFolder shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder));

// clear listView1 items
listView1.Items.Clear();


// we will enumerate files and folders
ShellAPI.SHCONTF fileFlag = ShellAPI.SHCONTF.NONFOLDERS | ShellAPI.SHCONTF.FOLDERS;


// does result equal S_OK
IntPtr fileEnumPtr = IntPtr.Zero;
if (shellFolder.EnumObjects(IntPtr.Zero, fileFlag, out fileEnumPtr) == ShellAPI.S_OK)
{
 IEnumIDList fileEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(
      fileEnumPtr, typeof(IEnumIDList));

 IntPtr gelt;
 int celtFetched;

 // enumerate founded objects
 while (fileEnum.Next(1, out gelt, out celtFetched) == ShellAPI.S_OK 
          && celtFetched == 1)
 {
  // get display name of object
  ShellAPI.SHFILEINFO info = new ShellAPI.SHFILEINFO();
  ShellAPI.SHGetFileInfo(gelt, 0, ref info, ShellAPI.cbFileInfo,
     ShellAPI.SHGFI.DISPLAYNAME | ShellAPI.SHGFI.TYPENAME);

  // add object to list
  listView1.Items.Add(info.szDisplayName);
  }
 }

Download Attachment


Comments:

Rob : Correction to: // get display name of object

I guess you forgot a ShellAPI.SHGFI.PID flag in your get display name of object example. It should read:

ShellAPI.SHGetFileInfo(gelt, 0, ref info, ShellAPI.cbFileInfo,
      ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.DISPLAYNAME | ShellAPI.SHGFI.TYPENAME);


Flenov : Thanks

Thanks for your correction. The Pidl is neaded to access the item


Send your comment

Your name:
Vote:
Title:
Comment:
Protection code:





Submit an article   Submit a file

Copyright © HackishCode.com 2008. All rights reserved
WEB Design and WEB Development by WEB consulting company ProfWebDev.com
www.hackishcode.com