Using FrontPage 2003 to Consolidate Images in a Common Folder

A few months ago I wrote a blog titled Using FrontPage 2003 to Bulk Rename Images Using VBA, in which I shared a VBA macro that renamed all of the images in a website to a common file-naming syntax. In that blog I explained my reasoning behind my use of the long-outdated FrontPage 2003, and that reason was that FrontPage's "Link Fix Up" feature replicates file renames across your entire website. This single feature can greatly reduce your development time for websites when you have a lot of renaming to do.

Recently I ran into another interesting situation where combining with FrontPage's VBA and "Link Fix Up" features saved me an incredible amount of time, so I thought that I would share that in today's blog.

Problem Description and Solution

I recently inherited a large website with thousands of images that were spread across dozens of folders throughout the website. Unfortunately, this website was created by several developers, so there were a large number of duplicate images scattered throughout the website.

It would have taken me several days to remove all of the duplicates and edit all of the HTML in the web pages, so this seemed like a task that was better suited for automation in FrontPage 2003.

VBA Bulk Image Moving Macro

The following VBA macro for FrontPage 2003 will locate every image in a website, and it will move all images to the website's root-level "images" folder if they are not already located in that folder:

Public Sub MoveImagesToImagesFolder()
    Dim objFolder As WebFolder
    Dim objWebFile As WebFile
    Dim intCount As Integer
    Dim strExt As String
    Dim strRootUrl As String
    Dim strImagesUrl As String
    Dim blnFound As Boolean
    
    ' Define the file extensions for image types.
    Const strValidExt = "jpg|jpeg|gif|bmp|png"
    ' Define the images folder name.
    Const strImagesFolder = "images"

    With Application
        ' Retrieve the URL of the website's root folder.
        strRootUrl = LCase(.ActiveWeb.RootFolder.Url)
        ' Define the root-level images folder URL.
        strImagesUrl = LCase(strRootUrl & "/" & strImagesFolder)
        
        ' Set the initial search status to not found.
        blnFound = False
        ' Loop through the root-level folders.
        For Each objFolder In .ActiveWeb.RootFolder.Folders
            ' Search for the images folder.
            If StrComp(objFolder.Url, strImagesUrl, vbTextCompare) = 0 Then
                ' Exit the loop if the images folder is found.
                blnFound = True
                Exit For
            End If
        Next
        
        ' Test if the images folder is missing...
        If blnFound = False Then
            ' ... and create it if necessary.
            .ActiveWeb.RootFolder.Folders.Add strImagesFolder
        End If
     
        ' Loop through the collection of images.
        For Each objWebFile In .ActiveWeb.AllFiles
            ' Retrieve the file extension.
            strExt = LCase(objWebFile.Extension)
            ' Test if the file extension is for an image type.
            If InStr(1, strValidExt, strExt, vbTextCompare) Then
                ' Test if the image is in the root-level images folder...
                If StrComp(objWebFile.Parent, strImagesUrl, vbTextCompare) <> 0 Then
                    ' ... and move the file if it is not.
                    objWebFile.Move strImagesUrl & "/" & objWebFile.Name, True, True
                End If
            End If
        Next
    End With

End Sub

In Closing...

This macro is pretty straight-forward, but there are a couple of parameters that I pass to the WebFile.Move() method which I would like to point out. The first parameter for the Move() is the destination URL, which should be obvious, but the second and third parameters should be explained:

  • The second parameter is set to True in order to update hyperlinks during the move process; this is the "Link Fix Up" feature.
  • The third parameter is set to True in order to overwrite duplicate files; this has the potential to be a destructive operation if you are not careful. In my situation that was acceptable, but you might want to double-check your content first.

Another thing to note is that you can easily update this macro to move other file types. For example, you could move all of the JavaScript files in your website to a common root-level "scripts" folder by changing the values of the strValidExt and strImagesFolder constants.

As always, have fun... ;-]


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Using FrontPage 2003 to Bulk Rename Images Using VBA

Despite the plethora of other tools and editors that I use to create websites, there are times when I simply have to dust off my copy of (gasp!) Microsoft FrontPage 2003. It may be a dinosaur, but there are some things that it does really well, and periodically I simply need to use it.

An often-mocked and yet critically essential feature that FrontPage 2003 provided was affectionately called "Link Fix Up," which was a feature that would replicate file renames across your entire website. In other words, if you had a file that was named "foo.html," you could rename it to "bar.html" and FrontPage 2003 would update every hyperlink in every file in your entire website which pointed to that file. Needless to say, this feature was often indispensable when I was working with extremely large websites.

Other applications may have similar features, but when you combine that feature with FrontPage 2003's built-in Visual Basic for Applications (VBA) functionality, you have a really powerful combination that can quickly seem indispensable.

With all of that being said, here's a scenario where using FrontPage 2003's "Link Fix Up" functionality with VBA really paid off, and I thought that it would make a great blog (in case anyone else runs into a similar issue and still has a copy of FrontPage 2003 lying around somewhere.)

Problem Description and Solution

I created a mixed-media website some years ago where I had thousands of images that were named like IMG5243.1024x768.png, IMG2745.1280x1024.png, IMG6354.800x600.png, etc. Some part of the file name obviously contained the image dimensions, which was useful at the time that I created the website, but that information was no longer necessary, and the filenames made the Obsessive Compulsive side of my behavior start to act up. (Too many characters.) With that in mind, I decided that I would rename all of those images back to simpler names like IMG5243.png, IMG2745.png, IMG6354.png, etc.

This is where FrontPage 2003's "Link Fix Up" functionality would come in handy; trying to crawl every webpage in my website to update the thousands of image links would have been incredibly painful, whereas FrontPage 2003 would take care of keeping the image links up-to-date for free, provided that I could come up with a way to automate the renaming process. (Enter VBA.)

Here is where I quickly ran into a problem - I hadn't standardized my file naming syntax. (Shame on me.) A lot of filenames had other parts or character strings that were going to cause problems, for example: IMG5243.1024x768_cropped.png, IMG2745.edited_1280x1024.png, IMG6354.new_800x600_small.png, etc. This meant that I was going to have to crawl through each filename character by character and look for image dimensions. This is not difficult through VBA, but it added a bit of complexity because I would have to locate any "x" character in a filename and then starting working my way to the right and left to see if it was surrounded by numbers. In other words, I would have to traverse every file name like "aaa_123x456_aaa.jpg" and "aaa.123x456.aaa.jpg" in order to remove "123x456," while leaving "aaa.wxy.jpg" untouched. Of course, there were also topics to be considered after I removed the numbers, like malformed image names like "aaa__aaa.jpg" and "aaa..aaa.jpg" that had unnecessary character duplications.

