Powered by discountASP.NET
referal ID: sdtref
Why recommend discountASP.NET?

Archives
Steve Trefethen Steve's RSS Feed Subscribe or via email
What's this?
Contact me Send mail to the author(s)
About Me
View my LinkedIn profile

Add to Google
Subscribe with Bloglines
MCP Microsoft Certified Professional

Falafel Software
ActiveFocus Project Management Solution by Falafel Software
Online or OnSite TestComplete Training
Blogroll
Recent Comments
My Online Tools
Stats
Total Posts: 441
This Year: 46
This Month: 2
This Week: 0
Comments: 1526
Tags
Disclaimer
The posts on this weblog are provided �AS IS� with no warranties, and confer no rights. The opinions expressed herein are my own personal opinions and do not represent my employer�s view in any way.
 Thursday, February 14, 2008

Logoff Remote Desktop Session Remotely

Posted @ 10:00PM by Steve Trefethen

Categories: howto | Tips | Windows

Tags:  |  | 

I’ve been working for a client where I’m connected to their VPN much of the day working remotely on machines located at the clients site. Occasionally, I’ll run into a Remote Desktop connection limit where I can’t login and infrequently, one of the logged on sessions will be my own. At that point, I’ll occasionally try using mstsc.exe with a /console switch to try and disconnect an inactive or unused session but in this instance I was getting this error:

This computer can’t connect to the remote computer.

The next thing is to try and logoff the session remotely using two Windows utilities, quser.exe and logoff.exe. With quser you can find out the session names of the logged on users and use that information in a subsequent call to logoff.exe to close the session.

Console output of quser.exe and logoff.exe

At this point, I can successfully log back in using Remote Desktop or my current favorite remote client Terminals.

 Monday, January 28, 2008

Using the Delphi command line compiler on a Continuous Integration server

Posted @ 11:25AM by Steve Trefethen

Categories: Continuous Integration | howto

Tags:  | 

Recently, I got an email asking how to deploy the Delphi command line compiler for use on a continuous integration (CI) server. Since I’m no longer working at CodeGear nor coding in Delphi I forwarded the message to a few guys at CodeGear mentioning that it would be a good blog post but alas, I never got a response. Geeze, I didn’t think it had been that long guys! :-) Anyway...

I figured the question was worth a post if for no other reason than to start a conversation so other Delphi developers could contribute with their experience. Before we begin be sure to read your Delphi software license as I seem to recall there being some sort of issue related to the license regarding compiler deployment.

Getting the command line compiler to a build machine should be pretty straight forward though I’ve never had a need to do it myself since I was always working with the entire source tree including the compiler.

Basically, what’s needed is the Delphi compiler and the DCU/DCP’s from the products "lib" directory which means.

  • DCC32.EXE
  • The lib directory from your Delphi IDE source path

Aside from that here are some other suggestions for a build machine:

  • Using command line options (or a dcc32.cfg file) always specify an output path for the compiler, never place project related output in the same directory as DCU/DCP’s that are shipped with Delphi
  • Make sure you do a "clean" before each new build meaning run a process that deletes all of the compiler produced output from the previous build and verify that it actually works!

Be sure to read Language Reference Guide as I recall working with Nathan Tawill years ago on it and it was very good.

Lastly, another option would be to simply install a copy of the product on the build machine. Oh yeah, be sure to ask CodeGear to create an install that will take care of all this for you.

See also:
Other continuous integration posts
Video: Setting up a continuous integration environment

Ok, that’s my quick and dirty write up, your turn, what’s missing?
 Friday, January 25, 2008

Configuring DNS CNAME and MX records for Google Apps on discountASP.NET

Posted @ 7:56AM by Steve Trefethen

Categories: howto

Tags:

The other day I signed up for Google Apps for my domain allowing me to use GMail as my mail client among other things. Initially, I had a little trouble configuring the MX records in order to get GMail working on discountASP.NET (DASP) and I noticed on their support forums others had similar issues. I could send email from the account but couldn’t get replies because sending TO my address failed. The mistake I made was in the MX records where I prefixed my domain with "mail" which was incorrect, no prefix is required. Once I corrected the settings, based on forum reply from DASP, GMail worked instantly.

Here are my DNS settings for Google Apps:

CNAME Record Manager : [Help?]
Canonical Name Record: Creates an alias from one hostname to another.
Use of CNAME is generally not recommended.

Domain Name Destination TTL
start.stevetrefethen.com ghs.google.com 3600
calendar.stevetrefethen.com ghs.google.com 3600
home.stevetrefethen.com ghs.google.com 3600
docs.stevetrefethen.com ghs.google.com 3600
mail.stevetrefethen.com ghs.google.com 3600

MX Record Manager : [Help?]
Mail Exchanger Record: Identifies the email server that handles email for a domain.

Domain Name Destination Distance TTL
stevetrefethen.com ASPMX.L.GOOGLE.COM 10 3600
stevetrefethen.com ALT1.ASPMX.L.GOOGLE.COM 15 3600
stevetrefethen.com ALT2.ASPMX.L.GOOGLE.COM 15 3600
stevetrefethen.com ASPMX2.GOOGLEMAIL.COM 20 3600
stevetrefethen.com ASPMX3.GOOGLEMAIL.COM 20 3600
stevetrefethen.com ASPMX4.GOOGLEMAIL.COM 20 3600
stevetrefethen.com ASPMX5.GOOGLEMAIL.COM 20 3600

I really like discountASP.NET which is why I participate in their referral program. So far I’ve had 14 people use my referral ID so thanks to those of you who have signed up, I’ve already made my first $120! Btw, it’s nice to visit a forum for a company where you can consistently read messages that are thankful for such high quality support for a change.

Btw, be sure to check out Scott Hanselman’s post on Google Apps as it’s not the solution for everyone, at least not yet. I’m going to play with it for a bit and see how it works.

 Thursday, December 13, 2007

Configuring CruiseControl.NET to publish exceptions outside of build tasks

Posted @ 12:22AM by Steve Trefethen

Categories: Continuous Integration | howto | Open Source

Tags:  |  | 

The other day I blogged about plug-ins I’ve been writing for CruiseControl.NET for a custom process that I’m working on. I’ve written a custom <sourcecontrol> plug-in that monitors a directory on an FTP server for new files. If files are present they’re downloaded and a build is triggered. The <sourcecontrol> tag of my ccnet.config file section looks like this:
<sourcecontrol type="ftp"> <remoteHost>localhost</remoteHost> <userName>User</userName> <password>pwd</password> <localPath>c:\temp\</localPath> <remoteDir>out</remoteDir> <timeOut>2</timeOut> <fileMask>*.*</fileMask> </sourcecontrol>

A problem I was running into was that exceptions, like failed FTP connections, within my sourcecontrol plug-in weren’t being published using my email publisher as configured in ccnet.config. Prior to v1.1 this used to work using if you had following tag in your ccnet.config file:

<publishExceptions>true</publishExceptions>

With v1.1 came support for log4net replacing the functionality of this tag which is mentioned here but without further details as to the alternative. To publish these exceptions you have to configure a log4net SmtpAppender to sent email which can be done from app.config as follows:

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <to value="to@b.com" /> <from value="from@b.com" /> <subject value="test logging message" /> <smtpHost value="smtpserver" /> <bufferSize value="512" /> <lossy value="true" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="WARN"/> </evaluator> <layout type="log4net.Layout.PatternLayout"> <conversionPattern
value="%newline%date [%thread] %-5level %logger [%property{NDC}] -
%message%newline%newline%newline"
/> </layout> </appender>

Btw, don’t forget to configure this appender in the <root> node of the <log4net> section as well. It’s a bit of a bummer that you have to have two Smtp setups to handle these kinds of exceptions but at least you have the capability to get the information published.

[Update: Dec 19, 2007] To clarify the exception I'm referring to above is occurs in my implementation of ISourceControl.GetModifications.

 Sunday, November 25, 2007

Configuring email notifications for CruiseControl.NET

Posted @ 9:15PM by Steve Trefethen

Categories: Continuous Integration | howto

Tags:  | 

I gotten a few emails asking how I to setup email notifications for builds running under CruiseControl.NET. Here is a section from one of the ccnet.config files I’m using on a CruiseControl.NET server:
1 <publishers> 2 <statistics /> 3 <xmllogger /> 4 5 <email from="fromaddr@here.com" mailhost="192.168.1.14" 6 mailhostPassword="pwd" mailhostUsername="username" 7 includeDetails="true"> 8 <users> 9 <user name="Steve Trefethen" address="stevet@nospam.com" 10 group="NotifyGroup" /> 11 </users> 12 <groups> 13 <group name="NotifyGroup" notification="failed" /> 14 </groups> 15 </email> 16 </publishers>
Nothing unusual except of course for changing some of the more obvious details. :-)
 Thursday, November 01, 2007

Processing CSV files in C# using Open Source FileHelpers Library

Posted @ 1:39AM by Steve Trefethen

Categories: .NET | howto | Open Source | Programming

Tags:  |  |  | 

Scott Hanselman recently posted about parsing CSV files from PowerShell and while I found it interesting I didn’t find the solution to be intuitive though perhaps that’s just me. I’ve recently purchased PowerShell in Action by Bruce Payette and I like the idea of PowerShell though I find myself bailing back to a plain old Command Prompt quite frequently. Anyway, a few days ago I blogged about using the Open Source FileHelpers library for parsing fixed and delimited length files. I thought it might be fun to tackle Scotts problem and see just how difficult it would be to duplicate his solution in C#. Here is what he was parsing (at least a snippet of it anyway):

"File","Hits","Bandwidth"
"/hanselminutes_0026_lo.wma","78173","163625808"
"/hanselminutes_0076_robert_pickering.wma","24626","-1789110063"
"/hanselminutes_0077.wma","17204","1959963618"
"/hanselminutes_0076_robert_pickering.mp3","15796","-55874279"
"/hanselminutes_0078.wma","14832","-1241370004"
"/hanselminutes_0075.mp3","13685","-1840937989"
"/hanselminutes_0075.wma","12129","1276597408"
"/hanselminutes_0078.mp3","11058","-1186433073"

With FileHelpers the first thing to do is define a class that maps the data in your file which for Scott’s data would look something like this:

    [DelimitedRecord(",")]

    class Show

    {

        public string Filename;

        [FieldConverter(typeof(IntConverter))]

        public Int32 downloads;

        [FieldConverter(typeof(IntConverter))]

        public Int32 bandwidth;

    }

Notice the class attribute indicates the separator used. Also notice the member attributes that provide string conversion for the integer values read from the file. Since the integers, unfortunately, have quotes the stock FileHelpers converter won’t work though that’s easily solved by writing a new IntConverted like this:

    public class IntConverter : ConverterBase

    {

        public override object StringToField(string from)

        {

            if (from != "" || from != "\"\"")

                return Convert.ToInt32(from.Substring(1, from.Length - 2));

            else

                return string.Empty;

        }

    }

For parsing the file we use FileHelpers DelimitedFileEngine like this:

     DelimitedFileEngine e = new DelimitedFileEngine(typeof(Show));

     e.Options.IgnoreFirstLines = 1;

     object[] shows = e.ReadFile("c:\\shows.txt");

This creates an instance of the engine passing our Show class type with an option to ignore the first line of the file (the one with column headings). Calling ReadFile parses it into and array of Show objects populated with the data. Next, we’ll change the filename to the episode number using Scott’s regex and sort the data both using anonymous delegates:

    Regex regex = new Regex("\\d{2}(?=[_.])");

    Array.ForEach((Show[])shows, delegate(Show one)

        { one.Filename = regex.Match(one.Filename).ToString(); }

    );

    Array.Sort((Show[])shows, delegate(Show one, Show two)

        { return one.Filename.CompareTo(two.Filename); }

    );

Finally, we sum the downloads and print the data. Note this for loop modifies the array using the first instance of an episode to aggregate the total downloads, perhaps not optimal but gets the job done:

    Show sh = (Show)shows[0];

    for (int i = 1; i < shows.Length; i++)

    {

        if (((Show)shows[i]).Filename.CompareTo(sh.Filename) == 0)

            sh.downloads += ((Show)shows[i]).downloads;

        else

        {

            Console.WriteLine("{0,-4} {1,-6}", sh.Filename, sh.downloads);

            sh = ((Show)shows[i]);

        }

    }

    Console.WriteLine("{0,-4} {1,-6}", sh.Filename, sh.downloads);


So, what’s the point? Well, at the end of Scott’s post he wrote:

It took less time than it would take to write a C# program and it’s easily modified ad-hoc.

Armed with FileHelpers this took no time at all, the bulk of the code is spent working with the data not importing into a usable form. Another point is, IMO the C# code is considerably easier to read. I’m finding that getting my head around PowerShell commands to be a bit awkward. For me PowerShell is tantilizingly powerful but I feel requires a different enough mind set to perhaps thwart rapid adoption. I can empathize with all those people who have "been meaning to try..." Of course, I suppose if we all had the chance to sit down with Lee Holmes things might be different.
 Wednesday, July 18, 2007

Using FeedBurner's MyBrand feature and regaining control of my RSS feed URL

Posted @ 10:13PM by Steve Trefethen

Categories: Blogging | howto

Tags:  | 

Since last October I've had my RSS feed hosted by FeedBurner which has worked out well though one down side is that my feed URL wasn't on my domain, at least not until now. A few weeks ago I blogged about FeedBurner PRO services that are now freely available including MyBrand described as follows on the FeedBurner website:
MyBrand lets you use your own domain name to host your feed instead of feeds.feedburner.com. It puts you in even greater control of your own content with FeedBurner and best of all, MyBrand is now free.

Below I outline the steps to get this setup on DiscountASP.NET (my hosting provider) but you should be able to do the same sort of thing on your host if you control your DNS settings.

  1. Login to your DiscountASP.NET account
  2. From the control panel under Tools & Utilities, select DNS Manager
  3. After reading, click "I Understand and Agree" on the warning page 
  4. Click the link to select the domain you wish to modify, in my case stevetrefethen.com
  5. In the CNAME Record Manager section click "New"
  6. Under the Domain Name column enter the prefix you wish to use for your domain's feeds. I used "feeds"
  7. Under the Destination column enter feeds.feedburner.com
  8. Click "add"
The screen should look something like this:

CNAME editing

Be aware that changes to CNAME records may take some time to propagate so you may want to wait a day before trying to access your new URL. In fact, I've done this and have updated my RSS feeds to use my own domain name. Don't worry, if you're already subscribed you don't have to change anything as the old FeedBurner URL will continue to work.

 Monday, May 21, 2007

Disabling Windows built-in zip file support on XP and Vista

Posted @ 2:06PM by Steve Trefethen

Categories: howto | Vista | Windows

Tags:  |  | 

In this post, I discussed a problem with the built-in ZIP file support included with Windows Explorer. A comment from that post mentioned simply disabling this native support and thus I thought it might be a good idea to mention how go about doing just that. Under Windows XP you can use the following command line from a Command Prompt:
regsvr32 /u %windir%\system32\zipfldr.dll
Of course, you can always re-register support by executing the above command without the "/u". While that may work under XP it fails under Windows Vista, go figure. If you run regedit and open up HKEY_CLASSES_ROOT there is a long list of file extensions with information about the various associations and such used by Windows. If you locate ".zip" you can see that the default value is "CompressedFolder" from there you can search for a CLSID that has the same default value and you'll find:
HKEY_CLASSES_ROOT\CLSID\{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}
WARNING: The following discusses steps for editing your Windows Registry. If something should go wrong you're on your own. You've been warned!

First, export the above key before touching it at all so you have a backup. Next, if you delete this key you will effectively disable the built-in ZIP file support for Windows Explorer.


 Friday, April 20, 2007

Thunderbird can't connect securely to x.y.com because the site uses a security protocol which isn't enabled

Posted @ 1:51PM by Steve Trefethen

Categories: Email | howto | Tools

Tags:  |  | 

Mozilla Thunderbird
After installing Thunderbird 2.0 I started getting the above error message upon attempting to connect to a secure newsgroup server that I had been using successfully in Thunderbird 1.5. The issue is that Thunderbird 2.0 has disabled certain secure protocols which are considered less secure by default though the error message doesn't really help you resolve the issue. Here is what I did to gain access to this server:
  1. Start Thunderbird
  2. Select Tools|Options
  3. On the Advanced page
  4. Click "Config Editor..." button
  5. For the news server I was trying to get to I had to enable the following security property "security.ssl3.rsa_rc2_40_md5" so I typed that into the Filter edit box and double clicked it to toggle it from false to true.Close
  6. Close the Config Editor and click OK on the options dialog.
Now I'm able to get to the secure newsgroup server.
 Wednesday, December 01, 2004

How to display more than 10 RSS entries on the Delphi 2005 Welcome page

Posted @ 12:55PM by Steve Trefethen

Categories: howto

Tags:

By default the Javascript code that processes the RSS feeds on the Welcome page limit the number of entries displayed to ten.  Ten was simply a nice round number and is, unfortunately, a hardcoded value.  However, since the Javascript source code is readily available from the Welcome page directory of your Delphi 2005 installation you can easily change this number to whatever value you want.  To do that simply follow these steps:

  1. From Windows Explorer locate the Welcome page folder under your Delphi 2005 installaction folder.
  2. Select the Welcome page folder and then select the sub-folder called “js“
  3. Open the file called rss.js using the IDE (thus getting syntax highlighting) and search for “limit to 10“ and you should see the following:
// limit to 10 entries displayed on welcome page
if (maxItems > 10)

Simply change “10” (in the code portion of course :) to the number of items you'd like to be able to see.

Enjoy!