Steve Trefethen
Contact me
About Me View my LinkedIn profile

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

Spread Thunderbird

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.

Intellisense for TestComplete's Script Extensions description.xml file

November 14 2008 5:34PM
I’ve been working on Script Extensions for TestComplete and thought it would be nice to have Intellisense support while editing the description.xml file required by the IDE. Here is what I did:
  1. Opened the TestComplete online help and searched for description.xml
  2. Copied the xml and saved it to a .xml file

     TestComplete online help for description.xml
  3. From the command line I ran xsd.exe on the file as follows:

    %ProgramFiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\xsd.exe TCSchema.xml
  4. In VS.NET open a description.xml file
  5. Select XML|Schemas... and Add the schema file saved in the step above:

    Adding a schema to edit an xml file in VS.NET 2008

Now, I have Intellisense support for creating description.xml files.

Intellisense support for custom xml file

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Missing Install Script Extensions menu item in TestComplete

November 10 2008 6:30PM

Recently, I upgraded my copy of TestComplete from v6.4 to v6.5 which includes a cool new feature called Script Extensions. The online help for this feature mentions a new File|Install Script Extensions... menu item which, after upgrading was not present on the File menu.

Fortunately, there is a simple workaround which is to manually place the item onto the menu as follows:

TestComplete Customize dialog

  1. Right click on the toolbar and select Customize...
  2. On the Customize dialog click the Commands tab
  3. Select the Script Extensions Category
  4. Select the "Install Script Extensions..." item
  5. Drag/drop it onto the File menu

At present, I’m still experimenting with Script Extensions but they look very powerful and are a welcome addition to TestComplete.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: ,

Retrieving XML from Microsoft SQL Server

July 28 2008 9:43AM

A

fter completing work on the EDI Invoicing system I’ve recently started work on the other half of the equation, Purchase Order processing. There’s an existing system in place but it’s old, brittle and doesn’t support everything the system requires these days. The new CCNET based Invoice processing is humming along nicely and has handled over $3 million in invoices.

EDI CCNET Web Dashboard

Getting XML from a SqlDataReader

Like the invoicing system the purchase order side needs to query the database fetching PO data for conversion to EDI and transmission to the trading partner. I’ve been looking for clean ways to produce XML from a SqlDataReader and discovered this post by Roy Osherove. IMO, the interesting piece of that post isn’t necessarily Roy’s VB code but what’s found in the comments. Specifically, the comment I’m referring to is related to using a DbDataAdapter descendent like this:

public class DataReaderAdapter : DbDataAdapter { public int FillFromReader(DataTable dataTable, IDataReader dataReader) { return this.Fill(dataTable, dataReader); } protected override RowUpdatedEventArgs CreateRowUpdatedEvent(
DataRow dataRow,
IDbCommand command, StatementType statementType,
DataTableMapping tableMapping)
{ return null; } protected override RowUpdatingEventArgs CreateRowUpdatingEvent(
DataRow dataRow,
IDbCommand command, StatementType statementType,
DataTableMapping tableMapping)
{ return null; } protected override void OnRowUpdated(RowUpdatedEventArgs value) { } protected override void OnRowUpdating(RowUpdatingEventArgs value) { } }

A descendent is necessary here to help expose the inherited, protected Fill(...) method. Once you have the data in a DataTable you can simply call WriteXml() and viola! But there is an easier way (at least for MSSQL)!

Fetching XML from SQL Server using "FOR XML"

After mentioning the above to John Waters, Falafel’s CTO, he proposed querying directly FOR XML (literally), an MSSQL feature I wasn’t unaware of (no surprise there having been a non-database guy for so long). Using SqlCommand’s ExecuteXmlReader makes creating an XmlDocument very easy as you can see below. Simply setup the SqlCommand normally and use its ExecuteXmlReader() method:

using (XmlReader reader= command.ExecuteXmlReader())
{
   try
    {
       reader.Read();
       return new XmlDocument().Load(reader);
    }
   finally
    {
        reader.Close();
    }
}

The SQL statement looks like this:

