Archive

Author Archive

Updating Version Numbers

July 10th, 2009 Russell No comments

I have a problem every build, where I have to update the assembly version numbers for all of my projects in my solution.

This is a hassle as I have to find them, check them out, update the version and check them in.

Ok doesnt sound like much work but all time must be accountable for minimising build times! (Especially for large projects)

I decided a python script would be a good idea to iterate through each file given a pattern and path, make a system call to TFS to check out files, update them and check them back in again.

If this script is successful, it could be used for other purposes later as well (e.g. mass replaces).

The TFS part is important for me because when files are not checked out they are in read-only mode and cant be modified using my script. Checking in is less important, however I thought it would be interesting to try to automate the whole process.

The first part is working out how to find a list of files that meet my requirements (in this case “AssemblyInfo.cs”). The os.walk() method is handy for returning a recursive list of files, and allow us to retrieve the full file path of each file.

Now we are in the context of each file:

We want to check it out. Use subprocess.call which passes a list of arguments (the first being the application) to run.

Now we read the file into a list to so we can update lines.

I decided to use regular expressions to find lines that contain [assembly: Assembly(File)Version("...")]
If it does, we update the line to (”X.Y.Z”) our new version number.

Then after that we re-write each line back to the file.

Once each file is updated, we call the same application again, passing it all the files we updated, and provides a comment.

Wallah! Easy :)

Source:

#
# Finds all AssemblyInfo.cs files and updates version numbers.
# Includes Checkout and Checkins.
#

import os
import subprocess
from os.path import join
import re

tfexec = 'C:/Program Files/Microsoft Visual Studio 9.0/Common7/IDE/tf.exe'

file_pattern = 'AssemblyInfo.cs'
asm_version = '1.0.2.9'

basepath = 'C:\\projects\\ProjectName.ProjectDir'
paths = ['Source\\Project1',
         'Source\\Project2']

file_list = []

for path in paths:
    path = basepath + '\\' + path
    for root, dirs, files in os.walk(path):
        for f in files:
            if f == file_pattern:
                filename = join(root, f)

                # TFS Checkout
                subprocess.call([tfexec, 'checkout', filename])

                # Update Value
                fin = open(filename)
                filedata = fin.readlines()
                fin.close()

                new_filedata = []

                # Go over each line in the file
                for file_line in filedata:

                    # Find/update line
                    match = re.compile('^\[assembly: AssemblyVersion\(\".*\"\)').search(file_line)
                    if (match):
                        file_line = '[assembly: AssemblyVersion(\"' + asm_version + '\")]\n'
                        file_list.append(filename + ' ')

                    # Find/update line
                    match = re.compile('^\[assembly: AssemblyFileVersion\(\".*\"\)').search(file_line)
                    if (match):
                        file_line = '[assembly: AssemblyFileVersion(\"' + asm_version + '\")]\n'
                        file_list.append(filename + ' ')                        

                    # Add line to new array.
                    new_filedata.append(file_line)

                # Write file.
                fout = open(filename, 'w')

                for line in new_filedata:
                    fout.write( line )

                fout.close()

# TFS Checkin

args = [tfexec,
        'checkin',
        '/recursive',
        '/noprompt',
        '/comment:Update Assembly Version Numbers ' + asm_version]

args.append(file_list)

subprocess.call(args)
Categories: Uncategorized Tags:

Regular Expressions: Searching for words

June 17th, 2009 Russell No comments

I had to do a mass replace to a SQL script that contained dictionary words. Visual Studio’s find & replace didn’t cut it, becuase there were 530,000 lines of SQL.

Instead, trusty Windows Grep (wingrep) came to the rescue. Two regular expression searches (then replace with blank text) only took 5 minutes!

My lines were in this format:
INSERT INTO Dictionary (word) VALUES ('apple')
I made the assumption that all words are in lower case.

Here are the regular expressions I used:

Find lines with words that contain non-alphabetic characters:
^INSERT.*\'[a-z]*[^a-z]+[a-z]*\’\)$

Find lines with words that are of length 1-3 characters:
^INSERT.*\'[a-z][a-z]?[a-z]?\’\)$

Normally in regular expressions I would have done this instead:
^INSERT.*\'[a-z]{1,3}\’\)$

But wingrep doesn’t appear to support {N, L} functionality.

Uploading Images in SQL

June 17th, 2009 Russell No comments

To upload a file to field with a type of varbinary(max), use the following:

To update a record

