Just a short, simple blog for Bob to share his thoughts.
27 October 2013 • by Bob • FrontPage, Macros, VBA
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.
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.
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
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:
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/
21 June 2013 • by Bob • FrontPage, Macros, 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.)
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.
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
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/
02 February 2011 • by Bob • FrontPage
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.
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
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 |
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/
31 January 2011 • by Bob • FrontPage, IIS, WebDAV
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.
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.
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:
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:
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.
For additional information on the concepts that were discussing in this blog, see the following topics:
I hope this helps.
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
28 April 2010 • by Bob • FrontPage
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:
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:
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:
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.
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.
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.
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.
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:
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.
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:
Both subkeys are under the following path in the registry depending on your version of Windows:
If these subkeys do not exist yet, you can add them as new string values, and then set them to 1.
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.
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. ;-]
05 April 2009 • by Bob • FrontPage
This FrontPage VBA Macro is designed to fix potential filename problems by:
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
23 April 2008 • by Bob • FrontPage, IIS, WebDAV
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...
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.
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:
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:
Using the WebDAV Redirector
http://go.microsoft.com/fwlink/?LinkId=112138
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.
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:
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:
Once your live web site is opened, the WebDAV editing experience is what you would have expected from using FPSE:
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.
17 April 2008 • by Bob • FrontPage, IIS
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.
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 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..."
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? )
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.
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.
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.
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.
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/
17 February 2008 • by Bob • FrontPage
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.
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
17 February 2008 • by Bob • FrontPage
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.
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