By David, on August 19th, 2009
From Using batch parameters [microsoft.com]:
Cmd.exe provides the batch parameter expansion variables %0 through %9. When you use batch parameters in a batch file, %0 is replaced by the batch file name, and %1 through %9 are replaced by the corresponding arguments that you type at the command line
These batch parameter modifiers variable arguments are immensely useful.
That document is missing some examples, so I’ve put together a simple table:
|
%1
|
Original argument
|
“C:\Users\DMoore\Documents\Document Name.txt”
|
|
%~1
|
Expands %1 and removes any surrounding quotation marks (“”).
|
C:\Users\DMoore\Documents\Document Name.txt
|
|
%~f1
|
Expands %1 to a fully qualified path name.
|
C:\Users\DMoore\Documents\Document Name.txt
|
|
%~d1
|
Expands %1 to a drive letter.
|
C:
|
|
%~p1
|
Expands %1 to a path.
|
\Users\DMoore\Documents\
|
|
%~n1
|
Expands %1 to a file name.
|
Document Name
|
|
%~x1
|
Expands %1 to a file extension.
|
.txt
|
|
%~s1
|
Expanded path contains short names only.
|
C:\Users\DMoore\DOCUME~1\DOCUME~1.TXT
|
|
%~a1
|
Expands %1 to file attributes.
|
–a——
|
|
%~t1
|
Expands %1 to date and time of file.
|
19/08/2009 02:53 p.m.
|
|
%~z1
|
Expands %1 to size of file. (bytes)
|
9
|
By David, on June 3rd, 2009
I’ve been writing some unit tests recently that test some multi-threaded functionality.
Typically this involves hooking up some event handlers then waiting for some asynchronous code to fire the event before proceeding with the unit test and assertions.
The ManualResetEvent class (MSDN) seems a good choice for this, and this post has a small example of using it in a unit test:
[Test()]
public void AfterRunAsync()
{
ManualResetEvent manualEvent = new ManualResetEvent(false);
TestTestCase tc = new TestTestCase(1, "", 0, 0);
bool eventFired = false;
tc.RunCompleted +=
delegate(object sender, AsyncCompletedEventArgs e) {
Assert.IsInstanceOfType(typeof (TestTestCase), sender, "sender is TestCase");
bool passed = tc.Passed;
string output = tc.Output;
eventFired = true;
manualEvent.Set();
};
tc.RunAsync();
manualEvent.WaitOne(500, false);
Assert.IsTrue(eventFired, "RunCompleted fired");
}
By David, on May 28th, 2009
This details how you can debug an application running on a remote machine from Visual Studio on your local machine, as if the remote application was running on your local machine.
The keys are:
- There must be a user account with the same username and password on the remote machine and the local machine (MACHINE account, not domain account).
- Visual Studio 2008 Remote Debugger must be installed and running on the remote machine under the user account in point 1
Create local machine account
- Right click My Computer > Manage
- Expand Computer Management > System Tools > Local Users and Groups
- Right-click Users under Local Users and Groups and choose New User…
- Enter in the username e.g. DebugUser
- Enter and confirm the password
- Un-check “User must change password at next login” and tick “Password never expire”
- Click Create
- Click Close
Create remote machine account
- Log on to the remote machine and repeat the steps for “Create local machine account”
- You must use the same username and password
- Find the user in the Users list and double-click to edit them
- Go to the Member Of tab
- Click Add…
- Type in Administrators and hit Enter or click OK
- Click OK
Run Visual Studio 2008 Remote Debugger
You have several options for launching the Remote Debugger.
- If you install Visual Studio 2008, the Remote Debugger folder can be found in %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE. In the Remote Debugger folder are separate folders for the x86 and x64 versions. Perhaps the easiest solution is to share this folder over the network, allowing you to launch the debugger over the network without having to install anything on the remote machine.
- Alternatively, you can find the Remote Debugger setup on the first disc for the Visual Studio 2008 setup, in a sub folder called Remote Debugger.
- Or, you can download it from here
It’s a good idea to run this as a Windows application as recommended by the Visual Studio 2008 Remote Debugger Configuration Wizard (and in my opinion easier to troubleshoot).
At this point if you’re not logged in as the new user you created, you might want to do that now so that you can run the Remote Debugger under them.
Once you’ve followed instructions for installing, run the remote debugger if it isn’t already by going to Start > Programs > Microsoft Visual Studio 2008 > Visual Studio Tools > Visual Studio 2008 Remote Debugger.
It should say that it’s running an instance similar to DebugUser@RemoteMachineName
Connect to the remote machine with Visual Studio
- In Visual Studio on your local machine, go to Debug > Attach to process…
- Make sure the Transport drop-down at the top is set to Default
- In Qualifier, type in the name of the Remote Debugger instance e.g. DebugUser@RemoteMachineName and hit Enter
- You should then see the list of remote processes in the list and can select the one you want and click Attach.
By David, on May 26th, 2009
In some of the work I’m doing right now, I’m manipulating an assembly after compile time – having it disassembled into IL, tweaked, then re-compiled back into an assembly.
The assembly is signed and what is being done to the assembly is breaking the strong name. This is quite comforting to know; the strong name wouldn’t be so strong if it was that easy to hack an assembly with a strong name.
When trying to load the hacked assembly, I am getting an exception (FileLoadException in this case but I’m guessing this may differ depending on your assembly load method) with the message “Could not load file or assembly ‘MyAssemblyName’ or one of its dependencies. Strong name validation failed.”.
The first interesting thing here is that the assembly named in the error message isn’t the hacked assembly; the hacked assembly is one of MyAssemblyName’s dependencies and is what’s triggering the error.
Make sure that you check the dependencies of the assembly named in the exception message when troubleshooting. The problem may be with one of the dependencies.
In my case the exception isn’t a surprise because of what’s being done to the assembly. But until I resolve that, how can I get around this for now?
You can exclude an assembly from strong name validation for development purposes using the Microsoft (R) .NET Framework Strong Name Utility tool aka sn.exe:
"%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\bin\sn.exe" -Vr "C:\Path\To\Assembly.dll"
Make sure you change the sn.exe path depending on which version of the .NET Framework SDK you have installed. If you’re having trouble, get into the ”%ProgramFiles%\Microsoft SDKs\Windows” dir and search for sn.exe, and use the newest one you can find.
You might find it handy to add this as a Post-build event command-line for your project from within Visual Studio in Project Properties > Build Events:
"%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\bin\sn.exe" -Vr "$(TargetPath)"
So how do you switch the strong name validation back on for your assembly?
Use the -Vu switch:
"%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\bin\sn.exe" -Vu "C:\Path\To\Assembly.dll"
By David, on May 22nd, 2009
If you have several applications that are using NLog, it can be a good idea to install NLog into the GAC and reference that.
A gotcha you must watch out for is caused by this piece of configuration from the NLog site:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog>
</nlog>
</configuration>
Because you are not using the strong name for the Assembly-qualified name of ConfigSectionHandler, it’s impossible to do a GAC lookup, therefore NLog won’t be found and you’ll get an application error (even if NLog is actually in the GAC).
This means your application will throw an exception when the configuration is loaded; there will be no NLog.dll in your application folder and it can’t check the GAC as it doesn’t have the strong name of the assembly you want.
You can fix this by including the strong name:
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog, Version=1.0.0.505, Culture=neutral, PublicKeyToken=5120e14c03d0593c" />
By David, on May 21st, 2009
I’ve been getting this error a bit lately as I trying to add new projects to the solution, and then add them to source control:
The project <ProjectName> cannot be added to source control. In folder <SolutionDir>, it overlaps a project that is already bound to source control at a lower root. To avoid this problem, add the project from a location below the binding root of the other source controlled projects in the solution.
The cause of this was that I had linked files within the new project that were pointing to existing files higher up in the solution folder (in this instance, in the solution root).
In this case I was linking to the strong name key from the solution root:
<SolutionRoot>\MyKey.snk
<SolutionRoot>\MyProject\MyProject.csproj <= Was linking to the key in the root
To add the project to source control, you have to remove these links first, add the project to source control, then you can put your links back in.
By David, on February 28th, 2009
A few months ago I posted a little query about finding duplicate rows in a database table. I’m revisiting this because I helped out Doogie with a similar query last night but with some complications.
Let’s start with the original simple scenario of checking duplicates in a single column.
Some example data, a Users table:
+----+----------------+
| Id | Email |
+----+----------------+
| 1 | joe@bloggs.com |
| 2 | joe@bloggs.com |
| 3 | joe@bloggs.com |
| 4 | jane@doe.com |
| 5 | jane@doe.com |
| 6 | john@doe.com |
+----+----------------+
You can see that joe@bloggs.com and jane@doe.com have been duplicated. This could have been prevented by putting a unique index on the Email column.
So to find what emails have duplicates in our table:
Continue reading Finding duplicated data across one or more columns in a database table
By David, on February 7th, 2009
Most thumbnail-generation solutions will shrink the original down while maintaining aspect ratio.
Usually you specify the maximum height and width of the thumbnail, e.g. 150 x 200.
However, if your original image’s aspect ratio is different to the maximum thumbnail dimensions, you will end up with dead space vertically or horizontally (shown in green in the illustration). This can be quite an eyesore when displaying thumbnails in a grid.

I’ve got an algorithm that will automatically crop the image either horizontally or vertically to then match the thumbnail aspect ratio, so you end up with the thumbnails all being the same size even though they may be coming from originals of wildly different aspect ratio.
In the illustration, you can see that the image is scaled down and fills all the available thumbnail space, showing the parts in grey from the original that were cropped out.

The algorithm does the cropping before the resizing. It takes the width and height of the original image, and the width and height of the desired thumbnail. It will return the width and height that the original must be cropped to, to match the aspect ratio of the thumbnail. Continue reading Creating thumbnail images with automatic cropping and maintaining aspect ratio
By David, on January 17th, 2009
Today I’m working on a .NET hobby project.
At a simple level, I’m writing a web proxy implementation, and was using 8080 as the default port.
When trying to write and run unit tests to make sure my server was binding to this port and shutting down as and when expected, I found I could connect to 8080 even when the proxy wasn’t running. Telnet-ing to that port would initiate a connection, and would eventually drop out at varying speeds, and immediately if I hit a key.
I could see nothing in netstat, and I got to the point of shutting down all programs and services I could and it still happened.
I loaded up TCPView and watched it, and saw that an ekrn.exe was doing stuff when I tried to telnet to port 8080. This is the ESET Service, part of ESET NOD32 Antivirus. I had already tried disabling NOD32 Antivirus while troubleshooting, but I went and inspected the options, and sure enough I saw this:

To get the above options window, you need to open the main NOD32 window, click Setup from the left bar and click Enter entire advanced setup tree…
Eureka! NOD32 sits there and quietly intercepts web requests to the usual web and proxy ports, so that it can appear that there are actually programs listening on those ports when there aren’t. Even when you’ve disabled the Web Access Protection and Real-time protection.
So now my options are to choose a new default port for my proxy, or disable 8080 in the NOD32 HTTP options.
By David, on January 8th, 2009
Hamilton has applied a bunch of patches and fixes to the Castle Project for the Components and Windsor sub-projects. Including 2 minor and insignificant patches that I submitted +D. It’s good to feel part of a major Open Source project, even for a small contribution.
http://hammett.castleproject.org/?p=336
While I’m currently focusing my efforts on ASP.NET MVC and moved away from MonoRail, I use Castle extensively in my .NET projects, particularly ActiveRecord and Windsor/MicroKernel.
|
|
|