Archive for the ‘Software Development’ Category

Mercurial Hook for Syntax Checking (PHP)

Friday, October 8th, 2010

For those unfamiliar with Mercurial, it is an awesome Source Control Management (SCM) tool. One of my favorite features of Mercurial is that the repositories are distributed which allows each machine to have a full copy of the project's history. Being distributed has many advantages such as faster committing, branching, tagging, merging, etc. since it is all done locally. Of course this setup also creates a backup of the repository each time an engineer clones a repository. There are a lot of benefits to using Mercurial, but that is not the focus of this post.

In this article, I am going to discuss how to setup a Mercurial hook to handle checking the syntax of files. Specifically, the hook will be setup to check the syntax of PHP files. This is beneficial as it will prevent users from adding files to Mercurial that are invalid and will keep the repository clean. Better yet, when dealing with a repository for a live website, it will prevent invalid files from ever being added to the live site.

The Pretxnchangegroup Event

Mercurial hooks are programs that Mercurial will execute during specific events. Ideally, a hook such as checking syntax would happen just before a commit is being made (the precommit event). Since Mercurial is distributed, this would require each client to install and setup the hook. This may work for some, but it does require more work and can cause issues if the hook is not setup correctly on each machine.

There is a better solution for environments that have a central repository for everyone to push their changes to. Basically, the hook can be setup on the pretxnchangegroup event. This event is executed just before a changeset (group of commits) is added to a remote repository (during a push).

To setup a hook on the pretxnchangegroup event, the syntax checking will need to build a list of every file that was changed for each changeset and then check the syntax on the latest version of each file. If there is a syntax error, the hook can exit with the appropriate status code to prevent the changesets from being added to the central repository.

When using the pretxnchangegroup event, each machine will be able to commit changes with files that have syntax errors. However, when trying to push the files to the central server, the changesets will be rejected until the syntax errors have been fixed.

In Process vs. External Hooks

With Mercurial, there are two types of hooks: an in-process and an external hook. An in-process hook is a Python module that is loaded at the time the Mercurial starts. An external hook can use any programming language that is supported by the OS.

These are advantages to using both an in-process and an external hook. An external hook is most beneficial when the code is already written in another language or the developers are more familiar with a language other than Python. An in-process hook has some nice advantages as it allows the developer access to the internals of Mercurial. It also gives the ability to display a message to the user when making a change in the repository.

External Hook Using a Shell Script

In order to show how Mercurial hooks work, I have developed both an external and in-process hook to check the syntax of PHP files. Below is the source code for an external hook. This hook is a bash script that I named php_syntax.sh.

#!/usr/local/bin/bash
echo "STARTING PHP SYNTAX CHECK..."
# create a random temp file
temp_file=`/usr/bin/mktemp -t php_syntax_files`

# get all modified files and remove duplicate's
#note: use file_mods,file_adds instead
hg log -r $HG_NODE:tip --template "{files}\n" | sort | uniq > $temp_file

# Walk through each line
#for line in "$temp_file"; do
for line in $(< $temp_file); do
	# Make sure it is a php file
	if [ `echo $line |  grep -Ei ".+\.(php)|(php4)|(php5)$"` ]
	then
		# create a random temp file
		php_file=`/usr/bin/mktemp -t php_syntax_check`

		# save the contents of this file (latest commit) to the temp file
		hg cat -r tip $line > $php_file

		# check the syntax
		php_syntax_output=`/usr/local/bin/php -l -d display_errors=1 -d error_reporting=4 -d html_errors=0 < $php_file`;

		# remove the temp file
		rm -f $php_file;

		test_syntax=`echo $php_syntax_output | grep "Parse error"`
		if [ "$test_syntax" ];then
			exit 1;
		fi
	fi
done

rm -f "$temp_file"

The above code will check the latest version of each file that is being changed when pushing to the server. It will only check files that have an extension of PHP, PHP4 or PHP5. The content of each file that is being pushed to the server is then stored in a temporary file and passed to PHP to check the syntax. If the syntax check fails, the program returns a 1 for failure which causes the entire push to fail so that no changes are pushed to the server. If there are no syntax errors, the hook exits normally and continues to push the files to the server.