VBA Bulk File Renaming Macro

All that being said, here is the VBA macro that I created, which worked great; I was able to have this macro rename my thousands of images in a matter of seconds, and FrontPage 2003 made sure that every image URL in my HTML/ASP files were kept up-to-date.

Sub RemoveImageSizesFromFilenames()
  Dim intSectionCount As Integer
  Dim intXPosition As Integer
  Dim intCharPosition As Integer
  Dim intDictionaryCount As Integer
  Dim objWebFile As WebFile
  Dim strExt As String
  Dim strOldName As String
  Dim strNewName As String
  Dim strUrlStub As String
  Dim strSections() As String
  Dim strWidth As String
  Dim strHeight As String
  Dim objDictionary As Object
  Dim objItem As Object
  Dim varKeys As Variant
  Dim varItems As Variant
  
  ' Define the list of file extensions to process.
  Const strValidExt = "jpg|jpeg|gif|bmp|png"
  
  ' Create a dictionary object to hold the list of old/new filenames.
  Set objDictionary = CreateObject("Scripting.Dictionary")
  
  ' Verify that a website is open; exit if not.
  If Len(Application.ActiveWeb.Title) = 0 Then
    MsgBox "A website must be open." & vbCrLf & vbCrLf & "Aborting.", vbCritical
    Exit Sub
  End If
  
  ' Loop through the files colleciton for the website.
  For Each objWebFile In Application.ActiveWeb.AllFiles
    ' Retrieve the file extension for each file.
    strExt = LCase(objWebFile.Extension)
    ' Verify if the filename is part of the valid list.
    If InStr(strValidExt, strExt) Then
      ' Retrieve the current file name
      strOldName = LCase(Left(objWebFile.Name, Len(objWebFile.Name) - Len(strExt) - 1))
      ' Verify a multi-part filename.
      If InStr(strOldName, ".") Then
        ' Split the multi-part filename into sections.
        strSections = Split(strOldName, ".")
        ' Loop through the sections.
        For intSectionCount = 0 To UBound(strSections)
          ' Verify that each section actually has characters in it.
          If Len(strSections(intSectionCount)) > 1 Then
            ' Check for a lowercase X character.
            intXPosition = InStr(2, strSections(intSectionCount), "x")
            ' Make sure that the X character does not start or end the string.
            If intXPosition > 1 And intXPosition < Len(strSections(intSectionCount)) Then
              ' Make sure that the X character has numbers to the left and right of it.
              If IsNumeric(Mid(strSections(intSectionCount), intXPosition - 1, 1)) And IsNumeric(Mid(strSections(intSectionCount), intXPosition + 1, 1)) Then
                ' Initialize the width/height strings.
                strWidth = ""
                strHeight = ""
                ' Loop through the string to find the height.
                For intCharPosition = intXPosition + 1 To Len(strSections(intSectionCount))
                  If IsNumeric(Mid(strSections(intSectionCount), intCharPosition, 1)) Then
                    strHeight = strHeight & Mid(strSections(intSectionCount), intCharPosition, 1)
                  Else
                    Exit For
                  End If
                Next
                ' Loop through the string to find the width.
                For intCharPosition = intXPosition - 1 To 1 Step -1
                  If IsNumeric(Mid(strSections(intSectionCount), intCharPosition, 1)) Then
                    strWidth = Mid(strSections(intSectionCount), intCharPosition, 1) & strWidth
                  Else
                    Exit For
                  End If
                Next
                ' Remove the width/height string from the current filename section.
                strSections(intSectionCount) = Replace(strSections(intSectionCount), strWidth & "x" & strHeight, "")
              End If
            End If
          End If
        Next
        ' Reassemble the file sections.
        strNewName = Join(strSections, ".")
        If Right(strNewName, 1) = "." Then strNewName = Left(strNewName, Len(strNewName) - 1)
        ' Cleanup several unnecessary character sequences.
        If StrComp(strOldName, strNewName, vbTextCompare) <> 0 Then
          strOldName = strOldName & "." & strExt
          strNewName = strNewName & "." & strExt
          strNewName = Replace(strNewName, "_.", ".", 1, -1)
          strNewName = Replace(strNewName, "._", "_", 1, -1)
          strNewName = Replace(strNewName, "..", ".", 1, -1)
          strNewName = Replace(strNewName, "__", "_", 1, -1)
          strUrlStub = Left(objWebFile.Url, Len(objWebFile.Url) - Len(strOldName))
          ' Add the old/new file URLs to the dictionary.
          objDictionary.Add strUrlStub & strOldName, strUrlStub & strNewName
        End If
      End If
    End If
  Next
  
  varKeys = objDictionary.Keys
  varItems = objDictionary.Items
  
  ' Loop through the collection of URLs to rename.
  For intDictionaryCount = 0 To (objDictionary.Count - 1)
    ' Avoid collisions with existing URLs.
    If Application.ActiveWeb.LocateFile(varItems(intDictionaryCount)) Is Nothing Then
      ' Get current URL.
      Set objWebFile = Application.ActiveWeb.LocateFile(varKeys(intDictionaryCount))
      ' Rename the URL.
      objWebFile.Move varItems(intDictionaryCount), True, False
    End If
  Next
  
End Sub

In Closing...

There are a couple of additional details about this macro that you should consider:

First of all, this macro intentionally avoids overwriting the destination filename if it already exists. For example, if you have two files named IMG1234.100x100.jpg and IMG1234.200x200.jpg, simply removing the image size characters from each file name would result in a collision for the name IMG1234.jpg. What the macro currently does is to rename the first file, then it leaves any possible collisions unchanged. You could easily modify this script to prompt the user what to do, or you could configure it to rename each file with a syntax like IMG1234a.jpg / IMG1234b.jpg / IMG1234c.jpg, but I'll leave that up to you.

Second, I wrote this macro for a specific set of file types and filenames, but you could modify the macro for a variety of scenarios. For example, one developer that I knew liked to test his content on his production server by creating preview files with names like foo.preview.html and bar.preview.aspx. This allowed the production files to coexist on the same server with the preview files, although the production files would have the production-ready filenames like foo.html and bar.aspx. Once he was ready to push the preview files into production, he would simply rename the necessary files. This system worked for a small set of files, but it didn't scale very well, so the amount of labor on his part would increase as the website grew more complex. (Of course, he should have been using a development website for his preview testing, but that's another story.) In any event, this macro could easily be modified to remove the ".preview." string from every file name.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Manually Localizing FPSE 2002 for Windows Server 2008 and Windows Vista

The FrontPage Server Extensions from Ready-to-Run Software, Inc. (RTR), are available and supported only in the English language. But that being said, the localized language files for FPSE 2002 are available for download from Microsoft, and if you're willing to do a little work, you can configure the FPSE 2002 administration pages for your website to be displayed in sixteen different languages. (The specific list of languages is provided later in this blog.)

Please note that this information is being presented "as-is" and is not officially supported by Microsoft or RTR.

Downloading and Installing the Localized FPSE 2002 Files

Download the self-extracting MSGS.EXE page that contains the FPSE 2002 language files from the following URL:

Extract the FPSE 2002 files by double-clicking the MSGS.EXE file and specifying an output folder.

By default, the installation package will install all of the localized files to the FPSE 2002 parent folder that is located at:

%ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\50

If you run the installation package on your server and accept the default path, then all of the languages will be available on your server.

However, if you only want to have one or more specific languages available, you would need to specify an alternate output folder for the extraction process. Under the output folder that you specified, you will see three folders: admisapi, bin, and isapi. Each of these folders will contain several subfolders, each of which contains the files for each of the localized languages. Each language that you want to have available on your server will need to be copied to their corresponding folders under the FPSE 2002 parent folder at:

%ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\50

You may copy all of the localized files to your FPSE directories, or you can select a single language by locating just the appropriate localized subfolders. For example, if you extracted the FPSE 2002 files to your C:\Temp folder and you wanted just the German language files, you would need to select the following folders:

C:\Temp\admisapi\1031

C:\Temp\bin\1031

C:\Temp\isapi\_vti_adm\help\1031

And you would copy those folders to the following paths:

%ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\50\admisapi\1031

%ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\50\bin\1031

%ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\50\isapi\_vti_adm\help\1031

Specifying the Language for an FPSE 2002 Website

Open the service.cnf file for one of your websites in Windows Notepad; this file will be kept in the _vti_pvt folder for a website. For example, for the Default Web Site this file would be at:

C:\Inetpub\wwwroot\_vti_vt\service.cnf

Choose the language abbreviation for your desired language from the list below. For example, if you were using German your abbreviation would be "de-de."

Language Description LCID Abbreviation
Arabic - Saudi Arabia 1025 ar-sa
Chinese - Taiwan 1028 zh-tw
German - Germany 1031 de-de
English - United States 1033 en-us
French - France 1036 fr-fr
Hebrew 1037 he
Italian - Italy 1040 it-it
Japanese 1041 ja
Korean 1042 ko
Dutch - Netherlands 1043 nl-nl
Portuguese - Brazil 1046 pt-br
Swedish - Sweden 1053 sv-se
Thai 1054 th
Chinese - China 2052 zh-cn
Chinese - Hong Kong SAR 3076 zh-hk
Spanish – Spain (Modern) 3082 es-es
See http://msdn.microsoft.com/en-us/library/0h88fahh.aspx for additional information about these languages and their related codes.

In the service.cnf file, locate the vti_defaultlanguage entry and change the value to the abbreviation for your desired language. If this value does not exist, you will need to add it. For example, if you were using the German language the syntax would be:

vti_defaultlanguage:SR|de-de

When you open the FPSE 2002 administration pages for your website, you should now see it in your localized language. (Note: You may need to refresh your browser's cache to see it correctly.)

That's all that there is to it. Once again, please note that the version of the FPSE 2002 from RTR is only supported in English; so if you are having any issues, you will need to change the value of the vti_defaultlanguage entry back to "en-us" before you contact RTR for support.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Life after FPSE (Part 6)

In this latest installment on my series about configuring your server for hosting without the FrontPage Server Extensions (FPSE), I'd like to discuss a couple of WebDAV best practices that I like to use.

Blocking FPSE-related Folders with Request Filtering

In my How to Migrate FPSE Sites to WebDAV walkthough, I discuss the following FPSE-related folders:

Folder Notes
_fpclass Should contain publicly-available FrontPage code - but should be secured.
_private The FrontPage Server Extensions often keep sensitive data files in this folder, so it should be secured to prevent browsing.
_vti_bin This is the virtual directory for the FrontPage Server Extensions executables. This path is configured to allow executables to function, and since we are migrating sites to WebDAV it should be secured to prevent browsing.
_vti_cnf The FrontPage Server Extensions keep sensitive metadata files in this folder, so it should be deleted or secured to prevent browsing.
_vti_log The FrontPage Server Extensions keep author logs in this folder, so it should be deleted or secured to prevent browsing.
_vti_pvt This folder holds several files that contain various metadata for your website, and should be secured.
_vti_txt This folder contains the text indices and catalogs for the older FrontPage WAIS search. Since later versions of FrontPage only used Index Server, it is safe to delete this folder, but at the very least it should be secured to prevent browsing.
fpdb FrontPage keeps databases in this folder, so it should be secured to prevent browsing.

One of the actions that I usually take on my servers is to lock down all of these folders for my entire server using Request Filtering. To do so, open a command prompt and enter the following commands:

cd %WinDir%\System32\inetsrv

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_vti_cnf']" /commit:apphost

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_fpclass']" /commit:apphost

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_private']" /commit:apphost

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_vti_log']" /commit:apphost

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_vti_pvt']" /commit:apphost

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_vti_txt']" /commit:apphost

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='fpdb']" /commit:apphost

Note: You should only enter the following commands if you are sure that you will not be using FPSE anywhere on your server!

cd %WinDir%\System32\inetsrv

appcmd.exe set config -section:system.webServer/security/requestFiltering /+"hiddenSegments.[segment='_vti_bin']" /commit:apphost

These settings will prevent any of the FPSE-related paths from being viewed over HTTP from a web browser; web clients will receive an HTTP Error 404.8 - Not Found message when they attempt to access those paths. But that being said - when you enable WebDAV for a website by using the Internet Information Services (IIS) Manager, it will configure the Request Filtering settings that enable WebDAV clients to access those paths through WebDAV requests, even though access from a web browser is still blocked. (All of this is made possible through the built-in integration between WebDAV and Request Filtering. ;-]) Enabling access to these folders over WebDAV is necessary if you are opening your website over a WebDAV-mapped drive while you are using authoring clients that do not have native WebDAV support, such as FrontPage or Visual Studio.

Two Sites are Better Than One

In part 4 of this blog series I discussed why I like to set up two websites when using WebDAV; as a quick review, here is the general idea for that environment:

  • The first website (e.g. www.example.com) is used for normal HTTP web browsing
  • The second website (e.g. authoring.example.com) is used for for WebDAV authoring

There is a list of several reasons in that blog post why using two sites that point to the same content can be beneficial, and I won't bother quoting that list in this blog post - you can view that information by looking at that post.

But that being said, one of the items that I mentioned in that list was using separate application pools for each website. For example:

  • The first application pool (e.g. www.example.com) is configured to use delegated configuration
  • The second application pool (e.g. authoring.example.com) is configured to ignore delegated configuration

This configuration helps alleviate problems from uploading invalid Web.config files that might otherwise prevent HTTP access to your website. By way of explanation, the WebDAV module attempts to validate Web.config files when they are uploaded over WebDAV - this is done to try and prevent crashing your HTTP functionality for a website and being unable to fix it. Here's what I mean by that: IIS 7 allows configuration settings to be delegated to Web.config files, but if there is a mistake in a Web.config file, IIS 7 will return an HTTP Error 500.19 - Internal Server Error message for all HTTP requests. Since WebDAV is HTTP-based, that means that you won't be able to fix the problem over WebDAV. (If the WebDAV module didn't perform any validation, that means that your website would become unusable and unrepairable if you had uploaded the bad Web.config file over WebDAV.) To help alleviate this, the WebDAV module performs a simple validation check to prevent uploading invalid Web.config files. But if you save an invalid Web.config file through some other means, like the local file system or over FTP, then you will have no way to repair the situation through WebDAV.

This leads us back to the idea that you can implement when you are using two websites - you can configure the application pool for the WebDAV-enabled website to ignore delegated configuration settings; so it doesn't matter if you have an invalid Web.config file - you will always be able to fix the problem over WebDAV. To configure an application pool to ignore delegated configuration settings, open a command prompt and enter the following commands:

cd %WinDir%\System32\inetsrv

appcmd.exe set config -section:system.applicationHost/applicationPools /[name='authoring.example.com'].enableConfigurationOverride:"False" /commit:apphost

Note: you need to update the highlighted section of that example with the name of your website, such as "Default Web Site," etc.

When you have two websites configured in this example and you have an invalid Web.config file that is causing the HTTP 500 error for the www.example.com website, you can still connect to authoring.example.com via WebDAV and fix the problem.

More Information

For additional information on the concepts that were discussing in this blog, see the following topics:

  • Life after FPSE (Part 4) - This blog post discusses a couple of WebDAV-related topics, and includes my list of additional reasons why configuring two websites when you are using WebDAV can be advantageous.
  • Adding Application Pools - This topic contains the detailed information about the enableConfigurationOverride setting for an application pool.
  • Using the WebDAV Redirector - This walkthrough discusses mapping drives to WebDAV-enabled websites.

I hope this helps. ;-]


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FrontPage Server Extensions and UNC Content

How to get the FPSE2002 AllowUNC feature to work with Windows Server 2008

I've had a few questions about getting the FrontPage 2002 Server Extensions (FPSE2002) AllowUNC feature to work with Windows Server 2008, so I thought that I would put together a blog from some of the information that I had been giving out whenever someone was having problems.

As a little bit of background information, Windows 2003 Server shipped with a later version of FPSE2002 than had previously been released, and that version of FPSE2002 was used as the code base for the version of FPSE2002 that was later shipped for Windows Server 2008. One the great features of this release was the ability to host your content on a remote server using a UNC share, which is something that web administrators had been requesting for years. Microsoft wrote a full whitepaper that details all of the possible configurations and steps to configure FPSE2002 with this feature at the following URL:

http://technet.microsoft.com/en-us/library/cc768023.aspx

That being said, that whitepaper is quite large, and not all of it is necessary if you simply want to host FPSE2002-based content on a UNC path. With that in mind, I have come up with an abbreviated set of steps that uses the whitepaper as a base for enabling this feature. To be more specific, I was able to implement this feature by using only the following sections of that whitepaper:

  1. "Configuring the File Server"
  2. "To Share the Folder"
  3. "Creating and Configuring a Virtual Server in IIS"
  4. "Configuring Security Settings for the Virtual Server"
  5. "To Configure the Registry for the Web server"
  6. "To Enable FrontPage Server Extensions 2002"

The body of this blog post is an excerpt from the whitepaper, and contains only the steps that I used to get my test scenario up and running. For my test, I set up a domain controller, a file server, and a web server; all running Windows Server 2008 or Windows Server 2003. I include notes when necessary to highlight issues that I ran into.

Additional Notes:

  • I cannot stress enough that setting up this configuration is not an easy task to perform, if you skip any steps that I have listed - the functionality will not work.
  • Some of the AllowUNC functionality is not implemented through the UI; you have to make changes to your registry to enable it.
  • All servers must be Windows 2008 Servers or Windows 2003 Servers in an Active Directory domain.
  • In the "To Share the Folder" steps I added the domain-level IUSR account to the permissions on the shared folder so that anonymous would work.
  • In the "Configuring Security Settings for the Virtual Server" steps I used Basic Authentication as this is the most common Internet-based method.
  • I only tested this with a UNC share on a Windows-based server, I did not test with SAN or NAS devices so I am not sure if they would work.

CONFIGURING THE FILE SERVER

You must configure a shared folder on the file server and grant the Web server access to the contents of that folder. Note that you must set the permissions for the folder itself, not a parent folder. It is recommended that you also implement IP Security on the file server, so that only the Web server, the domain controller, and other administrator computers can access the file server over TCP/IP. For more information about configuring IP Security, see Setting Up IPsec Domain and Server Isolation in a Test Lab.

To create a folder and set the folder ACLs
  1. In My Computer, create or locate the folder that will contain the Web site content.
  2. Right-click the folder, and click Properties.
  3. In the Properties dialog box, click the Security tab.
  4. Click Advanced. If you are using Windows Server 2008, click Edit.
  5. Click Add.
  6. Type Administrators, and then click OK.
  7. Select Full Control, and then click OK.
  8. Click Add.
  9. Click Object Types, and then in the Object Types box, select the Computers check box, and then click OK.
  10. In the Enter the object names to select box, type the Web server computer name, followed by a dollar sign ($) and then click OK.
  11. Select Full Control, and then click OK.
  12. Clear the check box for allowing inheritable permissions to propagate to the folder.
    • On Windows Server 2008 this check box is labeled "Include inheritable permissions from this object's parent".
    • On Windows Server 2003 this check box is labeled "Allow inheritable permissions from the parent object to propagate to this object and all child objects".
  13. Click Remove to clear the inherited permissions for the folder.
  14. Click OK, and then click OK again to close the Properties dialog box.
  15. The folder now only allows file access to the Administrators group and the Web server computer you specified. When you extend the virtual server on the Web server computer, the access control list (ACL) will be automatically updated with any additional required users or security principals.
To share the folder
  • On Windows Server 2008:
    1. Right-click the folder, and click Properties.
    2. On the Sharing tab, click Advanced Sharing.
    3. Check the Share this folder check box.
    4. In the Share name box, type the name to use for the share. Be sure to use the format sharename$ for the share name to make the folder hidden when users browse the machine.
    5. Click Permissions.
    6. Select Everyone, and then click Full Control.
    7. Click OK, and then click OK again, and then click Close to close the Properties dialog box.
  • On Windows Server 2003:
    1. Right-click the folder, and click Properties.
    2. On the Sharing tab, select Share this folder.
    3. In the Share name box, type the name to use for the share. Be sure to use the format sharename$ for the share name to make the folder hidden when users browse the machine.
    4. Click Permissions.
    5. Select Everyone, and then click Full Control.
    6. Click OK, and then click OK again to close the Properties dialog box.
About File System Security

Giving Everyone full control to your server share is necessary so that all users of your Web site can view the Web site information and run the ASP pages required to use FrontPage 2002 Server Extensions. However, you do not want to allow other computers or other servers access to the file share and those ASP pages. It is recommended that you implement Internet Protocol (IP) Security to help prevent users and computers from circumventing the FrontPage 2002 Server Extensions and Internet Information Services security for the file share and ASP pages.

Note - The separate user management feature for FrontPage 2002 Server Extensions also helps secure the process for accessing ASP pages through the file system. It is recommended that you implement this feature if you are connecting Web sites to UNC shares. For more information about managing users separately, see Authenticating Users Separately For Each Virtual Server.


CREATING AND CONFIGURING A VIRTUAL SERVER IN IIS

You use Internet Information Services (IIS) to create your new virtual server. You must also decide how to configure the security settings for your virtual server.

To create a virtual server on Windows Server 2008
  1. Click Start, point to Administration Tools, and then click Internet Information Services (IIS) Manager.
  2. Click the plus sign (+) next to the server name in the Connections pane that you want to add the virtual server to.
  3. Right-click Sites, and then click Add Web Site.
  4. In the Site name box, enter the name of the Web site.
  5. In the Physical path box, type the path to the network share where the site content will go. Note that if you used the format name$ for the share, you cannot browse to the share. You must type the path exactly.
  6. In the Type box, choose HTTP or HTTPS.
  7. In the IP address box, select the IP address you want to use.
  8. In the Port box, type the port number to assign to the virtual server.
  9. In the Host name box, type the host name that you want to use (if any).
  10. Click OK.
  11. Highlight the Web site you just created in the Connection pane.
  12. Double-click the Authentication feature in the Web site's Home pane.
  13. Highlight Anonymous Authentication in the Authentication pane.
  14. Click Edit... in the Actions pane.
  15. Click Specific user, and then click Set.
    • Enter the domain and user name of your domain-level IUSR account in the User name box.
    • Enter the password of your domain-level IUSR account in the Password and Confirm Password boxes.
    • Click OK.
  16. Click OK.
  17. Verify that the application pool for the new Web site is running as Network Service:
    1. Highlight the web site that you just created in the Connections pane.
    2. Click Basic Settings... in the Actions pane.
    3. Make a note of the application pool name, and then click OK.
    4. Click Application Pools in the Connections pane.
    5. Highlight the application pool from the step that you completed previously.
    6. Click Advanced Settings... in the Actions pane.
    7. Verify that IIS lists NetworkServicein the Identity field. If it does not, use the following steps:
      1. Click the ellipsis (...) to the right of the Identity field.
      2. Click Built-in account, and then select NetworkService from the drop-down menu.
      3. Click OK to close the Application Pool Identity dialog box.
    8. Click OK to close the Advanced Settings dialog box.
To create a virtual server on Windows Server 2003
  1. Click Start, point to Administration Tools, and then click Internet Information Services (IIS) Manager.
  2. Click the plus sign (+) next to the server name that you want to add the virtual server to.
  3. Right-click Web Sites, click New, and then click Web site.
  4. Click Next.
  5. In the Description box, type the description of your virtual server, and then click Next.
  6. In the Enter the IP address to use for this Web site box, select the IP address you want to use.
  7. In the TCP port this web site should use (Default: 80) box, type the port number to assign to the virtual server.
  8. In the Host Header for this site (Default: None) box, type the host name that you want to use (if any), and then click Next.
  9. In the Path box, type the path to the network share where the site content will go. Note that if you used the format name$ for the share, you cannot browse to the share. You must type the path exactly.
  10. If you do not want to allow anonymous access to your virtual server, clear the Allow anonymous access to this Web site check box.
  11. Click Next.
  12. On the Web Site Security Credentials panel, verify that the Always use the authenticated users credentials when validating access to the network directory check box is selected, and then click Next.
  13. On the Permissions panel, select the permissions to use, and then click Next. If your virtual server allows scripts to be run, you must also select the Run scripts (such as ASP) check box. If you want to allow ISAPI applications or CGI scripts to be used on your virtual server, you must also select the Execute (such as ISAPI applications or CGI) check box.
  14. Click Next, and then click Finish.

Note - If you chose to allow anonymous access for the virtual server, you must specify the domain account to use for anonymous users. When you use a local folder, you can use the default anonymous user (usually IUSR or IUSR_Machinename). To connect to a shared resource on a domain, however, you must specify an account with rights to the domain. Be sure to use an account with limited rights to the computers and resources in your domain. Do not unintentionally give anonymous users the ability to administer your server or print to your network printers.

Note from me:

As stated by me earlier, this entire article does not appear to work unless you specify a domain-level IUSR account in IIS, even if you are going to not allow anonymous access. In my testing, it seems to fail when anonymous is disabled and the anonymous user had been local, whereas it succeeded when the anonymous user is a domain-account with rights to the share, even though anonymous is disabled for the site.


CONFIGURING SECURITY SETTINGS FOR THE VIRTUAL SERVER

After you have created the virtual server, you must configure the security settings. When a Web site user requests a file that actually resides on a network share, there are two methods that FrontPage Server Extensions can use to provide the required authentication information:

  • Basic Authentication - Forwards the Web site requestor's username and password to the file server. If the user doesn't have access to the file server, he or she will not have access to the UNC-based files on the Web site. This method is best used for intranet Web sites.
  • Another authentication method used with Kerberos delegation If you want to use another authentication method, it is more secure to use it in conjunction with Kerberos delegation. For more information about configuring Kerberos, see the Help systems for Windows Server 2003 and Internet Information Services (IIS) 6.0.

Warning - Basic authentication forwards the requestor's username and password over the network. This means that usernames and passwords can be captured using a network packet analyzer. Only use basic authentication if you are sure that potential hackers don't have access to your network cabling or wireless media.

To configure the new virtual server to use basic authentication on Windows Server 2008
  1. In Internet Information Services (IIS) Manager, highlight the Web site you just created in the Connection pane.
  2. Double-click the Authentication feature in the Web site's Home pane.
  3. Highlight Basic Authentication in the Authentication pane.
  4. Click Enable in the Actions pane.
To configure the new virtual server to use basic authentication on Windows Server 2003
  1. In Internet Information Services (IIS) Manager, right-click the Web site you just created, and then click Properties.
  2. On the Directory Security tab, under Authentication and Access Control, click Edit.
  3. Check the Enable anonymous access check box.
  4. In the User name box for the anonymous user, type a domain user account to use for anonymous access. Note that because you are allowing access across computers, the default anonymous account (which is specific to each server) will not work. You must use a domain account for anonymous access.
  5. In the Password box, type the password that corresponds to the user account.
  6. In the Authenticated Access section, clear the Integrated Windows authentication check box, and check the Basic authentication (password is sent in clear text) check box.
  7. Click Yes to verify that you want to enable Basic authentication, and then click OK.
  8. Type the password again to confirm it, and then click OK.
  9. Click OK again to close the Properties dialog box.

Note from me:

As stated by me earlier, I only tested with Basic Authentication; I did not try Kerberos. Since we are making a single hop to another server, I would expect simple NTLM to fail. See KB 315673 for a description of single versus double hop setups when working with IIS configurations. But that being said, Windows Authentication in an Internet environment is impractical, so in most scenarios this point is moot.

After you create the virtual server, and before you can extend it with FrontPage 2002 Server Extensions, you must set the following registry entries to enable your Web server to work with a shared UNC folder:

  • NoMachineGroups: determines whether or not FrontPage 2002 Server Extensions can create local machine accounts for new users. Because local machine accounts on one server have no rights on another server, you must disable local machine accounts and use only domain accounts to work with a shared UNC folder. Set NoMachineGroups to "1" to disable local machine accounts. Note that because this is a global setting, you should only change it before you have extended your virtual servers. If you change this setting after a virtual server has been extended, the administration pages may not work.
  • AllowUNC: specifies whether or not to allow shared UNC folders. You must set this entry to "1" to enable UNC folder sharing.

Both subkeys are under the following path in the registry depending on your version of Windows:

  • On a 32-bit server:
    • HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\Web Server Extensions\All Ports
  • On a 64-bit server:
    • HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\All Ports

If these subkeys do not exist yet, you can add them as new string values, and then set them to 1.

To configure the registry for the Web server
  1. Open the Registry Editor on your Web server computer. To do so, click Start, click Run, and then type regedit.
  2. Open the correct subkey for your version of Windows:
    • On a 32-bit server:
      • HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\Web Server Extensions\All Ports
    • On a 64-bit server:
      • HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\All Ports
  3. If you see the NoMachineGroups and AllowUNCkeys, skip to step 4. If not, you must create these keys as described in the next step.
    1. Right-click in the right pane of the Registry Editor Window, click New, and then click String value.
    2. Type the name for the new entry: NoMachineGroups
    3. Right-click in the right pane of the Registry Editor Window, click New, and then click String value.
    4. Type the name for the new entry: AllowUNC
  4. In the right pane, right-click NoMachineGroups, and then click Modify.
  5. In the Value data box, type 1, and then click OK.
  6. In the right pane, right-click AllowUNC, and then click Modify.
  7. In the Value data box, type 1, and then click OK.

EXTENDING THE VIRTUAL SERVER

After the virtual server has been created and configured, you are ready to extend it with FrontPage 2002 Server Extensions. You must extend the virtual server before you can publish Web site content to it.

To enable the FrontPage Server Extensions 2002 Web Server Extension on Windows Server 2003
  1. Click Start, point to Administrative Tools, and then click Internet Information Services (IIS).
  2. In the console tree, click the name of the computer where you will create the virtual server, and then click Web Server Extensions.
  3. In Web Server Extensions, click FrontPage Server Extensions 2002, and then click Allow.
To extend the new virtual server and create a Web site
  1. Click Start, point to Administrative Tools, and then click Microsoft SharePoint Administrator.
  2. Click Extend next to the virtual server you just created in IIS.
  3. In the Administrator user name box, type the user name, and then click Submit.

After you extend the site, it is recommended that you run server health to make sure the permissions are set correctly and do not allow unauthorized access. To run server health, use the following command-line operations:

cd /d "%ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\50\bin"

owsadm.exe -o check -p 80 -w /


As I mentioned in the beginning of this post, there are a lot of steps to get this working, but it's possible to do so.

I hope this helps. ;-]

FrontPage Macro: Fix Filenames

Using this FrontPage VBA Macro

This FrontPage VBA Macro is designed to fix potential filename problems by:

  • Converting all filenames to lowercase.
  • Converting all non-alphanumeric characters to underscore characters.
  • Removing duplicate underscore characters.

FrontPage VBA Macro Example Code

Public Sub FixFilenames()
Dim objWebFile As WebFile
Dim objWebFolder As WebFolder
Dim strOldFile As String
Dim strNewFile As String

If Len(Application.ActiveWeb.Title) = 0 Then
MsgBox "A web must be open." & vbCrLf & vbCrLf & "Aborting.", vbCritical
Exit Sub
End If

For Each objWebFolder In Application.ActiveWeb.AllFolders
Here:
For Each objWebFile In objWebFolder.Files
strOldFile = objWebFile.Name
strNewFile = FixName(strOldFile)
If strNewFile <> strOldFile Then
objWebFile.Move objWebFolder.Url & "/" & strNewFile & _
".tmp.xyz." & objWebFile.Extension, True, False
objWebFile.Move objWebFolder.Url & "/" & strNewFile, True, False
GoTo Here
End If
Next
Next

MsgBox "Finished!"

End Sub

Private Function FixName(ByVal tmpOldName As String) As String
Dim intChar As Integer
Dim strChar As String
Dim tmpNewName As String

Const strValid = "1234567890_-.abcdefghijklmnopqrstuvwxyz"

tmpOldName = LCase(tmpOldName)

For intChar = 1 To Len(tmpOldName)
strChar = Mid(tmpOldName, intChar, 1)
If InStr(strValid, strChar) Then
tmpNewName = tmpNewName & strChar
Else
tmpNewName = tmpNewName & "_"
End If
Next

Do While InStr(tmpNewName, "__")
tmpNewName = Replace(tmpNewName, "__", "_")
Loop

Do While InStr(tmpNewName, "_-_")
tmpNewName = Replace(tmpNewName, "_-_", "_")
Loop

FixName = tmpNewName

End Function

Life after FPSE (Part 2)

Following up on my last blog post, today's blog post will discuss some of the highlights and pitfalls that I have seen while transitioning from using the FrontPage Server Extensions to publish web sites to WebDAV. It should be noted, of course, that FTP still works everywhere - e.g. Expression Web, FrontPage, Visual Studio, etc. As the Program Manager for both WebDAV and FTP in IIS I can honestly say that I love both technologies, but I'm understandably biased. <grin> That said, I'm quite partial to publishing over HTTP whenever possible, and Windows makes it easy to do because Windows ships with a built-in WebDAV redirector that enables you to map a drive to a web site that is using WebDAV.

To set the mood for today's blog, let's have a little fun at FPSE's expense...

No-FPSE

A Few Notes about Migrating FPSE Web Sites to WebDAV and Backwards Compatibility

To start things off, I wrote a detailed walkthrough with instructions regarding how to migrate a site that is using FPSE to WebDAV that is located at the following URL:

Migrating FPSE Sites to WebDAV
http://go.microsoft.com/fwlink/?LinkId=108347

I wrote that walkthrough from the point-of-view that you might want to preserve the FPSE-related metadata in order to open your web site using a tool like Visual Studio or FrontPage. Neither of these tools have native WebDAV support, so you have to map a drive to a WebDAV-enabled web site in order to use those tools, and the instructions in that walkthrough will lead you through the steps to make the FrontPage-related metadata available to those applications over WebDAV.

The part of that walkthrough that makes backwards compatibility work is where I discuss adding settings for the IIS 7 Request Filtering feature so that FPSE-related metadata files are blocked from normal HTTP requests, but still available to WebDAV. (These metadata settings are all kept in the folders with names like _vti_cnf, _vti_pvt, etc.)

It should be noted, however, that if you are not interested in backwards compatibility, the steps are much simpler. In Step 1 of the walkthrough, you would choose "Full Uninstall" as the removal option, and all of your _vti_nnn folders will be deleted. If you've already removed FPSE from a web site and you chose the "Uninstall" option, you can remove the _vti_nnn folders from your site by saving the following batch file as "_vti_rmv.cmd" in the root folder of you web site and then running it:

dir /ad /b /s _vti_???>_vti_rmv.txt

for /f "delims=;" %%i in (_vti_rmv.txt) do rd /q /s "%%i"

del _vti_rmv.txt

It's worth noting, of course, that this batch file can be pretty disastrous if run in the wrong web site, as FPSE will no longer be able to access any of the metadata that defined your web site. Any content stored in folders like _private, fpdb, _overlay, etc., will all be preserved.

Getting to Know the WebDAV Redirector

Windows Vista and Windows Server 2008 both ship a first-class director, making it easy to use WebDAV sites across the Internet as though they were local shares. Using the WebDAV director is as intuitive as mapping a drive to any UNC share, you just specify the drive letter and the destination URL:

MapDrive

If you prefer, you can also use the command-line to map a drive to a WebDAV site:

net use * http://www.example.com/

Enter the user name for 'www.example.com': msbob

Enter the password for www.example.com: ******

Drive Z: is now connected to http://www.example.com/.

The command completed successfully.

Rather than repeat myself any more than necessary, I wrote the following walkthrough for anyone that plans on using the WebDAV redirector:

That walkthrough discusses how to install the redirector if necessary, how to map drives to WebDAV sites, and how to troubleshoot any problems that you might see.

Microsoft Expression Web - Using a WebDAV-enabled Editor

One of my favorite publishing features in Expression Web is that it has native WebDAV support built-in, so it doesn't have a dependency on the WebDAV redirector in order to work with a WebDAV-enabled web site. If you're currently using Expression Web to open a web site using FPSE, the change to WebDAV should be fairly seamless. If you're currently using FrontPage, the Expression Web team has put together a whitepaper that describes the differences between FrontPage and Expression Web, which is available from the following link:

That being said, when opening a WebDAV web site in Expression Web, you simply enter the HTTP URL the same way that you would if you were opening a site using FPSE:

Expression-Web-Open-Site

When you first open a web site using WebDAV, Expression Web will prompt you whether to edit the web site live, or edit locally and publish your changes later:

Expression-Web-Edit-Live

Once your live web site is opened, the WebDAV editing experience is what you would have expected from using FPSE:

Expression-Web-Edit-Page

Summary

So in closing, I've presented a few things to consider when working with WebDAV instead of FPSE. Using the WebDAV redirector makes working with WebDAV sites as easy as working with network shares, and using Expression Web is by far the easiest way to edit WebDAV sites.

Life after FPSE (Part 1)

Today's blog post will be the first in a series of blog posts that I intend to write about my experiences with putting together a Windows Server 2008 machine without using the FrontPage Server Extensions (FPSE) for any web publishing. The main goal of this series is to describe some of the highlights and pitfalls that I have run into while transitioning away from FPSE.

Over the years I've seen the users of FPSE broken down into two groups: those that love FPSE and those that hate FPSE. So before anyone thinks that I fall into the category of people that hate FPSE, in this first part of the series I will explain a brief bit of my history with FPSE.

My Personal Background with FPSE

In late 1995, Microsoft bought a little-known Massachusetts-based company named Vermeer Technologies, Inc., which really only had one product: FrontPage 1.0. (Incidentally, that's where all of those _vti_nnn folders that FPSE uses come from: the "vti" stands for Vermeer Technologies, Inc.)

frontpage-1.0

FrontPage was quickly transitioned into the Microsoft array of Office products, and Microsoft realized that they needed someone to support it. With that in mind, four of my coworkers and I started a FrontPage support team in Microsoft's Product Support Services (PSS) organization. The following photo shows what the five of us looked like "way back when..."

robmcm-frontpage-startup-team

Note: My hair is much shorter now. Open-mouthed smile

The First Microsoft FrontPage Version

Back then we supported both the FrontPage client and FPSE. Two coworkers specialized on what was then a small array of Windows-based servers (WebSite, Netscape, etc.), while another coworker and I specialized on the wider array of Unix-based servers, (NCSA, CERN, Netscape, Apache, etc.) At first FPSE was 100% CGI-based, but Microsoft soon released Internet Information Services (IIS) 1.0 for Windows NT Server 3.51 and we provided an ISAPI version of FPSE when FrontPage 1.1 was released in early 1996. In either case, FPSE was often somewhat difficult to configure, so a couple of my coworkers and I used to spend our free time searching the Internet looking for servers that were using FPSE incorrectly, then we would call them and offer to help fix their web sites for free. (Support was different back then, wasn't it? Open-mouthed smile)

frontpage-1.1Windows-NT-Server-v3.51-boxshot

FrontPage Gains Popularity

Industry acceptance for FrontPage and FPSE grew rapidly through the releases of FrontPage 97 and FrontPage 98. During that same time period Microsoft released IIS 2.0 through IIS 4.0 for Windows NT Server 4.0, where I switched from supporting the FrontPage client and refocused my career to work exclusively with FPSE and IIS. Over a short period of time a couple of coworkers and I became the escalation point for all the really difficult FPSE cases - so chances are good that if you were using FPSE back then and you had a problem then one us us probably helped you fix it. Sometime around this period Microsoft decided to scrap internal development for the Unix version of FPSE, so Microsoft contracted Ready-to-Run Software, Inc., to port FPSE to Unix.

frontpage-97frontpage-98Windows-NT-Server-v4.0-boxshot

FrontPage Grows Up

The next couple of years saw the releases of FrontPage 2000, FrontPage 2002, and FrontPage 2003, where FrontPage did its best to move away from a simple web authoring tool into more of a feature-rich developer tool. During that same time period Microsoft released IIS 5.0 for Windows Server 2000 and IIS 6.0 for Windows Server 2003. Through all of these releases I slowly transitioned from an escalation team member to writing content, where I wrote or edited hundreds of Knowledge Base articles about FPSE and IIS for Microsoft's support web site. I also worked extensively with several members of the IIS product team in order to get some much-needed changes into FTP and WebDAV.

frontpage-2000frontpage-2002frontpage-2003
Windows-2008-Server-Box-ArtWindows-Server-2003-Standard-Edition-angled-boxWindows-2008-Server-Box-Art

What was interesting about the release of FrontPage 2003 is that Microsoft did not release a version of FPSE to coincide with that release. This decision was based on the fact that the product team that was responsible for FPSE was also responsible for SharePoint, and they decided to drop FPSE as a separate product in favor of SharePoint. What this meant to FPSE end users was - FPSE was being slowly phased out in favor of SharePoint, or in favor of competing publishing technologies like WebDAV or FTP.

The End of FrontPage

After the release of IIS 6.0 I accepted a position as an SDK writer on the IIS User Education team, and a short time later I found out that the Product Unit Manager for IIS, Bill Staples, was looking for someone to take over web publishing in IIS 7.0 on Windows Server 2008. Bill and I had already had several discussions on the subject so I volunteered for the position, and for the last few years my life has been happily consumed with shipping FPSE, FTP, and WebDAV for Windows Server 2008.

During this same time period, however, Microsoft ended the line of FrontPage products; the team responsible for the FrontPage client splintered into the groups that now make the SharePoint Designer and Expression Web products, and the FPSE product team was now focusing exclusively on SharePoint. This situation meant that no one that worked on FPSE in the past was available to work on a new version for Windows Vista or Windows Server 2008, which left FPSE users in a predicament if they wanted to upgrade their operating systems. With this in mind, the IIS product team decided to contract Ready-to-Run Software, Inc. again in order to port the Windows version of FPSE to Windows Vista and Windows Server 2008. Even then, though, FPSE's days are numbered.

Summary

So, the short end to this long story is that I've been around the FrontPage Server Extensions in one way or another ever since the very beginning, and I've seen the good, the bad, and the ugly.

In my next post, I'll discuss using WebDAV instead of FPSE.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FrontPage Macro: Disable Right-Click and Text Selection

Using this FrontPage VBA Macro

This FrontPage VBA Macro is designed to disable the right-click and text selection functionality for every HTML or ASP file within the currently open web site by inserting some simple JavaScript code.

Note: Unfortunately, not all web clients are created or configured equally, so some web clients will ignore this JavaScript code. So this feature will almost always work, but there's no way to guarantee.

FrontPage VBA Macro Example Code

Public Sub DisableRightClickInAllFolders()
Dim objWebFolder As WebFolder
Dim objWebFile As WebFile
Dim strExt As String

If Len(Application.ActiveWeb.Title) = 0 Then
MsgBox "A web must be open." & vbCrLf & vbCrLf & "Aborting.", vbCritical
Exit Sub
End If

With Application
For Each objWebFile In .ActiveWeb.AllFiles
DoEvents
strExt = LCase(objWebFile.Extension)
If strExt = "htm" Or strExt = "html" Or strExt = "asp" Then
objWebFile.Edit
DoEvents
.ActiveDocument.body.onContextMenu = "return false"
.ActiveDocument.body.onselectstart = "return false"
.ActivePageWindow.Save
.ActivePageWindow.Close
End If
Next
End With

End Sub

FrontPage Macro: Build Folder URL Tree

Using this FrontPage VBA Macro

This FrontPage VBA Macro is designed to return an array of all the folder URLs for the currently-open web site. I call this function from a lot of my other macros.

FrontPage VBA Macro Example Code

Private Function BuildFolderUrlTree() As Variant

On Error Resume Next

' Declare all our variables
Dim objWebFolder As WebFolder
Dim objFolder As WebFolder
Dim objSubFolder As WebFolder
Dim strBaseFolder As String
Dim lngFolderCount As Long
Dim lngBaseCount As Long

With Application

' Check the caption of the application to see if a web is open.
If .ActiveWebWindow.Caption = "Microsoft FrontPage" Then
' If no web is open, display an informational message...
MsgBox "Please open a web before running this function.", vbCritical
' ... and end the macro.
Exit Function
End If

' Change the web view to folder view.
.ActiveWeb.ActiveWebWindow.ViewMode = fpWebViewFolders
' Refresh the web view and recalc the web.
.ActiveWeb.Refresh

' Define the initial values for our folder counters.
lngFolderCount = 1
lngBaseCount = 0

' Dimension an aray to hold the folder names.
ReDim strFolders(1) As Variant

' Get the URL of the root folder for the web...
strBaseFolder = .ActiveWeb.RootFolder.Url
' ... and store the URL in our array.
strFolders(1) = strBaseFolder

' Loop while we still have folders to process.
While lngFolderCount <> lngBaseCount
' Set up a WebFolder object to a base folder.
Set objFolder = .ActiveWeb.LocateFolder(strBaseFolder)
' Loop through the collection of subfolders for the base folder.
For Each objSubFolder In objFolder.Folders
' Check to make sure that the subfolder is not a web.
If objSubFolder.IsWeb = False Then
' Increment our folder count.
lngFolderCount = lngFolderCount + 1
' Increase our array size
ReDim Preserve strFolders(lngFolderCount)
' Store the folder name in our array.
strFolders(lngFolderCount) = objSubFolder.Url
End If
Next
' Increment the base folder counter.
lngBaseCount = lngBaseCount + 1
' Get the name of the next folder to process.
strBaseFolder = strFolders(lngBaseCount + 1)
Wend
End With

' Return the array of folder names.
BuildFolderUrlTree = strFolders

End Function