Monday, December 28, 2009

Programmatically Create a ClickOnce Application Shortcut

A common approach for programmatically creating a shortcut to a ClickOnce application is to copy the “Application Reference” (*.appref-ms) file that was created in the user’s start menu when the application was installed.

The following function will create a ClickOnce Application Shortcut (*.appref-ms) file for the currently running ClickOnce application without coping the file that exists in the user’s start menu:

''' <summary>
''' Creates a ClickOnce application reference (*.appref-ms) file for the
''' currently running ClickOnce application.
'''
</summary>
''' <param name="location">
''' Path, including file name, of the new ClickOnce application reference
''' file to create. File should have an ".appref-ms" extension.
'''
</param>
Public Sub CreateClickOnceShortcut( _
   
ByVal location As String)

   
Dim updateLocation As Uri = _
        Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation
   
Dim AppSecurityInfo As New Security.Policy.ApplicationSecurityInfo( _
        AppDomain.CurrentDomain.ActivationContext)
   
Dim DeploymentInfo As ApplicationId = AppSecurityInfo.DeploymentId
   
Dim PublicKey As Byte() = DeploymentInfo.PublicKeyToken

   
Using ShortcutFile As New IO.StreamWriter( _
        location,
False, System.Text.Encoding.Unicode)

        ShortcutFile.Write(updateLocation.ToString().Replace(
" ", "%20"))
        ShortcutFile.Write(
"#"c)
        ShortcutFile.Write(DeploymentInfo.Name)
        ShortcutFile.Write(
", Culture=neutral, PublicKeyToken=")

       
For i As Integer = 0 To (PublicKey.Length - 1)
            ShortcutFile.Write(
"{0:x}", PublicKey(i))
       
Next i

        ShortcutFile.Write(
", processorArchitecture=")
        ShortcutFile.Write(DeploymentInfo.ProcessorArchitecture)

        ShortcutFile.Close()

   
End Using

End
Sub

It appears that the ClickOnce application’s manifest must be signed for the shortcut’s application specific icon to appear. If it is not signed, the default application icon appears.

Monday, December 21, 2009

ASP.NET AJAX Control Toolkit Hidden ComboBox Issue

The AJAX ComboBox control that is included in the September 2009 Release of the ASP.NET AJAX Control Toolkit has a problem whenever the control is hidden when the page is initially rendered. The button for the ComboBox control appears as a 1x1 pixel button and the DropDown list is only 1 or 2 pixels high.

The following is a javascript function I wrote that will correct these issues if it is called right after the ComboBox is made visible.

// Resets the ComboBox indicated by the id argument

// that was hidden when the
// page was initially rendered. This method should

// be called right after the
// hidden ComboBox is made visible. This function

// will correct control sizing
// issues that occur when a ComboBox is not visible

// when the page is initially
// rendered.
//
// Parameters:
// id: Name of the ComboBox control to reset.
// --------------------------------------------------

function ResetComboBox(id) { 

    // Get ComboBox 
    var Combo = Sys.Application.findComponent(id);  

    // Get Button Style 
    var ButtonStyle = Combo.get_buttonControl().style;  

    // Reset Button Image 
    ButtonStyle.height = Combo.get_textBoxControl().offsetHeight + 'px'
    ButtonStyle.width = ButtonStyle.height;

    // Reset Options List 
    var OptionListStyle = Combo.get_optionListControl().style; 
    Combo._optionListHeight = null
    Combo._optionListWidth = null
    OptionListStyle.display = 'block';
}

NOTE: I have only tested this with the September 2009 Release of the ASP.NET AJAX Control Toolkit.

Monday, April 20, 2009

Configuring IIS 6 to use Host Headers

IIS 6 can be setup to host mutiple websites using the same IP address using Host Headers. If the site only runs on port 80 (i.e. only uses http:// not https://) this can be setup using the Internet Information Services (IIS) Manager's "Advanced Web Site Identification" dialog. If one or more of the websites hosted on the IP address uses port 443 (i.e. https:// or SSL), the Host Headers must be configured using a command line tool.

Configuring Server Bindings for SSL Host Headers (IIS 6.0)

1. Open a Command Prompt window and change to the %SystemDrive%\Inetpub\AdminScripts directory.
2. Enter the following command to get a list of websites hosted by this server:

cscript.exe adsutil.vbs ENUM /P /W3SVC/

You should see something like the following:
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

[/W3SVC/AppPools]
[/W3SVC/Info]
[/W3SVC/1]
[/W3SVC/Filters]
[/W3SVC/260116085]
[/W3SVC/2123871385]
[/W3SVC/721699136]
 
To determine which the name of each website, enter the following command:

cscript.exe adsutil.vbs ENUM /W3SVC/<site identifier>/

Where <site identifier> is the number of the site to check. You should see something like the following:
 
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
 
KeyType                         : (STRING) "IIsWebServer"
ServerState                     : (INTEGER) 2
ServerComment                   : (STRING) "GenerationsUnite"
ServerAutoStart                 : (BOOLEAN) True
ServerBindings                  : (LIST) (2 Items)
  "192.168.64.7:80:www.mysite.com"
  "192.168.64.7:80:mysite.com"
 
SecureBindings                  : (LIST) (2 Items)
  ":443:www.mysite.com"
  ":443:mysite.com"
 
AuthFlags                       : (INTEGER) 0
Win32Error                      : (INTEGER) 0
[/W3SVC/260116085/filters]
[/W3SVC/260116085/root]
 
3. To setup an SSL Host Header binding, enter the following command:

cscript.exe adsutil.vbs set /w3svc/<site identifier>/SecureBindings ":443:<host header>" [<additional bindings>]

The following is an example that sets up two bindings for a website:

cscript.exe adsutil.vbs set /w3svc/260116085/SecureBindings ":443:www.mysite.com" ":443:mysite.com"

 

Thursday, February 26, 2009

XML Schema whiteSpace and the token Data Type

In developing some new XML Schema documents, we came across an unexpected relationship between the XML Schema token datatype and the rules for processing whitespace.

In section 3.3.2 of the XML Schema Part 2: Datatypes Second Edition document, token is defined as follows:

[Definition:] token represents tokenized strings. The •value space• of token is the set of strings that do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters, that have no leading or trailing spaces (#x20) and that have no internal sequences of two or more spaces. The •lexical space• of token is the set of strings that do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters, that have no leading or trailing spaces (#x20) and that have no internal sequences of two or more spaces. The •base type• of token is normalizedString.

Based on this paragraph, we assumed any validator (XSV for example) would indicate an instance error if the value of a token element contained a carriage return, line feed, or tab character. I also assumed a validator would indicate an instance error if the value of a token element contained any leading or trailing spaces or any internal sequences of two or more spaces. These assumptions, however, were not correct as is demonstrated by the following example:

Given the following XML Schema declaration:

<xs:element type="xs:token" name="XmlToken" />

The following are considered valid by validators:

<XmlToken>
  Token
</XmlToken>
<XmlToken>   Token   </XmlToken>
<XmlToken>
  Token1        Token2 
  Token3
  Token4 Token5 Token6
</XmlToken>

The reason these are considered valid token values has to do with the whitespace processing rules. Per section 4.3.6 (whiteSpace) of the XML Schema Part 2: Datatypes Second Edition document, an token actually allows carriage return (#xD), line feed (#xA) and tab (#x9) characters to appear in the value.

[Definition:] whiteSpace constrains the •value space• of types •derived• from string such that the various behaviors specified in Attribute Value Normalization in [XML 1.0 (Second Edition)] are realized. The value of whiteSpace must be one of {preserve, replace, collapse}.

preserve
No normalization is done, the value is not changed (this is the behavior required by [XML 1.0 (Second Edition)] for element content)

replace
All occurrences of #x9 (tab), #xA (line feed) and #xD (carriage return) are replaced with #x20 (space) 

collapse
After the processing implied by replace, contiguous sequences of #x20's are collapsed to a single #x20, and leading and trailing #x20's are removed.

whiteSpace is applicable to all •atomic• and •list• datatypes. For all •atomic• datatypes other than string (and types •derived• by •restriction• from it) the value of whiteSpace is collapse and cannot be changed by a schema author; for string the value of whiteSpace is preserve; for any type •derived• by •restriction• from string the value of whiteSpace can be any of the three legal values. For all datatypes •derived• by •list• the value of whiteSpace is collapse and cannot be changed by a schema author.

Since the whiteSpace value for a token is collapse, all whitespace characters are replaced with a space character, all leading and trailing space characters are removed, and all contiguous space characters are collapsed into a single space character before the XML instance document is validated.

Since all the offensive characters are removed before the document is validated, token values can actually contain carriage return, line feed, and tab character, even though they are forbidden by section 3.2.2 (token) of the XML Schema Part 2: Datatypes Second Edition document.