update <TABLE>
set <FIELD> = (Select * FROM OPENROWSET(BULK '<PATH>', SINGLE_BLOB) <FIELD>)
where <FINDRECORD>

To insert a record

insert into <TABLE>
Select
<FIELDS>,
<FIELDNAME>.*
FROM OPENROWSET
(BULK '<PATH>', SINGLE_BLOB) <FIELDNAME></code>

The path has to be accessible by the SERVER to update. Make sure the varbinary is set to varbinary(max).

Visual Studio Shortcuts Part 1

June 17th, 2009 Russell No comments

Below are some useful shortcuts for use in Visual Studio. These will only work with the C# keyboard layout.

CTRL+W, T
Display Task List
F9
Add/Remove Breakpoint
CTRL+E CTRL+W
Remove Word Wrapping
CTRL+U
Make Selection Lower Case
CTRL+SHIFT+U
Make Selection Upper Case
CTRL+K CTRL+X
Insert Snippet
CTRL+D CTRL+B
Show BreakPoint Tab
CTRL+E CTRL+C
Comment Out Selection/Line
CTRL+E CTRL+U
UnComment Out Selection/Line
CTRL+D CTRL+I
Immediate Window
CTRL+M CTRL+L
Expand All Regions
CTRL+L CTRL+L
Collapse Current Region

Unix Recursive Search

June 17th, 2009 Russell No comments

CAT is a UNIX command that displays the contents of files. It is part of the core linux utilities and comes as part of most linux distributions.

A powerful method of using CAT is piped with other commands. For example, if you want to search for something inside a text file, you could use:

cat HelloWorld.java | egrep ';$'

The previous command will pass the contents of HelloWorld.java to the next command EGREP. EGREP displays lines that contain the regular expression ‘;$’. That particular regular expression displays lines that end with a semi-colon.

This command can be used to search a source file for particular text. Rarely, however, do you want to know if a single file contians text. As a programmer, I would find it much more useful to search files from a particular directory for text. The following command will list lines from all java files in the directory:

cat *.java | egrep '^public class'

The problem with the above command is it will not search files recursively. That regular expression lists lines that begin with ‘public class’. The command CAT does not have a -r option (for example), to recursively display files.

BASH scripting can be messy, however here is a single line statement that will list all files recursively.

for a in `find `; do echo [$a]; cat $a | egrep ”; done

I will dissect it one command at a time:

The ‘for’ command is used to process each line that is resulted from the file command (see below). That way we can process each file individually. The letter ‘a’ is used as the variable that each line is put into.

The find command is similar to the ls command, except it lists files with their full paths. We need the paths to use to read each file. The single quotes (note it is the one on the ~ key) are used to tell the interpreter to execute the command inside then use the output in that position.

All commands between the ‘do’ and ‘done’ are executed for each line executed.

The text that is executed for each line is:

echo [$a]; cat $a | egrep ”;

Looks very similar to the very first command at the top of this page. It prints the contents of the file in the $a variable to standard output, and then EGREP filters each line by the expression provided. The echo command displays the filename so we know which file the search result is related to.

Here is an example:

for a in `find *.java`; do echo [$a]; cat $a | egrep ‘^public class’; done

That will display all java files in this and all subdirectories, and return lines that begin with ‘public class’.
Update:

Using ZSH, and unix tools for windows, the following will do the same:

for a in `c:/bin/find.exe | egrep '.cs$'`; do echo; echo \[$a\]:; cat $a | nl | egrep ‘ClientListDAO’; done

Categories: Uncategorized Tags: ,

Get Client IP Address in ASP .Net

June 17th, 2009 Russell No comments

The IP address of the client who sent the request can be useful for various tasks including auditing. I recently had to use the IP address to implement security auditing.

I found the HttpRequest.UserHostAddress property, however with some research discovered it will not always accurately return the correct result.

Http requests can travel from the origin to the destination via many different points on the internet. These can be proxies which will update the request header with its own IP address. The information being sent to the server is broken up into blocks, called packets.

For example:
A user is connected to the internet using a browser and has the IP address: 203.10.10.4.

They do a google search. They are sending a Http request to the IP address 74.125.67.100 (one of Google’s IPs).

Each packet will have the destination and origin IP address in the header. Packets may travel in different paths to get to the destination.

Say we have packet A:
Origin: 203.10.10.4

Packet A might be directed through the ISP proxy, which has the IP: 203.10.10.1.
The proxy will upate the header with the new IP and store the original IP in another variable in the header.

The destination will believe packet A orginated from 203.10.10.1, whereas it actually originated at 203.10.10.4.

