Thursday, July 29, 2010

Hint Paths and The System.Reflection.CustomAttributeFormatException

With in my organization we use multiple branches and a centralized bin directory within each branch. All of our references are file based and not version specific. There are arguments for why this works or why it should not be done but this implementation has worked for our current architecture.
Now lets say one day you come to work and start in a new branch and find the System.Reflection.CustomAttributeFormatException after comping a new. And you begin asking your self how did I get here and what have I done this is not my beautiful house this is not my large automobile. After answering those questions and more colleague and I found someone added a rouge reference to a DLL in another branch. Initially this involved some meticulous evaluation of each project and its references.

I offer you a magnet for your needle in the hay stack the code below can be pasted in to a visual studio macro to scan each project and make sure it is referencing the correct path. (Your paths may vary)
Imports System
Imports System.Diagnostics
Imports EnvDTE
Imports VSLangProj
Imports System.Collections

Public Module ReferenceScanner
    Private Path As String
    Private ExcludedPaths As ArrayList
    Private Sub Scan(ByVal project As Project)
        If Not project.ProjectItems Is Nothing Then
            If TypeOf (project.Object) Is VSProject Then
                Dim visualStudioProject As VSProject = DirectCast(project.Object, VSProject)
                For Each reference As Reference In visualStudioProject.References
                    Dim referencePath As String = reference.Path
                    Dim exclude As Boolean = False
                    For Each excludePath As String In ExcludedPaths
                        exclude = referencePath.StartsWith(excludePath)
                        If exclude Then Exit For
                    Next
                    If Not exclude And Not String.IsNullOrEmpty(reference.Path) Then
                        If Not reference.Path.StartsWith(Path) Then
                            Debug.Write(project.Name)
                            Debug.Write(" ")
                            Debug.WriteLine(reference.Path)
                        End If

                    End If
                Next
            End If
            For Each childProjectItem As ProjectItem In project.ProjectItems
                If Not childProjectItem.SubProject Is Nothing Then Scan(childProjectItem.SubProject)
            Next
        End If
    End Sub
    Public Sub CheckSolutionHintPaths()
        If ExcludedPaths Is Nothing Then
            ExcludedPaths = New ArrayList()
            ExcludedPaths.Add("C:\Windows\Microsoft.NET\Framework\")
            ExcludedPaths.Add("C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\")
            ExcludedPaths.Add("D:\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\")
        End If

        Path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(DTE.Solution.FullName), "bin")
        For Each project As Project In DTE.Solution.Projects
            Scan(project)
        Next
    End Sub
End Module

*Dont forget to replace the referenced dll after you have corrected your references

Saturday, May 1, 2010

Going Going Gone.. catch(T exception)

While writing some diagnostic code I got clever and tried to use a generic in a catch statement. After spending some time head scratching I came across this stackoverflow article http://stackoverflow.com/questions/1577760/why-cant-i-catch-a-generic-exception-in-c
apparently while this code compiles without error it results in an uncaught exception. The article refers to a defect in the compiler which indicates it is version specific. A good work around is to use the following code block instead:
catch(Exception exception) { if(exception is T) {//Your specialized code here;} }

Sunday, April 18, 2010

RDP Spanning and Multi-Monitor Support

In older versions of windows that support RDP I have found it is almost impossible to use multi-monitor support across RDP as it was designed (/span). The inability to maximize to monitor boundaries on the local machine is a frustrating limitation. I have tested several configurations and thought I would share my hacktastic findings:

SplitView
I installed the demo personal edition and could not get the boundaries to work properly. To be honest I felt 39$ was a little steep for what you would be getting.

Sizer
A good old tool from the 90's is a hidden gem unfortunately it is only 32-bit but this thing is an excellent and cheap alternative. Simply fire it up on your RDP host set your window sizes and positions and your off and running.

For Extra Credit-
If you hate browsing on your RDP host because it bogs down your RDP performance (flash ads mostly). Find a tool that allows you to set your client windows as "Always On Top" so you can use local applications over your spanned and maximized RDP session.

UPDATE: This solution is primarily geared to those of us still using Vista or XP as either a client or host. Those of you lucky enough to have both windows 7 at both ends can use the multimon feature: http://blogs.msdn.com/rds/archive/2009/07/01/using-multiple-monitors-in-remote-desktop-session.aspx


Thursday, January 28, 2010

All Your .base

I encountered some issues with a .NET service installer embedded into an .MSI package today. If you have classes dependent upon service startup in your installer and the service fails to start you will often get some unexpected and often cryptic messages. It gets even worse if your messages are relating to event log messages that wont write because of permissions or other similar issues. One gotcha I am guilty of was using EventLog instead of base.EventLog. I also failed to set the event log location when calling the static version of the method calls. By using base.EventLog the ServiceBase class creates an event log source and applies all messages to the Application log. Do this and all event log messages are not belong to us.

Tuesday, January 26, 2010

Console XML/XSD Validation Application

Could not find a decent console application to validate an XML file against multiple XSD Schema Documents so I decided to write one and share for any who may need it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.Schema;

namespace XmlValidator
{
class Program
{
static void Main(string[] args)
{
int result = 0;
string documentPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, args[0]);
if (!File.Exists(documentPath)) throw new Exception(String.Format("The document '{0}' does not exist", documentPath));
List schemaPaths = new List();
foreach (string path in args.Skip(1))
{
string schemaPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, path);
if (!File.Exists(schemaPath)) throw new Exception(String.Format("The schema document '{0}' does not exist", schemaPath));
schemaPaths.Add(schemaPath);
}
using (Stream stream = File.Open(documentPath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler(
delegate(object sender, ValidationEventArgs e)
{
result = -1;
Console.Write("Line:");
Console.Write(e.Exception.LineNumber);
Console.Write(" Position:");
Console.Write(e.Exception.LinePosition);
Console.Write(" ");
Console.Write(e.Severity.ToString("G"));
Console.Write(" ");
Console.WriteLine(e.Message);

}
);
foreach (string path in schemaPaths) settings.Schemas.Add(XmlSchema.Read(XmlReader.Create(path), null));
stream.Position = 0;
XmlReader validator = XmlReader.Create(stream, settings);
while (validator.Read()) ;
validator.Close();
}
if (result == 0) Console.WriteLine("Document is valid");
#if DEBUG
Console.ReadLine();
#endif
Environment.Exit(result);
}
}
}

Tuesday, September 15, 2009

IIS7 64Bit Hang Dump.. The hard way


So I have done so many searches and have not been able to find a half decent way to get a dump when IIS7 running 64bit has hung. DebugDiag even the updated one might run on a 64bit machine but does not seem capable of generating a 64bit crash dump file. The documentation on this subject is pretty poor on the 64b aspect of IIS7 running asp.net. That being said here is how I solved the problem if anyone has a better solution I would love to hear it.


The best solution I have found is to install the debugging tools on the target machine. Then use the code below in a powershell script and run the script in your console session adjust the interval or the time out as needed for your circumstance.


$interval = 2;
$timeout = 15;
$url = 'http://www.mywebsite.com'
$command =
$client = New-Object Net.WebClient;
$client.CachePolicy = New-Object Net.Cache.RequestCachePolicy([Net.Cache.RequestCacheLevel]::NoCacheNoStore);
Write-Host "Begin Monitoring $url";
$elapsed = $null;
$interval = New-Object System.TimeSpan(0,0,0,$interval,0);
do
{
Write-Host "Waiting for next test cycle in $interval"
[System.Threading.Thread]::Sleep($interval);
$started = [System.DateTime]::Now.Ticks;
$client.QueryString['t'] = $started;
$response = $client.DownloadString($url);
$ended = [System.DateTime]::Now.Ticks;
$elapsed = New-Object System.TimeSpan($ended - $started);
Write-Host "$url completed in $elapsed"
}
while ($timeout -gt $elapsed.Seconds)
if($timeout -lt $elapsed.Seconds)
{
$ended = [System.DateTime]::Now;
Write-Host "Dumping All Worker Processes at $ended";
&'C:\Program Files\Debugging Tools for Windows (x64)\dumphangw3wp.cmd'
}

Content of dumphangw3wp.cmd


cscript.exe "C:\Program Files\Debugging Tools for Windows (x64)\ADPlus.vbs" -hang -pn w3wp.exe -o "C:\Dump Files" -quiet

Thursday, July 30, 2009

Using a builder like pattern with MVC Helper Methods

The Microsoft MVC framework is a powerful new technology but after some work I found the helper extension methods to be a little restrictive. While creating copious methods with overloads it dawned on me a string builder like pattern could be used
Here is a pseudo code example what was implemented.


//Example of builder class
using System.Web.Mvc;
public class InlineTagBuilder : TagBuilder, IHelperBuilder
where T : InlineTagBuilder
{
public InlineTagBuilder(HtmlHelper helper, string tagName, TagRenderMode mode)
: base(tagName)
{

Helper = helper;
Mode = mode;
}

protected TagRenderMode Mode { get; private set; }

public HtmlHelper Helper { get; private set; }

new public T AddCssClass(string value)
{
base.AddCssClass(value);
return (T)this;
}

new public T MergeAttribute(string key, string value, bool replaceExisting)
{
base.MergeAttribute(key, value, replaceExisting);
return (T)this;
}

new public T MergeAttribute(string key, string value)
{
base.MergeAttribute(key, value, false);
return (T)this;
}

new public T MergeAttributes(IDictionary attributes, bool replaceExisting)
{
base.MergeAttributes(attributes, replaceExisting);
return (T)this;
}

new public T MergeAttributes(IDictionary attributes)
{
base.MergeAttributes(attributes, false);
return (T)this;
}

new public T SetInnerText(string innerText)
{
base.SetInnerText(innerText);
return (T)this;
}

public T AppendAttributeValue(string key, string right)
{
string left;
if (Attributes.TryGetValue(key, out left))
{
Attributes[key] = String.Concat(left, right);
}
else
{
Attributes.Add(key, right);
}
return (T)this;
}

public T InsertAttributeValue(string key, string left)
{
string right;
if (Attributes.TryGetValue(key, out right))
{
Attributes[key] = String.Concat(left, right);
}
else
{
Attributes.Add(key, left);
}
return (T)this;
}

public T AppendEvent(string name, string body)
{
return AppendAttributeValue(name, body);
}

public T InsertEvent(string name, string body)
{
return InsertAttributeValue(name, body);
}

public T AppendStyle(string value)
{
if (value != null && !value.EndsWith(";"))
{
value = String.Concat(value, ';');
}
return AppendAttributeValue("style", value);
}

public T SetId(string id)
{
return MergeAttribute("id", id, true);
}

public T SetTitle(string title)
{
return MergeAttribute("title", title, true);
}

public T SetInnerHtml(string innerHtml)
{
base.InnerHtml = innerHtml;
return (T)this;
}

public static implicit operator string(InlineTagBuilder builder)
{
return builder.ToString(builder.Mode);
}
}
public class AnchorTagBuilder : InlineTagBuilder
{
//Anchor Set Methods Here Each Method Returns This For Inline Stacking Of Method Calls...
}
//Add extension class for easy access from the helper in the view
public static class AnchorTagBuilderExtensions
{
public static AnchorTagBuilder Anchor(this HtmlHelper helper)
{
return new AnchorTagBuilder(helper);
}
}
//Example of what the view would look like
<html>
<body>

<%=Html.Anchor().MergeAttribute("href","http://www.microsoft.com").AddCssClass("footNote").AppendEvent("onclick","alert('Really Annoying Alert Box!')") %>

</body>
</html>