Introducing "ActiveX Scripting WebPart" for SharePoint technologies...

!! Update 12/15/05 !! This blog will be discontinued someday. A new blog were comments are available has been created here.

Yes, this sounds heretic, and it probably is :-) This is a generic sample (use it at your own risk :-) WebPart for SharePoint technologies (means it works for Microsoft Windows SharePoint Services as well as Microsoft SharePoint Portal Server 2003) that runs an ActiveX Scripting code on the server.
By default, VBScript and JScript (a.k.a JavaScript) are supported on decent Windows installations, but nothing prevents you from using Python, Perl or other languages that have an ActiveX Scripting existence. Here is an example of such a code (in VBScript) that displays the user name and the current date:

Sub Render(writer)
writer.Write "User: " & Context.User.Name & "<br>"
writer.Write "Date: " & Now
End Sub

Binaries and Source code can be downloaded from here

Installation:
--------------------------------------------------------------------------------
The WebPart can be installed using SharePoint standard deployment tools:

"%CommonProgramFiles%\Microsoft Shared\web server extensions\60\BIN\stsadm"
-force -o addwppack -filename ActiveScript.Web.UI.cab
-url https://serverNameGoesHere
 
Or (GAC installation)

"%CommonProgramFiles%\Microsoft Shared\web server extensions\60\BIN\stsadm"
-force -o addwppack -filename ActiveScript.Web.UI.cab
-globalinstall -url https://serverNameGoesHere

The WebPart caches a compiled version of the scripts. If you want to disable this cache, just add the following to your web.config:
<appSettings>
...
<add key="ScriptCachingMode" value="disabled" />
...
</appSettings>

Usage:
--------------------------------------------------------------------------------
Using the standard WebPart modification tools provided by the SharePoint WebPart Framework (Design Page, Browse, Modify, ToolPane, ...), you can switch the WebPart from Edit Mode to Run Mode. In Edit mode, you can type the script code directly into the provided TextArea.
This script code can be put in the main procedure (the one that is not inside a declared procedure, sub or function). In this case, it will run probably at Page initialization. For example, the following script code will render the current user's login name *before* the first <html> declaration:

Context.Response.Write Context.User.Name

Or it can be placed inside predefined "Emulated" function. Supported emulated functions prototypes are (the syntax here is in VBScript):

Sub OnInit()
' Code put here will run in the OnInit method
' of the ActiveX Scripting WebPart
End Sub

Sub OnLoad()
' Code put here will run in the OnLoad method
' of the ActiveX Scripting WebPart
End Sub

Sub OnPreRender()
' Code put here will run in the OnPreRender method
' of the ActiveX Scripting WebPart
End Sub

Sub Render(writer)
' Code put here will run in the Render method
' of the ActiveX Scripting WebPart
' The Writer object has only one Write(object obj) method
' see the example at the beginning
End Sub

Sub OnUnload()
' Code put here will run in the OnUnload method
' of the ActiveX Scripting WebPart
End Sub

"Emulated" ASP.Net Object Model:
--------------------------------------------------------------------------------
As already demonstrated before, the script code recognizes one "named object" (in ActiveX Scripting terminology) which is "Context" (sounds familiar?). From this context object, the ActiveX Scripting WebPart provides limited support for an "emulated" ASP.Net HttpContext object model. Please consult ASP.Net documentation for details on the following properties and methods.

Legend:
+: Class
R: Read Only property
RW: Read Write property
M: Method):

+ Context
+ Cache
M void Insert(string key, object value)
M object Get(string key)
R int Count
M object Remove(string key)

+ Request
R int ContentLength
R string CurrentExecutionFilePath
R bool IsAuthenticated
R bool IsSecureConnection
R string Path
R string PathInfo
R string PhysicalApplicationPath
R string PhysicalPath
R string RawUrl
R string RequestType
R int TotalBytes
R string UserHostAddress
R string UserHostName
M void ValidateInput()
M void SaveAs(string filename, bool includeHeaders)
M void MapPath(string virtualPath, string baseVirtualDir,
bool allowCrossAppMapping)
R string UserAgent
R string HttpMethod
R string ContentType
RW Encoding ContentEncoding
R string ApplicationPath
R string FilePath

+ Response
RW bool SuppressContent
R bool IsClientConnected
RW bool Buffer
RW bool BufferOutput
RW string StatusDescription
RW string Charset
RW string Status
RW string CacheControl
RW string RedirectLocation
RW int Expires
RW DateTime ExpiresAbsolute
RW string ContentType
RW Encoding ContentEncoding
RW int StatusCode
M void AddHeader(string name, string value)
M void AppendHeader(string name, string value)
M void AppendToLog(string param)
M void ApplyAppPathModifier(string virtualPath)
M void BinaryWrite(byte[] buffer)
M void Pics(string value)
M void SetCookie(string name, string value)
M void TransmitFile(string filename)
M void Clear()
M void ClearContent()
M void ClearHeaders()
M void Close()
M void End()
M void Flush()
M void Redirect(string url, bool endResponse)
M void Write(object obj)

+ Server
R string MachineName
R int ScriptTimeout
M void ClearError()
M object CreateObject(string progID)
M object CreateObjectFromClsid(string clsid)
M string HtmlDecode(string s)
M string HtmlEncode(string s)
M string MapPath(string path)
M void Transfer(string path, bool preserveForm)
M string UrlDecode(string s)
M string UrlEncode(string s)
M string UrlPathEncode(string s)

+ Session (no method implemented so far..., coding anyone ?)

  + Trace
R TraceMode TraceMode
R bool IsEnabled
M void Write(string message)
M void Warn(string message)

+ User
R string Name
R string AuthenticationType
R bool IsAuthenticated
M bool IsInRole(string role)