We have to check all of the possible header variables to determine which was the original IP address. The following are the server variables:

  • REMOTE_ADDR
  • HTTP_X_FORWARDED_FOR

When the packet is created, the REMOTE_ADDR variable is set with 203.10.10.4. The proxy will update REMOTE_ADDR with 203.10.10.1 and set HTTP_X_FORWARDED_FOR with 203.10.10.4.

There is no requirements that proxies will updated the forward variable, so there is a chance we will not be able to get the correct IP address.

Here is a method that attempts to retrieve the client IP address:
///
/// Returns the IP address of the remote client.
///

public static string GetClientIPAddress(HttpContext context)
{


context.Request.UserHostAddress
string ipAddress = “”;

// Try to get the IP address if a proxy has redirected the traffic.
string ipAddressForwardedFor = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
string ipAddressForwarded = context.Request.ServerVariables["HTTP_X_FORWARDED"];

// This is the same as context.Request.UserHostAddress
string ipAddressRemoteAddress = context.Request.ServerVariables["REMOTE_ADDR"];

// If there is no forwarded for ip address in the request header
if (string.IsNullOrEmpty(ipAddressForwardedFor))
{

// If there is no forwarded ip address in the request header
if (string.IsNullOrEmpty(ipAddressForwarded))
{
// No forwarded IP address, use the remote address.
ipAddress = ipAddressRemoteAddress;
}
else
{
// Forwarded ip address.
ipAddress = ipAddressForwarded;
}


}
else
{
// Forwarded ip address.
ipAddress = ipAddressForwardedFor;
}

return ipAddress;

}
As mentioned before, there is no guarantee that you will be able to retrieve the correct IP address. There are many factors that affect the reasons for this, including user privacy.  Some proxies are used simply to hide the IP address of the sender.

References:
http://haacked.com/archive/2006/10/11/A_Gotcha_Identifying_the_Users_IP_Address.aspx
http://msdn.microsoft.com/en-us/library/system.web.httprequest.userhostaddress.aspx
http://en.wikipedia.org/wiki/Packet_(information_technology)
http://proxy.org/

Waterloo Bridge

June 13th, 2009 Russell No comments

Categories: Uncategorized Tags:

Chestnut Recipes

June 11th, 2009 Russell No comments
Categories: Food, Uncategorized Tags: ,

Opening New Browser Windows Part 3

June 11th, 2009 Russell No comments

Now we have the design from part 2, we need to do a proof of concept to check browser compatibility, and check that our design meets the requirements outlined in part 1.

We need to create two javascript files:

  • ParentWindow.js
  • ChildWindow.js

We will begin writing the ParentWindow.js.

Firstly, we need to create a parameter object. Javascript objects can behave as “associative arrays”, therefore creating a new Object instance is all we need to do to have a collection of parameters:

var parameters = new Object();

We also want to attach this object to our window object. Then it can be accessed by child windows when required:

window["Parameters"] = parameters;

So far so good. We also need to have a reference to the child window that is currently open:

var childWindow = null;

We want to provide a function that can be used to retrieve parameters as well. This means that the child window can either use a property or call a function:

window.GetParameters = function ()
{
return parameters;
}

We need a function which handles the event when the child window has been closed. It will reset the paramter values, clear the child window reference and call a custom event handler if specified. We want it to only ever get called once. Once a child window has been unloaded, it is no longer in a state to return more data.

window.HandleChildUnloadEvent_Internal = function(args)
{
// Reset parameters.
parameters = new Object();
window["Parameters"] = parameters;

// Remove child window reference.
childWindow = null;

// If the page defines an event handler, we will notify it.
// Will only call this method once.
if (HandleChildUnloadEvent && !ChildUnloadEventHandled)
{
HandleChildUnloadEvent(args);
}

ChildUnloadEventHandled = true;
}

The main function, which opens the child window, checks if a window is already opened and then create a new one. If a window is already open, we will set focus to it.

function OpenWindow(url, width, height)
{
if (childWindow == null)
{
// Reset variable.
ChildUnloadEventHandled = false;

// Set childWindow reference to an empty object.
// We want the childWindow to NOT be null while the window is loading.
// This prevents multiple windows opening.
childWindow = new Object();

childWindow = window.open (url, ”, config=’height=’ + height + ‘, \
width=’ + width + ‘, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, \
location=no, directories=no, status=no’);
}
else
{
childWindow.focus();
}
}

That is all we need for the parent javascript file. In the HTML page that is the parent page, we need to call the correct function to open the window, and updtae the page when the child window has returned:


