Click here to Skip to main content
13,833,501 members
Click here to Skip to main content
Add your own
alternative version


44 bookmarked
Posted 28 Feb 2006

Reading contents of Web Folders in C#

, 28 Feb 2006
Rate this:
Please Sign up or sign in to vote.
An analysis of the different ways of getting the list of files in a web folder (including SharePoint) programmatically, and a simple solution. The sample code is for C# 2.0.


Once I needed to make some automation processing of Microsoft Word documents located in a SharePoint Portal Server. But I faced an interesting problem – how to find all the documents in SharePoint programmatically?

Investigation – Flops and Boomers

Trial of the FileSearch interface

First, as long as I already used Word automation interfaces, I tried to use the file searching capabilities implemented in the Microsoft Office API, namely the FileSearch interface exposed by Office’s Application object. I assumed that whilst Microsoft Word is capable of opening documents directly from SharePoint, of course, it would be able to search through Word documents on the server…

Naïve assumption - of course not. Things are never so simple that you may relax and have the fun of the “famous” KISS principle. It was able to work properly only on local disk, or, at most, at a network file share.

Trial of the SharePoint Web Services

OK, I know that the SharePoint Server exposes its content in the form of web services. I tried that stuff too, but those entities that I had to work with seemed to me much more complicated than was required for such a simple task - a lot of lists and items of different types. Also, I was not sure about the compatibility between different versions of the SharePoint Server (like 2001, 2003, and the next 2006), and furthermore, I wanted a solution that might work with not only the SharePoint Portal Server, but with any Web Folder that you may browse in Windows Explorer (e.g., running under pure Windows Server 2003).

Trial of WebDAV and Web Extender Client (WEC) protocols

As you may know, it is possible to browse a web folder in Windows Explorer only if the IIS server supports either the FrontPage Web Extender Client (WEC) or the Web Distributed Authoring and Versioning (WebDAV) protocol extensions.

There are different ways of making WebDAV/WEC requests – through composing XML requests, or through writing a defined set of HTTP headers into the HTTP request. These would require deep scrutinizing of the standards.

I found out that MS Office products use the FPWEC.DLL COM library usually located at %PROGRAMFILES%\Common Files\Microsoft Shared\web server extensions\60\BIN. It contains a set of wrappers for these protocols, but I found no documentation on them, and their usage did not seem to be straightforward, mainly in the asynchronous manner.

Unfortunately, I didn’t find any free really-working C# library that would allow mw to easily use WebDAV.

One of the ways is to use the OLE DB Provider for Internet Publishing from old ADO. However, on MSDN, there is this statement that “the .NET Framework Data Provider for OLE DB does not support OLE DB version 2.5 interfaces. OLE DB Providers that require support for OLE DB 2.5 interfaces will not function properly with the .NET Framework Data Provider for OLE DB. This includes the Microsoft OLE DB Provider for Exchange and the Microsoft OLE DB Provider for Internet Publishing”. I didn’t like to use COM interop over ADO 2.5 interfaces from my C# code, and I skipped this solution. However, you may try it – it may be quite feasible in some cases.

The Alternative Solution – Web Folder Short Cuts

Suddenly, I remembered that sometimes when you try browsing a web folder, a shortcut to the web folder is added to the My Network Places folder available in the Windows Explorer.

As you may know, these shortcuts are physically placed into the c:\Documents and Settings\{USER NAME}\NetHood hidden folder. A web folder shortcut is a physical directory with a read-only file attribute (the directory name is equal to the name of the shortcut) that contains two specific files:

  • Desktop.ini (file attributes are Hidden, System) – a text file that contains the ProgID of a shell extension that will handle how to represent the content of the shortcut to the user.
  • target.lnk – a binary file that contains a URL to the web folder the shortcut represents.

So I tried to read the content of the web folder shortcut just as Windows Explorer is expected to do; I used the “Shell Objects for Scripting” (VBScript sample):

dim oShell
dim oFolder
dim sDir
Dim s

