Article C0001 C# .NET
Special Folders, old school and current generation solutions

Searching for a method of retrieving Special Folders we first discovered the old school solution. This solution uses the Marshall technology which uses unmanaged code. These code segment shows how this is done the old school way:
            
//
// Special Folder
//
// Example using mashalling, the old school way.
//
// Edward Willemsen
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
// required for dll mashalling
using System.Runtime.InteropServices;
namespace SpecialF_OS
{
    public partial class frmMain : Form
    {
        const int CSIDL_PROGRAMS = 0x0002;
        const int CSIDL_FONTS = 0x0014;
        const int CSIDL_DESKTOP = 0x0000;
        // Create entrypoint to shell32.dll:
        [DllImport("shell32.dll")]
        static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner,
            [Out] StringBuilder lpszPath,
            int nFolder, bool fCreate);
        public frmMain()
        {
            InitializeComponent();
        }
        // Quit application:
        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        // Get some special folders:
        private void btnGet_Click(object sender, EventArgs e)
        {
        StringBuilder sf_path = new StringBuilder(255);
            lbSF.Items.Clear();
            
            SHGetSpecialFolderPath(IntPtr.Zero, sf_path, CSIDL_DESKTOP, false);
            
            lbSF.Items.Add("My Desktop: " + sf_path);
            SHGetSpecialFolderPath(IntPtr.Zero, sf_path, CSIDL_PROGRAMS, false);
            
            lbSF.Items.Add("My Programs: "+sf_path);
            
            SHGetSpecialFolderPath(IntPtr.Zero, sf_path, CSIDL_FONTS, false);
            
            lbSF.Items.Add("Fonts: " + sf_path);
        }
    }
}

Download the complete project here.

But when getting more familiar with C# we discovered the current generation solution to fulfill this task:

//
// Special Folders
//
// The new generation solution.
//
// Edward Willemsen
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace SpecialF_CG
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }
        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void btnGet_Click(object sender, EventArgs e)
        {
            lbSF.Items.Add("My Desktop: " +
                Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
                   
            lbSF.Items.Add("My Programs: " +
                Environment.GetFolderPath(Environment.SpecialFolder.Programs));
                   
            lbSF.Items.Add("My Documents: " +
                Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
        }
    }
}
Download the complete project here. Which solution to use is not only a matter of flavor, but is also matter of required functionality. When the path to the Fonts folder is required the current generation solution doesn't provide this item, but the old school solution does. This might probably change within .NET 3.0.

Here is a table which can be used to access all available Special Folder paths using the marshalling solution can be found here.

~Edward