function OpenSuburbWindow() {
// Set parameter values.
parameters["SuburbText"] = document.getElementById(”txtSuburb”).value;

// Open the window.
OpenWindow(’../SuburbLookup.htm’, ‘520′, ‘600′);
}

function HandleChildUnloadEvent(args) {
if (args != null) {
document.getElementById(”txtSuburb”).value = args["SuburbText"];
}
else {
document.getElementById(”txtSuburb”).value = “”;
}
}

The above code will get the existing value from a text input box and add it as a parameter. It will then open the window. Once the window closes, we handle the child unload event by updated the text input box with the selected parameter. If the parameter is null, (unexpectedly closed), we clear the text input box.

The child window javascript file is even simpler.
We want a parameter variable that will be populated by the parent window:

var parameters = window.opener.GetParameters();

We also want a function that will be called when the window is unloaded. It will notify the parent window of the event and pass back updated parameters:


function NotifyParentWindow(args)
{
window.opener.HandleChildUnloadEvent_Internal(args);
}

We also want a function that will pass back our parameter object, and close the window. This function will be used by the child window HTML page:


function CloseWindow()
{
NotifyParentWindow(parameters);
window.close();
}

Now all we need to do is populate the child window when the page has loaded and update the parameters and close the window. To populate the child window we create a function that is called from the body onload event:


function DoInitialSearch() {
var suburbValue = parameters["SuburbText"];
if (suburbValue) {
document.getElementById(”txtSuburb”).value = suburbValue;
}
}

We also need to create a function that will be called when the window wants to close and pass back values. In this case, when a suburb is selected we will return and close the window:


function SelectSuburb(suburb) {
parameters["SuburbText"] = suburb;
CloseWindow();
}

The proof of concept seems to be working. I encountered the following issues that need resolutions:

  • Opera does not fire the window.unload event.
  • When the site is run as static HTML pages, firefox does not allow the child window access to its parent.
  • Opera has issues with setting focus to a window.

It seems to be a widely known problem that Opera does not fire the unload event consistently with other browsers.  Setting focus to a window is not an issue that will stop functionality. It simply increases usability.

At this stage only the prototype is running as a static HTML page, so this will not be a problem when running under IIS (under the same host).

So proof of concept succeeded, now on to implementation.

Opening New Browser Windows Part 2

June 11th, 2009 Russell No comments

In part 1 I created a prototype of a window that would open in all required browsers.  Now I need to design a message sending process that will allow us to:

  • pass parameters to the new window
  • notify the parent window when an item has been selected
  • manage whether a child window has already been opened

When we create a child window, a window object is returned.  This is the object I plan to leverage to allow communication between windows.  The event we need to use is window.onunload.

As per the final post in this forum, we set up a function in the main window, that is called by the child window when it has finished processing.   It can pass back a parameter which gives us the ability to return a value as necessary. It is also nice because the child window will not need to know anything about its parent.  This helps us separate concerns, and have all the window management done in the parent!

The above design assumes the child object has a reference to its parent.  Luckily there is a property available as part of the window object in w3schools and found the opener property. This returns a reference to the window that opened the child window. This is what we need. This reference gives us a circular reference, which is not ideal.

The next design issue is passing parameters to the child window. Now we have a reference to the parent window, we can call a function to retrieve parameters. That means we can attach a function to the window object which will pass a parameter object (whatever that may be).

We have a set of functionality for the parent and for the child window.  We could put all of this into a single javascript file or separate into two.  If we put it all into one, we can reference it in one place (a master page, for example) and forget about it.  Call the openWindow method in the parent and set up functions to handle the events.  This sounds good because it is build and forget.  However it is unclear which is to be used by the child, and which for the parent.  If we separate it, it will be much easier to understand and simplify maintenance.

In summary, we now have:

A javascript file for the main window that:

  • Contains an array/list of parameters.
  • Contains a variable which contains a reference to the currently open window (or null if no child window is open).
  • Contains a function which returns the parameters.
  • Contains a function which handles an event that the child window has finished processing (passing an object parameter).
  • Attaches the above two functions to the main (current) window object.
  • Contains a function which will open a window (only if one is not already open), and keep a reference to it.

A javascript file for the child window that:

  • Initially retrieves the parameters from the parent window.
  • Handles the window.onunload event and calls the parent window notification function.
  • Passes the above function an object as a return parameter.

Next is to create a proof of concept for the above design, then finally (assuming POC succeeds) implementing it.