In order to install the above hook in Mercurial, simply add the following 2 lines to the .hgrc and/or the hgweb.config file.

[hooks]
pretxnchangegroup.syntax_check = /usr/home/mercurial/php_syntax.sh

Of course the path in the above line needs to be updated to where the bash script was saved. The bash script will most likely need to be updated to contain the correct paths as well.

With all of the above in place the following message will be displayed to the user when trying to push a file that has a syntax error:

running hook pretxnchangegroup.syntax_check: /usr/home/code.softwareprojects.com/php_syntax.sh
transaction abort!
rollback completed
abort: pretxnchangegroup.syntax_check hook exited with status 127
warning: commit.autopush hook exited with status 1

In-Process Hook Using Python

The major flaw with using the above shell script is it does not allow us to display a nice informative error to the user when their push fails due to a syntax error. This is one advantage of using a Python in-process hook instead. I have written very similar logic in Python which can be seen below:

import subprocess,os,re
import os.path
from mercurial import ui
from random import randrange
from time import time
def check(ui, repo, hooktype, node, **kwargs):
    #initialize variables
    error = ""
    fileSet = set()
    # Loop through each changeset being added to the repository
    for change_id in xrange(repo[node].rev(), len(repo)):
        # Loop through each file for the current changeset
        for currentFile in repo[change_id].files():
            # Only Check PHP Files
            if re.match('.*\.(php)|(php4)|(php5)',currentFile):
                # Build a unique list of each file that has changed
                fileSet.add(currentFile)
    # Loop through each file that has changed
    for currentFile in fileSet:
        # Grab the latest version of the current file in the changeset
        ctx = repo['tip']
        # Do not check the file if it is being deleted
        if currentFile not in ctx:
            continue;
        # Generate a unique temporary file name using random number and timestamp
        temp_file = '/tmp/php_syntax_check.%s%s' % (randrange(0,100000),int(time()))
        # Open the temp file for writing
        f = open(temp_file,'w')
        # Get the file context
        fctx = ctx[currentFile]
        # Save the contents of the current file to the temp file
        f.write(fctx.data())
        # Close the temp file
        f.close()
        # Check the syntax of the current/temp file
        proc = subprocess.Popen('/usr/local/bin/php-cgi -l -d display_errors=1 -d error_reporting=4 -d html_errors=0 < %s' % temp_file, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        # Retrieve the output of the syntax check
        out,err = proc.communicate()
        # Check for syntax errors and save them
        if 'Parse error' in out:
            error += "%s%s\n" % (out,currentFile)
    # Check if an error occured in any of the files that were changed
    if error != "":
        # Display a message to the user about each file that contained a syntax error
        ui.warn("******************************************************" +
            error +
            "******************************************************\n")
        # Reject the changesets
        return 1
    # Accept the changesets
    return 0

This code is very similar in functionality to the shell script. It first builds a list of all of the files being pushed that have a PHP, PHP4 or PHP5 extension. Then it obtains the contents of each file that is being pushed and stores each file in a random temporary file. It checks the syntax of each file and then cancels the push if there is one or more files with invalid syntax.

Since this is an in-process hook, it is able to display a nice message to the user about why the push was not allowed. This hook is also set up to check every single file and display a message about every file that has a syntax error. This allows the hook to display a message to the user such as the following:

******************************************************
Parse error: syntax error, unexpected T_ECHO in - on line 3
Errors parsing -
afile_test.php

Parse error: syntax error, unexpected '@' in - on line 15
Errors parsing -
anotherfile_test.php
******************************************************

In order to setup this hook with Mercurial, save the above Python code in a file that is on the PYTHONPATH. Then add the following two lines of code to the .hgrc and/or the hgweb.config file.

[hooks]
pretxnchangegroup.syntax_check = python:php_syntax.check

It is important to point out that the text on the right half of the equals sign tells Mercurial what to load. In this example, it says use Python, look for a file named php_syntax.py and call the function check.

Also, Mercurial will need to be restarted after setting up the above hook or after each time the hook is modified. This is because the in-process hook is loaded when Mercurial/Python is first started.

Conclusion

Mercurial is a great SCM tool and can be very powerful when combined with either in-process or external hooks. In-process hooks provide much more control and are the preferred method in most cases. The examples above are just an introduction to Mercurial hooks and they can easily be modified for specific environments or checking the syntax of other languages.

Please leave a comment if you have found this code useful or share your experiences with Merucial and hooks.

Java Live Messenger (MSN) Robot

Thursday, September 2nd, 2010

I recently had a project to setup an Instant Messenger Robot for Windows Live Messenger. A IM robot can have many purposes such as:

  • Keeping track of when contacts are online/offline and when they were last seen.
  • Broadcasting a message to all contacts.
  • Automatically answering common questions.
  • Notifying contacts about new events. A newer site http://notify.me has a nice IM Robot that notifies you when a RSS feed is updated. This works well in conjuction with sites like craigslist.
  • Keeping track of code snippets
  • Checking the weather
  • Checking server status

An IM robot can be setup to automate just about any task.

What IM Library to Use

Setting up a IM robot can be a bit of work especially if starting from scratch. There are a lot of libraries out there that can be used to help simplify the process. The trouble is a lot of libraries are not kept up to date and fail to work as IM protocols change.

I did some digging and found a library that would provide a good foundation to build a IM Robot that can do just about anything. I saw implementations in PHP, C, Java, Perl and Python. After some testing I concluded the Java MSN Library would be a very good fit.

How To Use It

Using this library with java is pretty straight forward. First, the library must be added to the classpath. The step to take to complete this will depend on how your developing your java code. The most basic method to add a library to your classpath is to do this at run time with a command such as:

java -classpath MyLibrary.jar MyPackage.MyClass

A better approach would be to setup the classpath in a manifest file. The manifest file is then placed inside the jar file and tells the executable jar where to look for the libraries. This manifest file should look something like the following (note the class-path on line 5):

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 14.3-b01 (Sun Microsystems Inc.)
Main-Class: imstatus.Main
Class-Path: lib/jml-1.0b4-full.jar lib/httpcore-4.0.1.jar lib/mysql-co
 nnector-java-5.1.6-bin.jar
X-COMMENT: Main-Class will be added automatically by build

This is setup so that the 3 required libraries are in the lib folder. These 3 libraries are needed for setting up an IM robot and can be downloaded from the following locations:

Now that the libraries are setup we can begin to use them.

Developing the IM Robot Code

There are a few examples of using the Java MSN Library on the main page. However, they are a tad confusing as it creates a new BasicMessenger class. This is confusing as the library already has a BasicMessenger class which is abstract. The library also has a SimpleMessenger class which is a subclass of BasicMessenger. This class appears to be the correct implementation that we would want to use to create a new IM Robot. However, the original authors made the constructor protected so that we cannot instantiate the class outside of the original package. Since we want a simple way to create an IM Robot I have modified the original source code to have a public constructor for the SimpleMessenger class. This new package can be downloaded from our server.

With this new package we can very easily create a new IM Robot with the following two lines of code (make sure to replace yourLogin and yourPassword):

SimpleMessenger messenger = new SimpleMessenger(Email.parseStr("yourLogin@msn.com"), "yourPassword");
messenger.login();

With that code in our main funtion we can run it and test that the Robot automatically logs into Windows Live Messenger.

Of course, that code just logs the Robot into Windows Live Messenger. The next step is to setup the robot to do something interesting. This is one feature that is very nice about the Java MSN Library as it has listeners for many different events. For example we can detect when the robot has finished logging in with the following:

messenger.addListener(new MsnAdapter() {
	// Setup the login completed event

	@Override
	public void loginCompleted(MsnMessenger messenger) {
		MsnOwner owner = messenger.getOwner();
		owner.setInitStatus(MsnUserStatus.ONLINE);
		owner.setStatus(MsnUserStatus.ONLINE);

		// Setup the contact list event
		messenger.addContactListListener(new ContactListAdapter());
	}
});

Then we can take this a step further and detect when a status changes for one of the robots contacts with something like the following:

messenger.addListener(new MsnAdapter() {
	// Setup the login completed event

	@Override
	public void loginCompleted(MsnMessenger messenger) {
		MsnOwner owner = messenger.getOwner();
		owner.setInitStatus(MsnUserStatus.ONLINE);
		owner.setStatus(MsnUserStatus.ONLINE);

		// Setup the contact list event
		messenger.addContactListListener(new ContactListAdapter());
	}
});

The above code will detect when the robot has finished logging in and then setup a new listener to detect when a contacts status has changed. The new listener invokes the ContactListAdapter class when a status has changed. This contactListAdapter class is setup as followes:

class ContactListAdapter extends MsnContactListAdapter {
	@Override
	public void contactStatusChanged(MsnMessenger messenger, MsnContact contact) {
		System.out.println(contact.getEmail()+" is currently "+contact.getStatus());
		// Can add code here to store the status in a database
	}
}

We can still take this a step further and setup the robot to handle automatically adding contacts when a contact requests it. This logic can be added to the ContactListAdapter class with something like the following:

class ContactListAdapter extends MsnContactListAdapter {
	@Override
	public void contactListSyncCompleted(MsnMessenger messenger) {
			MsnContact[] contacts = messenger.getContactList().getContactsInList(MsnList.AL);
			for (int i = 0; i < contacts.length; i++) {
				contactStatusChanged(messenger,contacts[i]);
			}
	}

	@Override
	public void contactAddedMe(MsnMessenger messenger, MsnContact contact) {
		messenger.addFriend(contact.getEmail(), contact.getDisplayName());
	}

	@Override
	public void contactAddedMe(MsnMessenger messenger, MsnContactPending[] pending){
		for(int i=0; i<pending.length; i++){
			messenger.addFriend(pending[i].getEmail(), pending[i].getDisplayName());
		}
	}

	@Override
	public void contactStatusChanged(MsnMessenger messenger, MsnContact contact) {
		System.out.println(contact.getEmail()+" is currently "+contact.getStatus());
		// Can add code here to store the status in a database
	}
}

There you have it! Put all of the above code together and you will have a robot that knows how to automatically add contacts and keep track of when a contact's status changes.

UltraMon Breaks After Remote Desktop Connection (RDP)

Tuesday, April 6th, 2010

I use the application UltraMon to help manage my multiple monitor setup. Overall this application is awesome as it makes moving applications between monitors a breeze and supports a separate task bar on each monitor, among other things.

However, I have had this issue for a while where UltraMon will not move applications between monitors after a Remote Desktop Connection has been established, instead UltraMon acts as if there is only one monitor.

In the past the only solution I had for this issue was to restart my computer. This is not an ideal solution for me as I'm often multi-tasking and running many applications at the same time.

In order to reboot I have to close down each application, save my work, reboot, and then start up every application again after the reboot. This is not a major amount of time but it does add up if I have to do it on a regular basis. Plus, I am one who likes to optimize everything to achieve as much efficiency as humanly possible in a given day.

So, I spent a few minutes and fiddled with UltraMon and found a way to fix this RDP flaw without requiring a reboot. The steps are as follows:

  1. Close UltraMonsshot-2010-04-05-[5]
  2. Right click on your desktop and select Screen Resolution
  3. Disable the monitor that the application cannot be moved to and click apply (screenshot on right). Repeat for all monitors that are suffering from this issue.
  4. Start UltraMon
  5. Enable all monitors that were disabled in step 3.

After completing the above steps UltraMon will be as good as new.

I have only tested this on Windows 7 so let me know if this works on other Windows versions as well.

Anyone up for automating the above steps? If I get a break I might try and tackle it.

Format Credit Card with X's and Dashes using PHP (credit card masking)

Monday, March 22nd, 2010

I recently had a project where I needed to accomplish the following two tasks:

  1. Replace all but the last four digits of a credit card with X's
  2. Format the credit card with dashes in the appropriate places

There are many different approaches that can be taken to accomplish the above two tasks. The simplest approach would be to do something like the following:

<?php
echo 'XXXX-XXXX-XXXX-'.substr($cc,-4);
?>

I have often seen credit cards masked with the above approach. For the most case this solution will work fairly well. However, I am not a huge fan of this approach as it displays the credit card at a fixed length of 16 digits. This can be a bit confusing since credit cards can very in length from 13 to 16 digits.

To better address this issue I put together two functions. One function is to apply a mask to a credit card and the other is to format the credit card with dashes. These functions will keep the original length of each credit card.

<?php

/**
 * Replaces all but the last for digits with x's in the given credit card number
 * @param int|string $cc The credit card number to mask
 * @return string The masked credit card number
 */
function MaskCreditCard($cc){
	// Get the cc Length
	$cc_length = strlen($cc);

	// Replace all characters of credit card except the last four and dashes
	for($i=0; $i<$cc_length-4; $i++){
		if($cc[$i] == '-'){continue;}
		$cc[$i] = 'X';
	}

	// Return the masked Credit Card #
	return $cc;
}

/**
 * Add dashes to a credit card number.
 * @param int|string $cc The credit card number to format with dashes.
 * @return string The credit card with dashes.
 */
function FormatCreditCard($cc)
{
	// Clean out extra data that might be in the cc
	$cc = str_replace(array('-',' '),'',$cc);

	// Get the CC Length
	$cc_length = strlen($cc);

	// Initialize the new credit card to contian the last four digits
	$newCreditCard = substr($cc,-4);

	// Walk backwards through the credit card number and add a dash after every fourth digit
	for($i=$cc_length-5;$i>=0;$i--){
		// If on the fourth character add a dash
		if((($i+1)-$cc_length)%4 == 0){
			$newCreditCard = '-'.$newCreditCard;
		}
		// Add the current character to the new credit card
		$newCreditCard = $cc[$i].$newCreditCard;
	}

	// Return the formatted credit card number
	return $newCreditCard;
}

?>

Below are a couple examples of how to use these functions and the results they create.

<?php
echo maskCreditCard('5362267121053405').'<br>'; // Prints XXXXXXXXXXXX3405
echo formatCreditCard('5362267121053405').'<br>'; // Prints 5362-2671-2105-3405
echo formatCreditCard(maskCreditCard('5362267121053405')).'<br>'; // Prints XXXX-XXXX-XXXX-3405
?>
<?php
$creditCard[] = '5362267121053405'; // Mastercard
$creditCard[] = '4556189015881361'; // Visa 16
$creditCard[] = '4716904617062'; // Visa 13
$creditCard[] = '372348371455844'; // American Express
$creditCard[] = '6011757892594291'; // Discover
$creditCard[] = '30329445722959'; // Diners Club
$creditCard[] = '214927124363421'; // enRoute
$creditCard[] = '180012855304868'; // JCB 15
$creditCard[] = '3528066275370961'; // JCB 16
$creditCard[] = '8699775919'; // Voyager

for($i=0;$i<count($creditCard);$i++)
{
	echo FormatCreditCard(MaskCreditCard(($creditCard[$i])))."\n";
}
?>

Output:

XXXX-XXXX-XXXX-3405
XXXX-XXXX-XXXX-1361
X-XXXX-XXXX-7062
XXX-XXXX-XXXX-5844
XXXX-XXXX-XXXX-4291
XX-XXXX-XXXX-2959
XXX-XXXX-XXXX-3421
XXX-XXXX-XXXX-4868
XXXX-XXXX-XXXX-0961
XX-XXXX-5919

Let me know if you find these functions useful or have any suggestions on how to tweak them.

Update .htaccess with Dynamic DNS IP Address to Prevent Password Protection

Tuesday, March 9th, 2010

I was working on a password protected site that needed to allow one specific user access without requiring a login/password to access it. The site was already using .htaccess to password protect the entire site so the quickest solution was to use the following type of setup in the htaccess file:

Order deny,allow
Deny from all
AuthGroupFile /dev/null
AuthName "A Blog"
AuthType Basic
AuthUserFile /home/admin/domains/domain.com/.htpasswd/public_html/.htpasswd
require valid-user
Allow from person.getmyip.com
Satisfy Any

The main addition that I added to the password protection is line 8 "Allow from". This line allows a specific IP address or host to have access without requiring password protection.

However, the host that needed to be used was a Dynamic DNS hostname. This creates a problem as Apache takes the following steps when the user requests access.

  1. Grab IP from user requesting access
  2. Do a reverse DNS lookup
  3. Compare the results to the host in the Allow from line (person.getmyip.com)

In this case when a reverse DNS lookup is completed on the users IP address it will not find the Dynamic DNS hostname. Instead, it will find the hostname that is associated with your ISP which might look something like this 8.sub-79-231-223.myvzw.com.

There are a number of ways to get around this issue. In my case I wanted to use a small script to dynamically populate the .htaccess file with the correct IP address.

Below is the following PHP script that handles updating .htaccess with the latest IP address. The main requirement is that there is a comment "# Allow from person.getmyip.com" somewhere in the .htaccess file. This line tells the script where to insert the IP address on the very next line.

<?php
// Rewrites the entire htaccess file. When a line starts with '# Allow from brett.getmyip.com' the
// very next line will be replaced with the actual ip associated with brett.getmyip.com
$htaccessFile = "/home/admin/domains/batie.com/public_html/.htaccess";
$handle = fopen($htaccessFile, "r");
if ($handle) {
	$previous_line = $content = '';
	while (!feof($handle)) {
		$current_line = fgets($handle);

		if(stripos($previous_line,'# Allow from person.getmyip.com') !== FALSE)
		{
			$output = shell_exec('host person.getmyip.com');
			if(preg_match('#([0-9]{1,3}\.){3}[0-9]{1,3}#',$output,$matches))
			{
				$content .= 'Allow from '.$matches[0]."\n";
			}
		}else{
			$content .= $current_line;
		}
		$previous_line = $current_line;
	}
	fclose($handle);

	$tempFile = tempnam('/tmp','allow_');
	$fp = fopen($tempFile, 'w');
	fwrite($fp, $content);
	fclose($fp);
	rename($tempFile,$htaccessFile);
	chown($htaccessFile,'admin');
	chmod($htaccessFile,'0644');
}
?>

I quickly wrote this script and realize that there is room for improvement. However, this meet the need and solved the problem.

After the script was completed adding a simple line to the crontab (crontab -e) file got it running on a regular basis to automatically update the file with the current IP.

# Script to update ip access for dynamic dns host - it allows person.getmyip.com
*/5 * * * * /usr/local/bin/php /home/admin/scripts/allow_person.php >/dev/null 2>&1

Paste Code – Live Writer Plugin To Paste HTML/Code

Saturday, March 6th, 2010

I recently started using Windows Live Writer and I believe it is currently the best application out there for quickly posting to a blog. However, I found one issue where I could not easily paste HTML and other code and decided to develop a plugin to address it.

If your in a hurry here is the download link:

DOWNLOAD: Paste Code For Windows Live Writer (839 Downloads)

The Issue

Below is an example of some code I would like to paste into Live Writer.

<html>
<head>
	<title>Hello World</title>
</head>
<body>
	Hello World
</body>
</html>

When I try to paste the above code in the "Edit" window. It appears correctly on the screen but in reality Live Writer added content to my code. When I view the source I receive the following:

&lt;html&gt;
  <br />&lt;head&gt;

  <br />&#160;&#160;&#160; &lt;title&gt;Hello World&lt;/title&gt;

  <br />&lt;/head&gt;

  <br />&lt;body&gt;

  <br />&#160;&#160;&#160; Hello World

  <br />&lt;/body&gt;

  <br />&lt;/html&gt;

This is very close to how I desire to have the code formatted. However, the major problem is it inserted a bunch of <br /> characters. It does make sense that it inserted these <br />'s since in most cases we want line returns to have breaks but this is not the case when pasting source code.

Next, if I paste the code in the "Source" window the problem is the code is taken as actual source. This means that the code will not be seen on the screen but instead will be interpreted by the browser. If I then swap back and forth between the "Edit" and "Source" windows my code gets reformatted to be the following:

Hello World

Which is obviously not what I wanted.

Solution: A Plugin

To address the issues stated above I put together a plugin that will allow pasting code in either the "Edit" or "Source" windows. It will replace special characters so that the code will be viewable and will not insert extra HTML (like <br />'s).

Below is a screenshot of the plugin in action:

sshot-2010-03-06-[3]

This plugin will automatically take the code that exists on the clipboard and display it in the "Code Snippet" section and give the ability to edit the code before pasting it.

It also has the "Before Code Snippet" and "After Code Snippet" text areas. These two text areas allow defining code to wrap around your code snippet. By default the two box's will have <pre> and </pre>. Using either a <pre> or a <textarea> is required in order to have the formatting display correctly. If the content of "Before Code Snippet" and "After Code Snippet" is changed it will be remembered the next time the plugin is used.

Once insert is clicked in the plugin the code will be added to your post in Windows Live Writer and will be formatted correctly.

DOWNLOAD: Paste Code For Windows Live Writer (839 Downloads)

Icing On Top

With this plugin in place we can easily paste code and not worry about the formatting. However, it is very beneficial to have the source code displayed on your blog with syntax highlighting. I do know that there are a few plugins for Windows Live Writer that will apply syntax highlighting to code. However, I do not love this for the following reasons:

  1. Will not work when writing an article from blog's admin page.
  2. Will not easily allow changing the Syntax Highlighting to a different algorithm. There are a ton of different Syntax Highlighting plugins for blogs and every once in a while I like to upgrade to the the latest and greatest.
  3. Will not work if I decide I want to move away from Windows Live Writer (that will never happen, right?).

For my blog I am using the syntax highlighter developed by Alex Gorbachev. There is also a nice plugin that quickly installs this syntax highlighting in a wordpress blog. With the paste code plugin for Windows Live Writer in combination with syntax highlighting I can quickly paste code and achieve the following results:

sshot-2010-03-06-[4]

How to Modify a Program's Icon

Monday, March 9th, 2009

It is possible to change just about any icon that comes with an application.  There are a few different applications that will help make this job easy and my favorite is resource hacker. The reason that I can think of that someone would want to change a programs icon are the following:

  • Two programs have icons that look too similar
  • The program comes with an icon that does not give a good representation of what the program does
  • To have the coolest icons on the block
Resource Hacker Replace Icon

Resource Hacker
Replace Icon

The steps to replace an icon for a program are fairly simple. Just follow the below steps to modify the icons for any of your applications.  

  1. Download Resource Hacker
  2. Unzip the file and run ResHacker.exe
  3. Open the program that contains an icon you would like to change (like C:\Program Files\Brett Batie\Excel on Multiple Monitors\runExcel.exe)
  4. Click Actions→Replace Icon in the Menu Bar
  5. Click the "Open file with new icon…" button
  6. Select the new icon (like C:\Program Files\Microsoft Office\Office12\EXCEL.exe)
  7. Click the "Replace" button
  8. Click File→Save in the Menu Bar
  9. Close Resource Hacker All Done

Open Excel in Multiple Windows

Thursday, January 29th, 2009

In my previous post I mentioned that there was a way to create a bat file to force Excel to open each file in a new window. Opening Excel in multiple windows makes it easier to use Excel across multiple monitors and gives back the standard alt+tab to flip between Excel Spreadsheets. The problem with my previous solution was that the Excel files loose their icons. Unfortunately because the solution uses a bat file the icon cannot be changed. So I took the previous solution and enhanced it a little bit.

OpenOffice Icon

OpenOffice Icon

This solution uses the same principle but installs a program instead of using a bat file. This program has an icon so all the associated Excel files will also use that icon. I was originally hoping to use the Microsoft Icon for this program but after looking at their Terms of Use a decided to use the Open Office Icon.

Without further ado the directions to get Excel running on multiple monitors is below:

1. Download the following file and run the installer.

DOWNLOAD: Open Excel in Multiple Windows (2576 Downloads)
If you cannot install this application because you need admin privileges you can download the following file. Then follow the directions below and make sure you browse to the location of where you stored this download (in the 2nd step).
DOWNLOAD: Standalone - Open Excel in Multiple Windows (861 Downloads)

2. Update the file association for each Excel File.

Right click the excel file and select “Open With…” and then in the window that opens click “Browse…”

Open With

Then select the program that you just installed. By default it will be installed at C:\Program Files\Brett Batie\Excel on Multiple Monitors\runExcel.exe. Make sure that “Always use the selected program to open this kind of file” is checked in the “Open With” dialog.

Now anytime you open an Excel file it will open a new copy of Excel.

changelog:

1.1 - Fixed a problem where filenames with spaces would not open.

Open Excel in Two Windows (Microsoft Excel 2007 / Windows Vista)

Monday, January 19th, 2009
There is a flaw with the below solution it causes the associated Excel files to loose their icons. I posted a follow-up article for opening Excel in Multiple Windows that provides the same solution while associating a new icon with the Excel Files.

When you open an Excel file in Windows Vista, it will only open 1 instance of Excel and force you to tile the windows in order to see both at the same time. I find this annoying especially when I want the Excel files to display on multiple monitors.

I looked around for some solutions and found the following:

I didn't like using the start menu option as I like to use Windows Explorer to open my Excel files and I couldn't get the DDE option to work. So, I took a minute and developed my own fairly simple solution.

1. Put the following line of text in a bat file and save it at as c:\Program Files\runExcel.bat

start "Excel" "c:\Program Files\Microsoft Office\Office12\EXCEL.EXE" /e %1

2. Modify the shortcut for the .xls extension

Right click the excel file and select "Open With…" and then in the window that opens click "Browse…"

Open With

Then select the bat file you created in the first step by browsing to c:\program files and selecting runExcel.bat. Make sure that "Always use the selected program to open this kind of file" is checked in the "Open With" dialog.

Now anytime you double click on an Excel file it will always open it in a new window – the way I think it should be.

Verify a WordPress Blog with Google

Monday, July 21st, 2008

In order to verify your site with google you need to go to Google's Webmaster Tools Dashboard and add your website and then click verify. After clicking verify it will ask you to put a file on your website with a name similar to google54fbcc37db740a4d.html. In most cases this is all that needs to be done and then google can verify that you are the owner.

If you are using permalinks with WordPress it is not so easy to get Google to verify your site. There are two items that are causing validation to not work with WordPress. First, Google is trying to access more than just google54fbcc37db740a4d.html it is also trying to request a page that does not exist. When I tested it, Google was also asking for noexist_54fbcc37db740a4d.html. You might notice that Google just replaced the word "google" with "noexist_". Second, WordPress is taking a request for any page (including ones that do not exist) and trying to find an appropriate page and is therefore not returning a 404 error. These two problems cause Google to respond with the following error when you try to validate your site.

We've detected that your 404 (file not found) error page returns a status of 200 (Success) in the header.

 The code that causes WordPress to not return a 404 for an invalid page is the following which is in an .htaccess file.

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

After creating your file google54fbcc37db740a4d.html and adding it to your server you just have to modify the above .htaccess file to have it not redirect the request for noexist_54fbcc37db740a4d.html to index.php. You also need to specify a specific page or message to display when a 404 error occurs. You can do that by replacing the above code with the following code.

RewriteEngine On
ErrorDocument 404 "This page does not exist"
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{request_uri} !^/noexist_54fbcc37db740a4d.html$ [nc]
RewriteRule . /index.php [L]

Make sure you replace the 54fbcc37db740a4d in the above code with the same characters of the file that google tells you to add to your website.