1 SELECT * FROM SA_OrderHeader WHERE OrderHeaderID = @OrderHeaderID FOR XML, AUTO ROOT('details')

Notice "AUTO ROOT" which allows you to control the name of the root node of the returned XML document, very handy.

Having said all this I’m sure there are other ways to accomplish the same thing so please let me know what you’ve come up with.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: ,

Poor man's guide to locking down Windows XP

May 27 2008 4:57AM

A

while ago, I found myself sitting at my Mom’s Windows XP computer staring at your typical family tech support nightmare. A nephew had been given access to the machine from the admin account and the result, as you might expect, was a disaster. Of course, the conversation started with "Hey, do you think you could look at our computer it seems awfully slow?"

Some advice, if you ever hear this question and the machine has a broadband connection look for any possible means to change the subject and start packing the car!

After attempting as best I could to clean things up and having no desire to install any additional software for fear of exacerbating an already terrible situation I opted to create a secondary "nephew" user account I could attempt to lock down. Armed with Internet Explorer and Google I searched for ways to disable certain Windows features in an effort to try and "protect" the new account. My focus was only things I could do with the registry since, again, I didn’t want to install any software. Without further adieu here is the list of registry tweaks I found and used in no particular order.

WARNING: If you use and/or apply any of this information it is entirely your responsibility, you assume ALL risk. You’ve been warned!

Btw, here’s great guide to the Windows registry for reference though not all of these items came from that site.

Hide or Display Administrative Tools Menu
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\
Advanced]
Value Name: StartMenuAdminTools
Data Type: REG_SZ (String Value)
Value Data: Yes or No

Hide Control Panel, Printer and Network Settings
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoSetFolders
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Disable Drag-and-Drop on the Start Menu
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoChangeStartMenu
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disable restriction, 1 = enable restriction)

Remove Run from the Start Menu
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoRun
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Remove Tray Items from Taskbar
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoTrayItemsDisplay
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = default, 1 = enable restriction)

Disable the Change Password Button
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
System]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
System]
Value Name: DisableChangePassword
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Disable the Lock Workstation Button
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
System]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
System]
Value Name: DisableLockWorkstation
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Disable System Restore Tools and Settings
System Key: [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore]
Value Name: DisableConfig, DisableSR
Data Type: REG_DWORD (DWORD Value)
Value Data: (1 = enable restriction)

Disable the Ability to Right Click on the Desktop
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoViewContextMenu
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Screen Saver Password Protection Policy
User Key: [HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\
Desktop]
Value Name: ScreenSaverIsSecure
Data Type: REG_DWORD (DWORD Value)

Remove the Security Tab
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoSecurityTab
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = default, 1 = enable restriction)

Remove the Hardware Tab
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoHardwareTab
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = default, 1 = enable restriction)

Disable the New Menu Item
In the registry find this key [HKEY_CLASSES_ROOT\CLSID\{D969A300-E7FF-11d0-A93B-00A0C90F2719}].

Rename it by placing a dash "-" in front of the GUID (the long bracketed value at the end.

Disable the Ability to Customize Toolbars
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoToolbarCustomize
Data Type: REG_DWORD (DWORD Value)
Value Data: (1 = enable restriction)

Remove File Menu from Explorer
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoFileMenu
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Hide the Network Neighborhood Icon
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoNetHood
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = disabled, 1 = enabled)

Avoid Accidental Registry Imports with Regedit
Open your registry and find the key below.
Change the (Default) value to equal "edit".
Exit your registry editor.

System Key: [HKEY_CLASSES_ROOT\regfile\shell]
Value Name: (Default)
Data Type: REG_SZ (String Value)
Value Data: edit

Disable Windows Installer
System Key: [HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer]
Value Name: DisableMSI
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = default, 1 = admin only, 2 = disabled)

Restrict Installations from Removable Media
User Key: [HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer]
Value Name: DisableMedia
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = default, 1 = enable restriction)

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Logoff Remote Desktop Session Remotely

February 15 2008 6:00AM

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.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: , ,

Using the Delphi command line compiler on a Continuous Integration server

January 28 2008 7:25PM
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?
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: ,

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

January 25 2008 3:56PM

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.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: