Sunday, November 20, 2005

Setting the DOS ErrorLevel

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/setting_the_dos_errorlevel.htm]

Programs can return an errorLevel. Batch scripts can then access than using %ErrorLevel%, and then use this in the flow of the script. For example, if program X returns a certain errorLevel, the script can take a specific path. Convention is that an errorLevel of 0 is "Success", and anything else is some kind of failure.

This is not to be confused with creating an environmental variable named "ErrorLevel". Setting the environmental variable does not update the batch script's error level itself. This becomes apparent when using another tool that checks the script errorLevel. For example, in NAnt you can execute batch scripts and specify the build to fail if there's an error in the batch. However, you'll notice (at least in version .84) that setting the errorLevel as an environmental variable won't cause the script to fail, but having an exe fail will.

We want the option of setting the errorLevel from an environmental variable, not just through an exe. We can do this by writing a trivial console app:

[STAThread]
static int Main(string[] args)
{
      int i = 0;
      try
      {
         i = Convert.ToInt32(args[0]);
      }
      catch
      {
        Console.WriteLine("Error info...");
      }
      return i;
}

This takes a single argument from the command line, converts it to an integer, and then returns that value as the program error code. Note that console apps need not return "void", as is the template default. They can return int precisely for this purpose.

We can then call this program, passing in some parameter from DOS, and it will set the errorLevel. You'll notice that this would cause the NAnt build to fail. Also note that this call must be the every last line of the batch - not even an ECHO or REM after it.

Confusing the environmental errorLevel and DOS script's errorLevel is an easy and understandable mistake, and fortunately it has an easy and understandable solution.

Monday, November 14, 2005

Random DOS Nuances: for-loops, params, and if-blocks

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/random_dos_nuances_forloops_params_and_ifblocks.htm]

I've blogged some tips on DOS before, but here are some more. One of my coworkers (thanks Roey) pointed out several DOS nuances that I found useful - they're the kind of things that are easy to miss:

Use single % for parameters (like %1), double %% for variables (like %myVar%)

While you can use environmental variables using the percent signs like so: %myVar%, parameters only have the first percent, like so: %1. What's tedious is if you make it %1%, you may be able to get away with it in some cases. But if you put two parameters on the same like like %1...%2, then you need to get it straight.

Set operators within an if-block don't update until after the if-block finishes

In a language like C#, you could both update the variable, and then use that variable within the same if-block. Apparently you can't do that in DOS.

REM: Won't work:
If 0 EQU 0 (
    set outputFile="ABC"
    Echo Value: %outputFile%
)

You need to let the if-block finish first. You can do this by putting the set operation in its own block, either like this:

REM: WIll work:
If 0 EQU 0 (
set outputFile="ABC"
)
Echo Value: %outputFile%

or like this:

REM: will also work:
If 0 EQU 0 set outputFile="ABC"
If 0 EQU 0 Echo Value: %outputFile%

DOS for-loops in a batch script require an extra '%' in front of the variable.

This will fail:

Rem start loop:
for /F %a in (C:\temp\List.txt) do Echo %a
Pause

This will work:

Rem start loop:
for /F %%a in (C:\temp\List.txt) do Echo %%a
Pause

This last one is especially tedious to debug because if you copy the contents of the script to a command window to run it, then it suddenly works.
 

Thursday, November 10, 2005

Chicago .Net Launch

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/chicago_net_launch.htm]

I just got back from the Chicago .Net Launch, and it was very impressive. It looks like Microsoft is releasing new products for the entire enterprise spectrum. I'm especially interested in the new Visual Studio and Team System that finally makes it easy to build good development process, and the new features of ASP.Net. I also had some great experiences with the ask-the-experts. The Microsoft guys were on as usual, but the non-Microsoft experts were great too. In particular, Jon Henning of DotNetNuke nailed a bunch of my ASP questions. I also stopped at maybe 50 different vendor booths to see every kind of tool and service in the .Net ecosphere. A good day all around.

Tuesday, November 8, 2005

Making backups with the free RoboCopy

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/making_backups_with_the_free_robocopy.htm]

I had gotten an external harddrive to backup my laptop, but now I needed a way to copy only changed files. For example, if I have 5GB of files to backup, but perhaps only 10-100MB of new files each time I do the backup, for performance reasons I only want to copy the new stuff. Initially I thought "oh well, I'll just write my own program to do this", but then I realize that this is such a common task that there has to be free stuff out there (principle: don't reinvent the wheel). Someone pointed me to Robocopy, which you can download for free, along with 50+ other tools, as part of the Windows Server 2003 Resource Kit Tools.

Robocopy, for "Robust File Copy Utility ", is a command line tool for copying files from one location to another. It has all the switched that you'd expect: only copy changed files, ignore hidden files, number of times to retry copy a file if there are errors (such as a process locks the file and you can't copy it). It's a convenient thing. I created a batch script to do my master backup:

set USBdrive="E:\Tim_Main"
rem "C:\Ameripay" "%USBdrive%Tim_Main\Ameripay"

robocopy /S /R:2 /W:10 /XA:H "C:\Ameripay" "%USBdrive%\Ameripay"
robocopy /S /R:2 /W:10 /XA:H "C:\Development" "%USBdrive%\Development"
robocopy /S /R:2 /W:10 /XA:H "C:\Documents and Settings" "%USBdrive%\Documents and Settings"
robocopy /S /R:2 /W:10 /XA:H "C:\Inetpub" "%USBdrive%\Inetpub"
robocopy /S /R:2 /W:10 /XA:H "C:\Learning" "%USBdrive%\Learning"
robocopy /S /R:2 /W:10 /XA:H "C:\Projects" "%USBdrive%\Projects"

REM DONE!

Pause

I stored the target drive as an environmental variable, and then used the following options:

SwitchPurpose
/SCopy Subdirectories, but not empty ones.
/R:2Number of Retries on failed copies: default 1 million.
/W:10Wait time between retries: default is 30 seconds.
/XA:HDon't copy hidden files

There's tons of other switches to configure.

It's quick, yet extremely helpful if your main hard drive crashes.

Tuesday, November 1, 2005

Reminders for Text Editor Settings

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/reminders_for_text_editor_settings.htm]

Developers use Text ASCII files for tons of things - source code, Xml, html pages, etc... There are tons of different editors for these different kinds of files (Visual Studio, XmlSpy, FrontPage, NotePad, etc...). Given that multiple developers are working on the same files and storing them in source control, there are two potential options that should be consistent between your text editors:

  • Make sure they have the same tab settings (such as a tab = 4 spaces)
  • Make sure they use the same line break character (such as CR & LF).

For example, if you have XmlSpy use regular tabs, but Visual Studio use tabs=4 spaces, then when the same file is edited in both, it may get totally reformatted. This can cause merge problems. However if they both have the same tab and line break settings, then they won't be reformatted differently.

Most tools have these settings stored under something like Tools > Options. It's a quick thing to check, but an annoying thing if it goes unchecked.

Monday, October 31, 2005

HtmlControls vs. WebControls

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/htmlcontrols_vs_webcontrols.htm]

Plain Html provides form controls via the tag. These are standard controls like textBoxes, dropdowns, and radiobuttons. ASP.Net provides its own version of these controls. Ultimately the ASP.Net version gets rendered as a html. For development you can use either the WebControls or the normal html controls run as server controls. The table below offers some comparisons:

 WebControlHtmlControl runat=server
DescriptionThe ASP.Net controls residing in System.Web.UI.WebControlsNormal html controls that are run at the server. These reside in System.Web.UI.HtmlControls. Setting a HtmLControl to be runat=server does not automatically make it an ASP.Net webControl.
Pro
  • Easier to initially use. For example, automatically works with validators (a disabled Html control doesn't).
  • Many more webControls than htmlControls (such as the dataGrid, validators, and placeHolders)
  • Lighter - doesn't have all the extra properties of WebControls
  • Easier to hook up to JavaScript.
Con
  • Heavier - has more properties, state, and methods, such as the AutoPostBack. Just compare HtmlInputText and TextBox.
  • Lacks the extra features of WebControls

The Pros and Cons mean that they each have scenarios where one is better than the other. For cases like textBox and dropdown where both can provide the same control: HtmlControls are good for high performance apps because you use only the functionality that you need, WebControls are good for rapid development because it automatically gives you more stuff (which then must be paid for with performance).

Thursday, October 27, 2005

Using a single html file for easy management

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/using_a_single_html_file_for_easy_management.htm]

Normally you want to split your html objects (like styles, scripts, and data) into separate files to make things more reusable. However sometimes when you're creating an internal developer report (for status, confirmation, quick info, etc...), it's easier to give the user a single html file than a whole collection of files. For example, suppose you're making an internal WinForms tool that assists with some development task, and then generates an Html status report. As a single file, it's easier to mail to others or copy into different directories,.

An html page can have several components, each as separate, physical files:

  • The main html page itself
  • A style sheet
  • External JavaScripts
  • Inline frames
  • Images
  • An Xml data source

We can embed both the style sheet and JavaScript into the head of the main html file itself:

<html>
<
head
>
<
title>Security Rightstitle>


<Style>
.TableHeader
{
    font-weight: bold;
    background-color: #FFFFCC;   
}
Style>


<script language=javascript>

script>


head>
<
body>

We can imitate some features of inline frames via CSS by scrolling inline tables.

If you're already automatically generating the report, then you've already essentially split data from presentation and therefore you can also hardcode the data directly into the Html itself.

That leaves us with Images - which I'm not sure of any way to embed images into an Html file.

However all in all, having the option of putting your styles, scripts, inline frames, and data all into a single file may make it easier to manange for internal reports.