set oShell = CreateObject("Shell.Application")
set oFolder = oShell.NameSpace("c:\Documents and" & _ 
              " Settings\Administrator" & _ 

for i=0 to oFolder.Items.Count-1
    s = s + oFolder.Items.Item(i).Path+ _

MsgBox s

… and it has worked out. Inside, the appropriate shell extension (pre-installed with Windows) provides the necessary Folder and FolderItem objects, doing all the hard work of interacting with the web server through WebDAV/WEC for us – we will just utilize their results. Note, that passing a pure HTTP URL to the Shell.Application object won't work.

Recently, I came across a script code that allows creating web folder shortcuts (Code Ccomments) - many thanks to the author. I converted the code into C#:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace Utils
    public static class PathRoutines

        //'44 seems to be the length where we have 
        //to change a byte from 00 to a 01.
        private const int URL_CUTOFF = 44;

        //This is where we construct the target.lnk
        //file byte by byte. Most of the lines 
        //are shown in 16 byte chunks,
        //mostly because that is the way I saw it 
        //in the Debug utility I was using to inspect shortcut files.
        private static readonly byte[] LINK_CONTENT_PREFIX = new byte[]
        {//Line 1, 16 bytes
          0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 
          0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 
          0x00, 0x00, 0x00,
         //Line 2, 16 bytes
          0x00, 0x00, 0x00, 0x46, 0x81, 0x00, 0x00, 
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
          0x00, 0x00, 0x00, 
        //Line 3, 16 bytes
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
          0x00, 0x00, 0x00,
        //Line 4., 16 bytes. 13th byte is significant.
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
          0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
          0x00, 0x00, 0x00,
        //Line 5. 13th byte is significant.
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
          0x00, 0x00, 0x00, 0x00, 0x00,
        //When I was analyzing the next byte of shortcuts 
        //I created, I found that it is set to various values,
        //and I have no idea what they are referring to. 
        //In desperation I tried substituting some values.
        //00 caused a crash of Explorer. FF seeems to work fine for all.

        private static readonly byte[] LINK_CONTENT_MID = new byte[]
            0x14, 0x00,
            //Line 6, 16 bytes
            0x1F, 0x50, 0xE0, 0x4F, 0xD0, 0x20, 0xEA, 0x3A, 
            0x69, 0x10, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30,
            //Line 7, 16 bytes
            0x30, 0x9D, 0x14, 0x00, 0x2E, 0x00, 0x00, 0xDF, 
            0xEA, 0xBD, 0x65, 0xC2, 0xD0, 0x11, 0xBC, 0xED,
            //Line 8, 16 bytes
            0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x0F, 0xA4

        private static readonly 
                byte[] LINK_CONTENT_MID2 = new byte[]
            0x4C, 0x50, 0x00, 0x01, 0x42, 0x57, 0x00, 0x00,
            //Line 9, 16 bytes
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
            //Line 10, 2 bytes
            0x00, 0x00

        private static readonly 
                byte[] LINK_CONTENT_POSTFIX = new byte[]
            //Last line, 13 bytes
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00

        /// <span class="code-SummaryComment"><summary></span>
        /// Returns path to a directory with name 
        /// 'shortcutName' that is mapped
        /// to the specified web siteUrl.
        /// If the directory already exists - does nothing
        /// <span class="code-SummaryComment"></summary></span>
        /// <span class="code-SummaryComment"><param name="siteUrl">The target url</param></span>
        /// <span class="code-SummaryComment"><param name="shortcutContainerPath">Folder where</span>
        ///           the shortcut folder mapped to
        /// the specified web siteUrl will be created<span class="code-SummaryComment"></param></span>
        /// <span class="code-SummaryComment"><param name="shortcutName">Name of the </span>
        ///          shortcut folder<span class="code-SummaryComment"></param></span>
        public static string CreateWebFolderLink(string siteUrl, 
               string shortcutContainerPath, string shortcutName)
            if (siteUrl.Length > 255)
                throw new ArgumentOutOfRangeException("Length" + 
                      " of Url [" + siteUrl + "] is more" + 
                      " than 255 symbols");

            string localFolderPath = 
              Path.Combine(shortcutContainerPath, shortcutName);

            DirectoryInfo localDir = null;
            if (Directory.Exists(localFolderPath))
                return localFolderPath;

            localDir = Directory.CreateDirectory(localFolderPath);
            localDir.Attributes = FileAttributes.ReadOnly;

            string desktop_ini_filePath = 
              Path.Combine(localFolderPath, "Desktop.ini");
            StreamWriter writer = new 
              StreamWriter(desktop_ini_filePath, false);
            writer.WriteLine("CLSID2={0AFACED1" + 

            string lnk_filePath = 
              Path.Combine(localFolderPath, "target.lnk");
            FileStream fs = new FileStream(lnk_filePath, 
            BinaryWriter stream = new BinaryWriter(fs, 
            stream.Write(LINK_CONTENT_PREFIX, 0, 

            //'This byte is 00 if the URL is 44 characters 
            //or less, 01 if greater.
            if (siteUrl.Length > URL_CUTOFF)

            stream.Write(LINK_CONTENT_MID, 0, 

            //'This byte is 00 if the URL is 44 characters 
            //or less, 01 if greater.
            if (siteUrl.Length > URL_CUTOFF)

            stream.Write(LINK_CONTENT_MID2, 0, 

            //The next byte represents the length of the site name.

            char[] webFolderNameChars = 
            stream.Write(webFolderNameChars, 0, 

            //Middle line, separates the Folder Name 
            //from the URL. 3 bytes.

            //The next byte represents the length of the site URL.

            char[] sitePathChars = siteUrl.ToCharArray();
            stream.Write(sitePathChars, 0, sitePathChars.Length);

            stream.Write(LINK_CONTENT_POSTFIX, 0, 


            return localFolderPath;

By the way, you may use the CreateWebFolderLink method to create the necessary web folder shortcuts to be visible in the “My Network Places” folder; for that, just pass the “c:\Documents and Settings\{USER NAME}\NetHood” string as the shortcutContainerPath parameter.

So now, when one wants to get a list of files in a web folder, the algorithm will be as follows:

  • We create a temporary shortcut to the web folder.
  • We use Shell32 to read its contents.

Create a temporary shortcut to the web folder:

/// <span class="code-SummaryComment"><summary></span>
/// Returns path to a shortcut folder that is mapped
/// to the specified web siteUrl. Name of the folder is derived
/// automatically.
/// If the shortcut folder already exists - does nothing
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="siteUrl"></param></span>
/// <span class="code-SummaryComment"><param name="shortcutContainerPath"></param></span>
/// <span class="code-SummaryComment"><returns></returns></span>
public static string CreateWebFolderLink(Uri siteUrl)
    //derive shortcut name
    string sitePath = siteUrl.ToString();
    string shortcutName = 

    return CreateWebFolderLink(sitePath, 
           Path.GetTempPath(), shortcutName);

Use Shell32 to read contents:

In order that the following code is compiled, you need to add a COM reference to the Shell32 library (its caption is “Microsoft Shell Controls and Automation”) to your project.

/// <span class="code-SummaryComment"><summary></span>
/// Uses Shell32
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="siteUrl"></param></span>
/// <span class="code-SummaryComment"><param name="filePathPattern">For example,</span>
///        to make a wildcard search ".doc" use the following
/// reg expression: Regex regex = new Regex(@".*\.doc",
///         RegexOptions.Compiled | RegexOptions.IgnoreCase);
/// to exclude word template documents assigned
/// to a SharePoint workspace, use the following 
/// reg expression: new Regex(@"(?<span class="code-SummaryComment"><!.*/Forms/[^/]+)\.doc$", 

///          RegexOptions.Compiled | RegexOptions.IgnoreCase)</param></span>
/// <span class="code-SummaryComment"><param name="searchSubFolders"></param></span>
/// <span class="code-SummaryComment"><returns></returns></span>
public static StringCollection 
       SearchFilesInWebFolder(Uri siteUrl, 
       Regex filePathPattern, bool searchSubFolders)
    string mapFolderPath = CreateWebFolderLink(siteUrl);
    StringCollection ret = new StringCollection();

    Shell32.ShellClass shell = new Shell32.ShellClass();

    Shell32.Folder mapFolder = shell.NameSpace(mapFolderPath);
    SearchInFolder(mapFolder, filePathPattern, searchSubFolders, ret);

    return ret;

private static void SearchInFolder(Shell32.Folder folder, 
        Regex filePathPattern, bool searchSubFolders, 
        StringCollection resultList)
    foreach (Shell32.FolderItem item in folder.Items())
        if (item.IsLink)

        if (item.IsFolder && searchSubFolders)
            SearchInFolder((Shell32.Folder) item.GetFolder, 
                filePathPattern, searchSubFolders, resultList);

        if (filePathPattern.IsMatch(item.Path))


The suggested solution seems to be quite simple and feasible for Windows or console applications. However, for server applications, use it with caution – you may likely face some problems with security (I am a bit doubtful whether an “ASP.NET” user would be able to use the Shell32 COM Interop) and multithreading. For such circumstances, I think the best approach would still be to use Web Services or WebDAV/WEC protocols directly.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Roman Koreshkov
Web Developer
Russian Federation Russian Federation
Roman Koreshkov has been on Systems Architect position in many software development companies.
He is keen on object-relational mapping methodologies, business layers, business rules and requirements management and code-generation stuff.
His current engagement is architecturing a next-generation HR products with the highest level of flexibility and performance.
His current professional passion is the new AJAX technologies and approaches.

You may also be interested in...


Comments and Discussions

QuestionPlssssssssssssss help Pin
pallavijain12-Mar-13 6:00
memberpallavijain12-Mar-13 6:00 
QuestionWebshare folder. Pin
Manjunath_N1-Mar-13 2:05
memberManjunath_N1-Mar-13 2:05 
Question.lnk is not readable Pin
Manjunath_N15-Feb-13 4:45
memberManjunath_N15-Feb-13 4:45 
QuestionThe type or namespace name 'Shell32' could not be found (are you missing a using directive or an assembly reference?) Pin
akil chehade16-Oct-12 3:46
memberakil chehade16-Oct-12 3:46 
AnswerRe: The type or namespace name 'Shell32' could not be found (are you missing a using directive or an assembly reference?) Pin
Roman Koreshkov16-Oct-12 5:30
memberRoman Koreshkov16-Oct-12 5:30 
QuestionNice Article Pin
Prakash Varun 201031-May-12 23:10
memberPrakash Varun 201031-May-12 23:10 
AnswerBinary File Specification for LNK File Pin
CVisions21-Apr-11 10:22
memberCVisions21-Apr-11 10:22 
GeneralRe: Binary File Specification for LNK File Pin
Roman Koreshkov22-Apr-11 0:52
memberRoman Koreshkov22-Apr-11 0:52 
AnswerRe: Binary File Specification for LNK File Pin
CVisions25-Apr-11 6:27
memberCVisions25-Apr-11 6:27 
GeneralNot Work in Windows7 Pin
cwchiu9-Nov-09 22:10
membercwchiu9-Nov-09 22:10 
GeneralFix for japanese support Pin
KU28-Jul-09 0:05
memberKU28-Jul-09 0:05 
GeneralRe: Fix for japanese support Pin
Roman Koreshkov28-Jul-09 0:25
memberRoman Koreshkov28-Jul-09 0:25 
QuestionDoes it work in vista? Pin
austin ajit4-Feb-09 14:44
memberaustin ajit4-Feb-09 14:44 
AnswerRe: Does it work in vista? Pin
Roman Koreshkov4-Feb-09 21:42
memberRoman Koreshkov4-Feb-09 21:42 
GeneralMapping Sharepoint sites under My Network Places\Web Folders Pin
Kfir Haliva28-Jun-08 14:01
memberKfir Haliva28-Jun-08 14:01 
QuestionIs there another way? Pin
mike payne4-Apr-08 0:12
membermike payne4-Apr-08 0:12 
AnswerRe: Is there another way? Pin
Vivekv4-Apr-08 11:51
memberVivekv4-Apr-08 11:51 
Generalfile/folder attributes Pin
Vivekv31-Mar-08 9:42
memberVivekv31-Mar-08 9:42 
QuestionLogin Pin
miauwmiauwmiauw19-Dec-07 22:54
membermiauwmiauwmiauw19-Dec-07 22:54 
GeneralThreads in knots... Pin
therearefartoomanybens28-Nov-07 12:57
membertherearefartoomanybens28-Nov-07 12:57 
GeneralNot working Pin
arslanjatt21-Nov-07 23:24
memberarslanjatt21-Nov-07 23:24 
GeneralRe: Not working Pin
Roman Koreshkov22-Nov-07 0:24
memberRoman Koreshkov22-Nov-07 0:24 
GeneralRe: Not working Pin
arslanjatt22-Nov-07 2:09
memberarslanjatt22-Nov-07 2:09 
AnswerRe: Not working Pin
Roman Koreshkov22-Nov-07 2:48
memberRoman Koreshkov22-Nov-07 2:48 
GeneralRe: Not working Pin
arslanjatt22-Nov-07 3:26
memberarslanjatt22-Nov-07 3:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.190114.1 | Last Updated 1 Mar 2006
Article Copyright 2006 by Roman Koreshkov
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid