Thursday, November 28, 2013

Emulating Back and Forward On A Regular 2 Button Scroll Mouse

I have discovered just how much I depend on the back and forward buttons on my mouse. Working on a lot of different computers where I cannot control the hardware I am provided, but thankfully I can over come that by using AutoHotKey and adding the following script to the default script.

It is important to ensure the first line is in the script. If it is not there, you will not be able to use your right button for anything. Seems unintuitive, but that is how it is.
RButton::click right
RButton & WheelDown::Send {Browser_Back}  ; Left Arrow, Browser Back Button
RButton & WheelUp::Send {Browser_Forward}  ; Right Arrow, Browser Forward Button
Now I can navigate forward and backward by right clicking and scrolling.

Tuesday, November 19, 2013

Suppressing Compiler Warnings

Sometimes there are warnings that are necessary, but they can clog up your compiler output or MSBuild output. There is a simple way to turn off the ones that need to be there. Simply find the codes that should be suppressed by looking at the compiler output. For example, below is a warning from MSBuild (these can also be found in the Error List panel in Visual Studio).
c:\<path to file with the warning>\SomePage.aspx.cs(1196): warning CS0219: The variable 'SomeString' is assigned but its value is never used [C:\<path to build file>\Build.xml]
Then you surround the code that is generating the warning and surround it with #pragma warning tags like below. You can suppress multiple warnings like in the example below.
#pragma warning disable 0649
#pragma warning disable 0219

// Put your code here that will generate the warnings.  

#pragma warning restore 0219
#pragma warning restore 0649

Friday, November 8, 2013

MsBuild CodeTaskFactory Custom Task to Warming Up a Web App

I remember reading about the MSBuild CodeTaskFactory a couple years ago and hadn't run into a situation where I needed it until now. CodeTaskFactory is a great way to extend MSBuild's capabilities without having to go through the hassle of creating a custom MSBuild Task and having to make sure everyone has the dll.
<UsingTask TaskName="TestWebAppAvailable" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
  <ParameterGroup>
    <hostname ParameterType="System.String" Required="true" />
    <servers ParameterType="System.String[]" Required="true" />
    <Result ParameterType="System.String" Output="true" />
    <!--<TestSuccess ParameterType="System.Boolean" Output="true" />-->
  </ParameterGroup>
  <Task>
    <!--<Reference Include="System.Xml"/>-->
    <Reference Include="System.IO"/>
    <Reference Include="System.Net"/>
    <Using Namespace="System"/>
    <Using Namespace="System.IO"/>
    <Using Namespace="System.Net"/>
    <Code Type="Fragment" Language="cs">
      <![CDATA[
string requestUrl = "http://" + hostname + "/Default.aspx";
Result = "success";
foreach (string server in servers)
{
    Log.LogMessage("Server: " + server, MessageImportance.Normal);
    if (string.IsNullOrEmpty(server))
    {
        continue;
    }
    Log.LogMessage("Warming up: " + requestUrl, MessageImportance.Normal);
    System.Net.HttpWebResponse res = null;
    try
    {
        System.Net.WebRequest wr = System.Net.WebRequest.Create(requestUrl);
        wr.Timeout = 20000;
        wr.Proxy = new System.Net.WebProxy("http://" + server, false);
        res = (HttpWebResponse)wr.GetResponse();
        Log.LogMessage(server + " - " + res.StatusCode, MessageImportance.Normal);
    }
    catch (System.Net.WebException ex)
    {
        res = (HttpWebResponse)ex.Response;
        Log.LogMessage("EXCEPTION: " + ex.ToString(), MessageImportance.High);
        Log.LogMessage("res == null: " + (res == null).ToString(), MessageImportance.High);
        Log.LogMessage("Server: " + server, MessageImportance.High);
        Log.LogMessage("res.StatusCode: " + (res != null ? res.StatusCode.ToString() : "Res was null"), MessageImportance.High);
    }
    catch (System.Exception ex) {
        throw;
    }
    Log.LogMessage("res == null: " + (res == null).ToString(), MessageImportance.High);
    if (res.StatusCode != System.Net.HttpStatusCode.OK)
    {
        string message = server + " Web request failed with code: " + res.StatusCode.ToString();
        System.Net.WebException exception = new System.Net.WebException(message);
        if (res != null)
        {
            res.Close();
        }
        Result = server;
        Log.LogMessage("EXCEPTION: " + message, MessageImportance.High);
        break;
    }
    
    if (res != null)
    {
        res.Close();
    }
}
]]>
    </Code>
  </Task>
</UsingTask>
Basically this takes in a host header for the hostname and a list of servers. It then iterates over the servers and requests the Default.aspx page. A successful request returns "success". A request that returns a status code that is not 200 returns the server name that failed.

Then using the new custom task is as easy as the following:
<ItemGroup>
  <Servers Include="$(DeploymentWebServer1)"></Servers>
  <Servers Include="$(DeploymentWebServer2)"></Servers>
</ItemGroup>
<TestWebAppAvailable hostname="$(DeploymentHostname)" servers="@(Servers)" ContinueOnError="True">
  <Output TaskParameter="Result" PropertyName="TestResult" />
</TestWebAppAvailable>
<Error Text="Server $(TestResult) returned a bad response.  Recopy web application files." Condition="'$(TestResult)' != 'success'" />