Tuesday, January 19, 2010

image Recently, I ran into a need to make use of the Mono.Cecil.dll library from a .net application I was working on. Cecil is a fantastic little project under the Mono project that allows you to interrogate an existing .net assembly (EXE or DLL file) and retrieve all kinds of information about the assembly, from the resources embedded within it to the classes and methods defined, and much more. You can even alter the contents of the assembly and write the new version back out to disk!

The thing is, Cecil comes prebuilt as a C# assembly (a DLL file), and I really did not want to have a second file required for this particular application (it’s just a little command line utility).

My first take was to use Oren Eini’s excellent concept of an assembly locator. My idea here was to embed an assembly as a binary resource, then, when requested, read that resource into a stream, load the assembly from the stream, and resolve references to it via the assembly locator.

I’m still working on that concept, because I think it’s a clever and convenient solution to the problem, but, in researching that, I happened to remember the even easier (as in, no code required at all!) solution of using ILMerge.

ILMerge

If you haven’t already discovered it, ILMerge is a Microsoft research project in the form of a single command line EXE utility, that can “merge” any number of .net assemblies with a “target” assembly, and produce either a .net DLL or EXE output file.

There’s a really good article on CodeProject describing the general use of the program. There’s even a GUI (Gilma) for it.

Automating ILMerge

What the article doesn’t go into is automating the ILMerge process. After all, you won’t want to manually run that command line utility every time you build your application!

The good thing is, it’s trivially easy to automate as long as you take care of one critical step.

  • First, download and install ILMerge from the link above.
  • Once it’s installed be sure to copy the ILMerge.exe utility to somewhere on your path (or add the folder it’s in to your path).
  • Then, grab the Mono.Cecil.dll file (or whatever DLL it is you want to merge into your main project EXE). Put it in the root folder of your project.
  • Go ahead and set a reference to that file, so you still get all the .net intellisense goodness, but be sure to set the Copy Local property for the reference to FALSE (after all, you don’t want to copy this DLL to the output folder along with the application if you don’t actually need it, right?)

    image

  • With that done, you MAY want to mark the DLL you’re embedding as “included in project” from the Solution Explorer.

image If you do this, however, make sure you also set the Copy to Output Folder to “Do not copy” (that’s the default though so it should already be set).

The Tricky Part

One limitation of ILMerge is it that it can’t alter the target assembly “in place”. This means that, for instance, if you want the final resulting executable file name to be called GenerateLineMap (my utility), you can’t have VS compile the assembly to that name. You’ll need to use some other name for the initially compiled assembly.

On the Application tab of the project properties you can change that name, like so:

image

I just added “-Interim” to the Assembly Name.

Now, go to the compile tab of the project properties and click Build Events

image

Insert this as the POST BUILD EVENT

ilmerge /target:winexe /out:"$(TargetDir)$(ProjectName)$(TargetExt)" "$(TargetPath)" "$(ProjectDir)Mono.Cecil.dll"

Notice that the OUT parameter specifies the output file name via the $(ProjectName) variable (which is still “GenerateLineMap”) while the first assembly to merge is specified using the $(TargetPath) variable (which is the full filename of the output assembly, including the “-Interim”).

image

EDIT: Important note: Notice the /target:winexe option. You’ll need to change that as appropriate depending on the type of exe you’re building. In my case, I had a console app where this needed to be set to just /target:exe. Setting it to /target:winexe caused all of the console output functions to just do nothing, which threw me for a bit!

Now, just rebuild the solution and you should see two resulting EXE files in your output folder, one with the “–Interim” (which is the version WITHOUT the embedded Mono.Cecil.DLL file or whatever DLL you’ve chosen) and one WITH the embedded file. As a final cleanup, you may want to add an additional Post build step to remove the “*-Interim” files.

To test, just make sure you DO NOT have the embedded DLL anywhere on the path or in the same folder as the exe and run the exe. If everything went right, your app should work exactly the same as if the embedded DLL was included externally with the app!

Now, your application is back to being a single EXE to distribute, and it was built completely automatically by Visual Studio.

Caveats

You knew there had to be some, right?

The first is that if the dll to embed contains licensing information, it might not work properly after being embedded. I don’t have any DLLs like that to test with, but I’ve read reports about the problem at various sites on the internet. Just something to be aware of.

Second, trying to replace the originally named exe with the newly built one results in VS not being able to debug the exe in the IDE (it throws a message about the assembly manifest being different from what was expected). I haven’t worked that issue out yet. What this means is that you might need to leave any references set to “Copy to Output Folder” while debugging, and not replace the original compiled assembly, just ILMerge it into a new assembly name.

posted on Tuesday, January 19, 2010 12:54:37 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, December 09, 2009

I’ve just finished paving my main machine with Windows 7 64 bit, and was working on tidying up some of the finer points of my installation.

One minor item I use is a batch file with a reference to the excellent Poweroff utility. The batch file basically powers down the monitor, locks the machine, then goes into standby/hibernate mode. I attach it to a Ctrl-f11 hotkey to make it a quick keystroke to powerdown my machine.

Anyway, I have that bat on my path, and I happen to keep it out on a network drive (a NAS array), not on my local machine. I generally keep data off my local machine, preferring to only have program installs and temp files locally.

But when I pointed my shortcut to the network path and hit Ctrl-F11, I’d get that annoying “The publisher could not be verified” prompt. Every time!

Well, a few googles later and I came across this tip on annoyances.com.

It’s for Vista, but it also works in Win 7 (even the 64bit version).

Run gpedit.msc Go to User Configuration >> Administrative Templates >> Windows Components >> Attachment Manager Add "*.exe; *.bat" to the "Inclusion list for moderate risk file types" setting.

I added *.bat to the list, as well as *.exe because, in my case, I keep a number of handy BAT files in folders out on my network drives and then include those folders in my path.

Works a treat. Be sure to read up on why to include this in the Moderate risk element and not the High Risk, though. Generally, if you have a reasonably good firewall/router, making this change should be safe.

posted on Wednesday, December 09, 2009 6:25:15 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, December 17, 2008

I've looked for a long time for a decent Explorer replacement. You know, what once was called a "File Manager".

Funny how that entire class of application seems rarer now than a graft-free politicians office. The built in Windows Explorer is good enough for most, though it's generally woefully lacking in virtually all aspects that make a good File Manager. This is an area where I actually have real commercial experience, too. I wrote the Windows version of the venerable WindowDos file manager in another lifetime. It's actually still up, though I don't believe it's really being sold anymore. And that was back in the days of WFW3.11, and Win95, when 8.3 names were still very much in-yo-face, and NT was this weird OS that nobody had the hardware for. OS2 was a much better choice\:\-\) .

Anyway, I've checked out a number of them over the years, including Directory Opus (very good, but $$$$), XYPlorer, Explorer2, Total Commander, and plenty of others, but, with the exception of Directory Opus (Dopus to those in the know), they all came up short for me.

But I recently came across AccelMan, by FlexigenSoft.image

Wow. Very cool, highly customizable, fast, nice and "keyboardy" for those that like to leave the mouse behind when browsing.

It does multiple pane browsing (and not just your Commander-style 2 pane, oh no, you can pile 'em on baby!), has a built in file viewer, hex viewer, graphic viewer, plus a command line and console view, customizable filters (show all Document files, or VB Source files, or Graphics files, for instance), and easy to edit bookmarks (files and folders). It's its own app, so it's not an Explorer addin, nor does it attempt to replace the built in Explorer, and as far as I can tell, it doesn't muck with your system, at least not much.

But the best part? They've decided to make it freeware. When you download, be sure to grab a license key (it's right there on the same download page). Then, after installing, register the app with the key and you're set.

Just to be fair though, the app isn't perfect. I've noticed a few crashes when mucking with some of the more esoteric customization features, and there are several things I wish they'd do different, as well a few features I'd love to see. Given the freeware nature of the product, who knows if there's updates in the offing, though it appears to have been updated as late as June of this year.

That said, the basic functionality appears quite stable (so far anyway) and you can't beat the feature/price ratio!

(UPDATE 12/20/08) I've submitted a number of comments to Flexigensoft about AccelMan, but to date, haven't received any response. Granted, it's the holiday season, so I'll definitely give them that.

AccelMan is a product I'd +really+ like to see continue, even if just to get a few minor fixes in. Hell, I'd be happy to pay their original posted price if they'd get back to me about whether there will be any updates in the near future.

At this point, the biggest issues with the app that I've seen are:

  1. Inconsistent startup. Sometimes, it'll start right up. Sometimes, you click to start it and nothing appears to happen. A quick look at taskman reveals that the app started and is running "hidden". Kill that process and start it again, and, so far, anyway, it always starts up properly then. This is probably why I've seen more than a few posts about the 3.5 version simply "Not working" on people's machines. I'm guessing it's some internal window positioning code that's wack. Can't be too tough a fix.
  2. Even more bothersome is that if you copy files, delete folders, create new folders, etc etc, the Tree/File List isn't immediately updated. I can replicate this behavior consistently, and it's unbelievably annoying<sigh>.
  3. No command line parameters. Minor issue, but it sure would be nice to create shortcuts on the desktop to start in a particular folder, or with a file highlighted, but there is no support for that. Even Explorer can do this!

Bottom line: AccelMan is still definitely usable, but the above glitches are enough to make me think twice about moving to it completely as my FileManager of choice, which is terribly unfortunate.

posted on Wednesday, December 17, 2008 11:01:28 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Sunday, November 30, 2008

Every once in a while, I've run into the need to send an email via the command line. Often, this is during make scripts, or other long processing batch jobs. I've almost always ended up succumbing to "net send" and being done with it, but that's not an option anymore with Vista. The good ol' (and much maligned) Messenger service is no more under Vista and Server 2008.

So, I need to send an email via command line.

There's piles of little email apps like this floating around, but most don't support TLS, secure sockets or authenticated smtp access, which, for better or worse, is what GMail requires now.

After a good deal of searching, I ended up coming across the very nice (and free), MailSend utility by Muhammad A Muquit.

Sending email from the command line is a simple (albeit a tad long winded) command, all on one line of course:

mailsend -from you@gmail.com -to someone@domain.com +cc +bc -d gmail.com 
    -smtp smtp.gmail.com -v -starttls -auth-plain -user you@gmail.com -pass "yourpassword" 
    -sub "Test Subject" -M "This is the body of a test message"

Quite handy.

posted on Sunday, November 30, 2008 10:03:28 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, July 24, 2008

I've always been a big fan of the MZTools addin for VB6, so it was a little disappointing, if not understandable, that for his .NET foray, he's wanting to get paid a little something for it.

Not that that's bad, I just haven't been able to commit to MZTools for .NET just yet.

In the meantime, I stumbled across a very slick little VS addin called DPack.

It's actually a small set of different addins. Doesn't look like you get the source, which is unfortunate, but the features are pretty slick, plus they work in VB, C++ and even C# and Ruby.

The Code Browser alone is worth the download. With one keystroke, you get a window like this:

image

It's nicely sorted, browsable, and with one other click, takes you directly to the given code element. Even better, you can assign direct keystrokes to filter only methods, classes, properties, etc. By default, ALT-M shows just the methods in the current file, for instance. Reminds me of the old F2 (Function list) key that used to be in older VB's. I missed that key<sob>.

Also particularly nice is the "Surround Selection With..." feature. You can't customize the surrounding text but they give you the most common items (surround with TRY CATCH, FOR NEXT, DO WHILE, REGION, etc, etc.), so that's not too bad.

It seems very quick and stable. And the best part is, it's completely free!

posted on Thursday, July 24, 2008 9:46:10 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, March 13, 2008

If you use FireFox (and if not, what's up with that), you need to check out Chuck Baker's FireFox Environment Backup Utility (FEBE).

Slick little tool for saving all your FireFox goodness for that day when, suddenly, you realize you'll be paving your machine and having to dig through your subconscious to come up with all those bookmarks, RSS feeds and FireFox extensions that you use everyday but couldn't name to save your ass.

posted on Thursday, March 13, 2008 8:36:33 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, July 24, 2007

I've noticed over that past few weeks of running Vista that certain things tend to be A LOT slower now, even given the fact that I recently picked up a gigabit network card for my server, and a gigabit switch, so I could make use of the built-in gigabit network adapter on my new workstation motherboard.

For instance, I use a program called VBLiner to line number all my VB source right before I compile it. The line numbering process itself is very fast, but the program would pause, noticeably, for each file it opened. It was almost as if the process of locating and opening the file was slow, but actually reading it was very fast.

Today, it finally got to be too much, so I had to start digging.

Come to find out, Vista has this nifty new thing called "Network Autotuning" that, apparently, doesn't work particularly well.

You can see it yourself by opening a DOS box (with Admin priviledges), and entering

NETSH INTERFACE TCP SHOW GLOBAL

You should end up seeing something like this:

image

That "normal" is the problem.

Execute this to turn off autotuning:

NETSH INTERFACE TCP SET GLOBAL AUTOTUNINGLEVEL=disabled

turn it back on with

NETSH INTERFACE TCP SET GLOBAL AUTOTUNINGLEVEL=normal

and, apparently, using this will sometimes work, too, though I'm a bit hesitant to bother at this point.

NETSH INTERFACE TCP SET GLOBAL AUTOTUNINGLEVEL=HIGH

Nothing like a built-in network performance de-tuner.  It's STRESS.EXE but without all the hassles of actually having to run a utility. Grrr.

posted on Tuesday, July 24, 2007 5:49:10 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, July 19, 2007

With the success I had with getting a bootable image of MFSTools onto my old 1GB USB stick, why not go all out.

My local Fry's has on sale Sony MicroVault USB sticks with a slide out connector.

image

I picked up a 4GB model for 37$ and am thinking a multi-boot setup with multiple partitions.

  • MFSTools, for all my Tivo adventures.
  • DOS6.2 with all my various boot tools, SpinRite, etc.
  • Ultimate Boot Disk, with various OpenSource DOS's, plus some Linux stuff to, I believe.
  • A BartPE Windows XP boot partition.

Anything else that might seem useful?

Niceties about the USB boot disk option:

  • It's fast
  • You don't have a reburn a DVD to make a change to the configuration
  • The sizes are to a point now as to be actually useful

I probably won't toss my trusty DOS 6.2 boot floppies just yet, 'cause some of my machines can't boot to USB, but I suspect that will be changing over the next year or so.

posted on Thursday, July 19, 2007 8:01:24 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [6] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, July 14, 2007

I needed to format a 120GB disk to FAT32 to run a few trial runs with MFSTOOLS for upgrading a TIVO unit with a bigger harddisk. You'll also run into this, though, if you need to format a USB key, or removable harddisk as FAT32 (so it would be compatible with Linux or a Mac).

You can't format at drive/partition with FAT32 format greater than 32GB under Vista.

Microsoft has apparently just put an arbitrary limit in the formatting routines.

Not only that, you can't format FAT32 at all via the GUI, as far as I can tell. The drop down list for format type only shows NTFS.

You CAN format in FAT32 by opening a command prompt as administrator and running

Format {drive} /FS:FAT32

But that's still limited to 32GB partitions.

I did find a couple of solutions, though.

The first is a freeware command line utility from RidgeCrop Consultants called fat32format.

The second is a GUI utility (but that's putting it nicely) called Flash HD to GO!, for formatting USB keys, but it appears to work with any media.

They both seem to work just fine under Vista for formatting an actual harddisk (in my case a 120GB Seagate).

I will admit though, the Flash HD to Go utility can be a little nerve wracking to run, with it's decidedly sparse UI and limited warnings and information about the drive that's about to go bye bye.

posted on Saturday, July 14, 2007 6:23:35 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, July 11, 2007

Maybe I'm jumping on the band wagon a bit late with this one, but it's pretty slick if your machine's BIOS will support it.

It IS actually possible to write a boot sector and boot files to those little 256mb+ USB keys that you can get in the gumball machine down at just about any local soda fountain or 10 cent store these days.

Why would you want to?

  • They boot a LOT faster than CD or DVD
  • They're rewritable without any special considerations.
  • You don't have to have special burner software to update them (other than what's required to lay down a boot sector).
  • You don't have to suck up an EIDE channel just to be able to hook up a CD to boot to.

It was that last part that hooked me. I'm in the process of upgrading a TIVO to 320GB and my shiny new iron only has 1 EIDE port (and 2 channels). One to the old TIVO drive, one with the new drive and, bang, nothing to boot to (You don't want to boot to Windows with your TIVO drive attached, Windows like to stamp any drives that it can see, which can screw your TIVO drive all to hell).

With a bootable USB key with MFSTools on it, I can boot to the USB, and still have both the HD's connected to copy and back up between them.

I know, I know. Grab an old machine with 2 IDE ports and my problem was solved. Well, the only old machine I have left is way, way old, and it's bios doesn't even recognize the 320gb drive I'm using to upgrade. The other, not so old machine, is just waiting to be hauled to the hazardous waste site, cause it won't even give up a POST BEEP.

To get DOS or windows on the disk, you'll need to format the USB Key with a boot sector. The easiest way I found to do that is this HP utility. It should let you format the drive and copy the boot sector over from a boot floppy. Once that's done, you should be able to grab a copy of BARTPE and build up a fully USB KEY bootable copy of Windows XP, assuming you have a bootable CD of Windows XP. Well, it ain't a "full" Windows XP but it'll get you loaded and able to grab info of an otherwise unbootable drive.

To get Linux working, you gotta go deep. You'll have to use SYSLINUX, and/or ISOLINUX to overwrite the DOS boot sector with a LINUX boot sector.

To get MFSTools working on the resultant LINUX USB key, you'll need to get the ISO first. Mount it using something that'll mount ISO images, like Elaborate Byte's free and excellent Virtual Clone Drive. Then copy the whole thing down to the USB key. This won't copy the boot sector, though. That's what SYSLINUX was for.

Still won't quite work though. You have to copy the contents of the ISOLINUX folder down to the root of the USB key. Then Rename ISOLINUX.CFG to SYSLINUX.CFG. That'll allow the ISOLINUX image to boot to a ram drive like it does normally when booted from CD (at least, that's the way I understand it, knowing what I know about Linux at this point).

If all that's done right, and assuming that your machine supports booting from USB, and assuming you've configured the BIOS to allow it, reboot and feel the joy.

If it doesn't work, take two aspirin, reboot and... be thankful Windows doesn't require this sort of nonsense....???? Ok. I jest.

BartPE is a very interesting possibility because it's relatively easy to build and you can add your own Windows tools to the mix (up to the size of your USB key anyway). Could come in very handy for recovery and forensics work. And USB Keys are more scratch resistant than CD's. Plus, some have that nifty, switchblade action with the USB plug.

image or image

Oh, and one final tidbit for any security oriented people, check this out and see if you get any sleep that night.

posted on Tuesday, July 10, 2007 11:54:23 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, July 04, 2007

I've read a ton of good press about BlogJet and from the demo I looked at it's pretty slick. But BlogDesk is free and does everything I needed it to, until now.

I have to say, Windows Live Writer is an awfully nice way to write blogs, and it's free as well. It works smashingly with dasBlog, sets up on Vista without a hitch, has a built in spell checker, which myself (and a lot of blog writers out there) need, and can even edit blog entries using the styles cribbed from you blog itself.

Check out this screenshot of Live Writer entering this actual entry.

image

Sweetness. And it pulled the style sheets automatically. It doesn't look exactly  like my blog, but hey, that's pretty good for being editable!

Finally, if you prefer, there's all sorts of effects you can give graphics as you paste them in. I tend towards the simplistic, but there's drop shadows, overlays, transforms, etc to play with.

UPDATE: Well, Live Writer is nice, but it's definitely still beta. With lots of images, it seems to crash when loading drafts to continue editing. But it works well enough for image-light pages, so your mileage may vary.

posted on Wednesday, July 04, 2007 5:00:52 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Monday, June 25, 2007

I'm now in full rebuild mode after last weeks unfortunate RAID incident.

After installing Citrix Desktop and setting all my parms back up, I got

“The desktop you are trying to open is currently available only to administrators. Contact your administrator to confirm that the correct settings are in place for your client connection.”

After some digging around, I came across this Citrix posting that was exactly the problem.

I had the Citrix Connection set to "Server", it needs to be "Published Application".

Too bad the error message itself didn't actually mention that. But it's hard to find too much fault in that.

 

posted on Monday, June 25, 2007 7:36:08 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [3] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, June 15, 2007

I've recently read several blogs about how great Windows PowerShell is, so I decided to check it out myself last night.

I didn't get very far before I came across this on the download page:

"The .NET Framework 2.0 is required in order to install Windows PowerShell"

Ok, fair enough.

And then I proceeded to actually check out the download page, where they present no fewer than 20 different download options, including variants for "English" and "localized", x86 and x64, plus Itanium.

First, I know from experience that it would be almost insane to suggest that small development shops try to maintain 20 different downloads of what is essentially the same product. MS can get away with this because they've got lots of money to throw at the problem, but is 20 different downloads of a command shell utility really justified? Ok, some of them are for some MultiLingual UI addon, so the total versions of the utility iself is fewer than that, but not by much.

The bigger issue I have here, though, is that I thought, and MS would surely have everyone believe, that the .NET runtime and the JIT compiler within should automatically be handling the differences between x86, x64 and Itanium. That's the whole point of the JIT, right? The multilanguage versions? I can accept them, with reservations, but the different processor versions? I'm no expert on the PowerShell internals, but if it requires the .NET framework, that would seem to imply that it's managed code, which would imply that the JIT should take care of the differences between platforms. And if it's not managed code, why not? Is it that MS is saying that managed code is good enough for everyone else, but not good enough for them?

Reminds me of the discovery I made ages ago that Outlook communicates with Exchange via RPC, not via DCOM, even though DCOM was being pushed hard by Microsoft at the time. Another case of "good for you, not good enough for us", perhaps?

Oh, and PowerShell looks like a very handy tool for Administrators. I'm sure I'll find some uses for it eventually. But, get-childitems -path env: just to retrieve the current environment vars? There's something to be said for mapping all sorts of various available info like that into a consistent interface, but my stack's too deep as it is right now to pile this syntax on top just yet.

posted on Friday, June 15, 2007 1:07:00 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, June 06, 2007

I've been experimenting a lot lately with Apophysis for fractal generation, and one thing that bugs me is that when actually running a render, the program still runs at normal priority. Which means that even on a very fast dual core Core2 processor, my system just drags.

It's easy enough to remedy; just use taskman to set the Apophysis Process to below normal priority. The render still runs full speed if you aren't doing anything else on the machine, but it takes a backseat to anything else going on.

I've used this trick before for many purposes (Terragen, anyone!), and even used it within a Service process I wrote once. The service was fully multithreaded, and each thread adjusted it's priority based on what it was doing.

Well, the frustration got a little much last night so I started looking for something that would automatically recognize processes as they come online and adjust their priority based on predefined settings.

Look no further, Process Priority Optimizerto the rescue. It's a small utility that runs in the tray (what doesn't anymore ;-) ). You can set the preferred priority if a process, save, and then, if that process loads up again, it's priority is automatically adjusted.

UPDATE:

Even better, Ralf pointed me to a program called ProcessTamer. It looks even better than Process Priority Optimizer, because it will automatically adjust the priority of processes that are running hot, no preconfiguration necessary. The latest version also supports specific configurations for particular applications, which is what the Optimizer will do While.

I'm all for apps that handle things transparently (unless, of course, I want to configure it, I'm fickle that way \:\-\) ) , so my money's on ProcessTamer now!

Just don't go setting arbitrary processes to real time! You have been warned\:\-\)

posted on Wednesday, June 06, 2007 10:33:59 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [1] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Sunday, June 03, 2007

I'm finishing up my little Signature Enhancement Utility for Outlook and had finally gotten the Media Center 12 "Currently listening to" functions operational (This is just a minor feature I've seen popular on website blogs and forums, where the tag line contains not only the author's name but what they are currently listening to, if anything, nifty and fun, but not in the least practical).

I figured I'd go ahead and try to support Windows Media Player 11 (and hopefully earlier versions) as well.

Basically, the idea is to grab a reference to the running instance, interrogate it as to the "playing" state and, if it's playing or paused, retrieve the name, album, artist, etc info on the playing track and make it available as replaceable fields in the signature.

With Media Center, it was almost trivial:

Set omc = GetObject(, "MediaJukebox Application")
If not omc is nothing Then
   '---- it's running
   ' if it's not running, they can't be playing any music
   With omc
   Select Case .GetPlayback.State
      Case PLAYSTATE_PAUSED, PLAYSTATE_PLAYING
      '---- Media center info is available
      ps = .GetCurPlaylist.Position
      CurTrackTitle$ = .GetCurPlaylist.GetFile(ps).Name
      etc...

Obviously, if the GETOBJECT fails to return anything, Media Center isn't currently running so the user can't be listening to anything.

Three hours of Googling later, plus tons of experimentation and I'm not even an inch closer to getting this working for Media Player.

Using ROTView(the Running Object Table viewer, comes with various installations of Visual Studio), it does appear that WMP registers "something" with the ROT, which I'd think would be accessible by VB's GetObject().

Alas, "Windows Media Player", "WindowsMediaPlayer", "MediaPlayer.MediaPlayer", and on and on, all came up empty.

I scoured the registry for anything that even remotely looked like the moniker of a WMP registration with the ROT and everything I tried also came up empty. I'm sure it's another case of knowing the magic password, but so far, it appears to be a tad more involved than Speak, friend, and enter.

So, for now, looks like I'll have to rely on the FunPack for support of a limited set of attributes of the currently playing song in WMP. Apparently, for ITunes, you can use this plugin to accomplish the same thing, though I don't use ITunes and probably won't bother with testing that.

If anyone's ever had any success with accessing the running instance of Media Player, I'd love to hear about it!

posted on Sunday, June 03, 2007 8:16:07 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [9] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, May 30, 2007

In case you've missed the first 2 posts in this series, I'm discussing the concept of using Resouce files with Visual Basic 6.

In the first part, I talked about how to compile arbitrary information into a resource file and reference it from VB.

In Part 2, I discussed a technique for compiling a VersionInfo resource and writing it into your VB executable, thus replacing the incomplete VB provided VersionInfo resource.

In this installment, I wanted to share a little trick for defining the elements of the "Version number" in a resource (RC) file such that you only have to enter the version number once.

If you recall, I presented a sample RC file the last time, looking like this:

1 VERSIONINFO
FILEVERSION 1,2,3,4
PRODUCTVERSION 1,2,3,4
FILEOS 0x4
FILETYPE 0x1 //// 2 for dll, 1 for exe
{
BLOCK "StringFileInfo"
{
BLOCK "000004b0"
{
VALUE "CompanyName", "MyCompany"
VALUE "ProductName", "MyProduct"
VALUE "FileDescription", "MyFileDesc"
VALUE "LegalCopyright", "MyLegalCopyright"
VALUE "LegalTrademarks", "MyLegalTrademark"
VALUE "OriginalFilename", "MyOriginalFilename"
VALUE "ProductVersion", "1.2.3.4"
VALUE "FileVersion", "1.2.3.4"
VALUE "Comments", "MyComments"
VALUE "InternalName", "MyInternalName"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0000 0x04B0
}
}

If you'll notice, there is one thing about this script that no lazy programmer worth a macro recorder would tolerate. The Version Number is duplicated several times, and what's worse, in several different formats.

First, we have the FILEVERSION and PRODUCTVERSION entries, with comma separated numbers.

But then we also have the stringized version of those two elements, that must be specified as period separated elements within quotes.

I don't have an alcohol fueled Code Sync 5000 robot to keep those numbers straight so I figured I'd just use macro substitution. Right. Turns out, the Resource compiler (RC.EXE) is a mighty fickel beast.

What I envisioned was a simple block to define the version number:

#define MAJOR          1
#define MINOR          0
#define REVISION       0
#define BUILD          116

and then use those definitions further down in the file, like so

FILEVERSION MAJOR,MINOR,REVISION,BUILD

and similiarly

VALUE "ProductVersion", "MAJOR.MINOR.REVISION.BUILD"

But obviously, there's a problem; actually, more than just one.

I won't dwell on the details, but after much head scratching (polite euphimism), I ended up with this joyous concoction:

#define COMMAVER(mj,mn,rv,bl)        mj,##mn,##rv,##bl
// Commaver yields x,y,z,a  (necessary for the numeric versions)

#define PERIODVERPT2( mj )           #mj ""
#define PERIODVERPT3( mj,mn,rv,bl )  PERIODVERPT2( mj ) "." PERIODVERPT2( mn ) "." PERIODVERPT2( rv ) "." PERIODVERPT2( bl )
#define PERIODVER                    PERIODVERPT3( MAJOR,MINOR,REVISION,BUILD )
// PeriodVer yields x.y.z.a (necessary for the stringized versions)

// define the two numeric versions
// always make them the same                    
#define FILEVER        COMMAVER(MAJOR,MINOR,REVISION,BUILD)
#define PRODUCTVER     FILEVER

// define the two stringized version numbers, we just make them the same
#define STRFILEVER     PERIODVER
#define STRPRODUCTVER  PERIODVER

Then you can use them like so

....
FILEVERSION FILEVER
PRODUCTVERSION PRODUCTVER
....
VALUE "ProductVersion", STRPRODUCTVER
VALUE "FileVersion", STRFILEVER

Get clever with the #include directive and you can easily keep the version numbers of all the separately compiled VB components of your project synchronized and only have to set the version number in a single place.

If there's a simpler way, I'd love to hear about it. But this works, and it keeps all my version numbers straight.

posted on Wednesday, May 30, 2007 7:33:03 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [1] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, May 29, 2007

How about a little fun?

I use batch files, make files, etc. to automate build processes quite often, but they can generate output that is, well, so very boring.

Why not liven it up a bit with FIGlets! This is some seriously old school tech, but it's quite a nice effect if used in moderation.

Instead of just printing:

Build Starting...

in your output, how about:

      ____          __    ___ _____ __
     / __ )__ __(_)/ /___/ / / ___// /_____ ______/ /_(_)___  ____ 
    / __ // / / / / / __/ /\__ \ / __/ __ `/ ___/  __/ / __ \/ __ `
   / /_/ / /_/ / / / /_/ / ___/ / /_/ /_/ / /   / /_/ / / / / /_/ / _ _
  /_____/\__,_/_/_/\__,_/ /____/\__/\__,_/_/\__/_/_/ /_/ /_ \__, (_/_/_)
                                                           /____/

Makes it much more obvious when things have started or finished.

To generate one-off text snippets like this, go to The Ascii Generator.

or, for real flexibility, just download the original FIGlet command line utility. Be sure to get all the various fonts. Personally, I like the SLANT font the best (the example above is in SLANT).

Then you can just use:

FIGlet -f slant "Build Starting..."
....
FIGlet -f slant "Build Finished..."

in your batch files for some real early 90's chic!

posted on Tuesday, May 29, 2007 9:01:15 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, May 23, 2007

I've seen lots of rants over the years saying things along the lines of

Who wants to use a language that looks like this:

10   Print "Hello, World"
20   If x = 1 Then Goto 50
30   Print "Something else"
50   Print "Result was 50"

Or similiar nonsense. Of course, VB only vaguely resembles this style of code anymore, but one thing has remained virtually the same. Line numbers.

If I remember correctly, in BASCOM and BASICA, they were required. Then Basic Professional Developer System (MS BasicPDS) came out and line nums were no longer necessary, but you could still use them if you liked (probably more to be backwardly compatible with all that old BASICA code).

In all the older VBs (pre .NET days), you actually had to add line numbers to the source code itself in order to get them into the program and refer to them (via the ERL function). While this was certainly doable, the resultant code ended up looking like some seriously old-school mash you wouldn't want to be caught dead delivering (or trying to maintain).

However, being able to report a line number during an error at runtime, at the client site, so it can be logged or reported back to you as a developer is damn near invaluable. Microsoft recognized this enough in .NET to include line number support built in to the error stack and handling subsystem (although the old style line numbers in code and ERL function still work, appearently).

That's great for .NET, but there's still a lot of VB6/5 and older code laying around that has to be maintained. So what do you do?

Ages ago, I built a little command line utility to run through every module in a VBP file (and every module of every project in a VBG file, too), and either add or remove line numbers. It output all the files to the same directory, but with "LINED_" prepended to the file name. This tactic makes it very easy to simply DEL LINED_*.* when you've compiled the line numbered project to clean things up and not leave line numbered code sitting around. You can run it against individual BAS, FRM, CTL, DSR, CLS, etc files, but if you point it at a VBP or a VBG file, it'll even rewrite that file so that it's contents point to the new file names. This makes it very easy to construct a batch file to 1) line number a project, 2) compile it, and 3) kill off the line numbered source files.

For instance, this batch file:

set pfile=%~dpn0
set pname=%~n0
set pdir=%~dp0
vbliner %pfile%.vbp
VB6.EXE /m "%pdir%LINED_%pname%.vbp"
del "%pdir%LINED_*.*"

Just name it the same name as a VBP file, save it to the same folder as your VBP file, and run it.

It will pull the file name and path from the name of the batch file itself (which should be the same as the VBP you want to compile), line number the project, compile it, then delete the line numbered source files when fnished, leaving you with a nice compiled file, completely line numbered but with none of the mess.

Its other nifty trick is to line number the lines using the same algorithm that the VB6 IDE uses to display line numbers as you move through code, as in:

This one trick (which I haven't seen in any utility to line number VB source), makes it so that you don't have to keep the line numbered source around so you can refer to it later. Somebody calls up saying they get an error in Module XYZ, line number 10202, all you have to do is pull that version of the module from SourceSafe (you do use version control of some kind, right?), load it up in VB and jump to the given line number. Can't get much simpler.

VBLiner starts numbering at 10000, the rational behind that being that if you happen to need to include a hardcoded line number in your code for some reason, the automatic numbers hopefully won't interfer with your hand coded numbers.

Another handy tip. Once you've opened your VB project, Right click the project explorer, select ADD, then ADD FILE. Find the BAT file that you just created above, and be sure and check the "Add as Related Document" box before adding it to your project. Now, then, you should be able to simply DBL CLICK on the BAT file from the VB project explorer to run the bat file and compile your project, complete with line numbers, all automatically.

And a final note; VBLiner does ostensibly support removing line numbers from VB files as well, but I've never had much use for that facility, so it's not well tested. As with any freeware, use at your own risk. And it should go without saying, Back up your source files before running it on them.

Download a zip of the utility here and let me know what you think.

posted on Tuesday, May 22, 2007 11:16:32 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, May 22, 2007

VB has one of the best IDE's around. Sure Eclipse is pretty capable, Delphi is quite slick, and for the purists, editors like SlickEdit can make you almost believe you're coding in an IDE.

But VB's IDE is the one to beat. And it has been since VB3.

But even the best have issues; mistakes, ommisions, things that jsut could have been so much better.

And that's where MZTools comes in.

If you haven't already played with it, download a copy and install it now. Carlos originally built MZTools for VB6 way back when, and that version was (and still is) a free utility. He's branched out to supporting Visual Studio .NET now, and the newest version is not free, but it is worth every penny.

Take a look at the features page for version 3 (which supports VB6). The Code Review, Code Templates, and Error Handler Templates are gauranteed to save tons of time.

Personally, I don't like his line numbering support. I feel like the line number applied to a line should be the same as the actual line number in the file, as reported by the VB6 editor, like this:

That way, you don't have to retain the numbered version of the source to be able to refer back to a specific line number. However, this is a pretty minor nitpick.

In short, MZTools is a massively handy utility to have on you're VB menu bar. Definitely for VB6 (cause it's, well, free), and worthy of consideration for .NET.

posted on Tuesday, May 22, 2007 6:55:10 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [3] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Sunday, May 20, 2007

On a lark a few days ago, I decided I'd like to have random rotating quotes appended to my outgoing emails. I use GMail for mail preview (and access when I'm away from my desk), but usually, I use Outlook when I'm at my desk.

Supporting random email signatures in GMail is a topic for another day, and I've honestly not even investigated it at all.

But Outlook. Surely, I thought there must be a free little utility to do that out there.

Well there are a few, but most aren't free, and the few that are, aren't particularly well built from what I can tell.

The one free one I did see that seemed to hold promise was QLiner. After a quick install, and then converting some quotes to a plaintext file, I fired it up and set things up.

It works, but it seems finicky to me. For one, it doesn't actually template out the signature, so much as it completely replaces the existing signature with a rebuilt version (with the new quote) on a configurable timeout. So if you sent 3 messages within 5 minutes, and the timeout was set to 10 minutes, it's likely all 3 messages will have the same quote.

Plus, it seemed to just "stop working" after a time. I never could see a pattern to this, but, invariably, after a few days, I'd notice that the signature wasn't changing anymore. Stopping and restarting the program fixed it each time, but that's not the hallmark of a solid app.

In the end, I uninstalled it, and I believe I'm going to throw my hat in the ring on this one.

I'm calling it Sig-Licious. The idea is that it is a simple COM Outlook addin that monitors for new email creation events, intercepts it, and parses and replaces keywords in the signature with specific bits of info.

For instance, {Date}, {Quote}, {QuoteAuthor}, {CurrentTrack} (ie what piece of music you're listening to right now, if any), etc, etc.

Any thoughts on what other variables might be nice? To totally geek it up, how bout any ol' Environment Var? Or the content of a performance counter at the time? Or maybe your CPU fan speed? I'm thinking various Active Directory fields might be nice, if available. Or maybe info from arbitrary Text files? Or maybe info from arbitrary posts you store in specific folders within Outlook proper.

I'll post something when I've got it a bit farther than just messageboxes\:\-\) .

Or stop me before I get too far and tell me the URL of that nifty app you've found that can do all this. Please!

Update

I found a few more apps out there for this. First, ADOLSign is 129$! For what is essentially a search and replace tool. Jeez.

Then there's Exclaimer. It's even more expensive, but does a lot more. For an enterprise setup, I could see spending a few bucks for this sort of functionality, but for your average joe, like me? Um, no.

I also just ran across Symprex Mail Signature Manager. It's freakin' expensive and you can only get a min 10 user license, and it appears to require Echange, but if you need something like that, it looks pretty complete.

And finally, Bells and Whistles. It's also basically a glorified macro search and replace. 29$. Better, but still, 29$ for this?

So far, nothing for the loan gunman looking for nifty sigs. I think I'll continue on with my little addin.

posted on Sunday, May 20, 2007 12:02:22 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, May 18, 2007

I had to do some icon editing recently, and did a little digging for a decent, free (or nearly free) editor that supports the new Vista and XP style icons.

I turned up AWIcons lite that looks pretty good, for a freeware version of their pro app.

Then I happened upon IconFX. Wow! It's not quite as polished and it's missing a few minor features, but it's a pretty slick package.

I also looked at Axialis and IconCool, but both are commercial and in the 50-60$ range, which isn't bad, but still.

In the end, I like AWIcons for the UI and the ability to sort the icon images within a single icon to the order necessary for XP. It's an SDI app (meaning you can only open one icon at a time in the app), but you can open multiple instances of the app, and cut/paste works seemlessly between them, so it's not a deal breaker.

IconFX supports more effects, hue, saturation, plus drop shadow etc, but you can't reorder the internal images. It is MDI, though, so you can load up any number of icons simultaneously to edit. The UI is a bit clunkier, but still perfectly functional.

There's a very good writeup of a number of the better editors here. To summarize, they recommend Axialis, followed by MicroAngelo, AWIcons and IconCool. Personally, I ran into errors after installing IconCool, so I'm not so sure about that one.

Looks like there's hundreds more, but these seem like the most capable. Anybody know of others that are good?

posted on Friday, May 18, 2007 9:28:57 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, April 21, 2007

Feng Shui is all about the placement of things to better harmonize with their (and consequently your) surroundings.

With VB, there's no better place to examine that than the file footprint of your application.

Ask yourself: You have two apps to evaluate. They perform identically, are configurable in all the same ways and behave exactly the same. One app consists of hundreds of files scattered across dozens of folders. The other's footprint is exactly one file, the EXE itself. Which would you choose?

Granted, that's an extreme case, but the point is, the smaller your app footprint, the better, in almost all circumstances.

And a really nice way to shrink an app footprint is with resources.

If you've never messed around with resource files in VB6, or maybe only tried to use the built in resource editor add-in, you really don't know what you're missing.

Resources can be an immensely handy way to embed everything from pictures to WAV files, to chunks of script, to icons, and just about anything else directly into your application, but in a way that makes them accessible to the outside world, for one-off customizations, translations, or to just keep the file footprint of your app as small as possible.

However, resource files can be notoriously difficult to work with because of the lack of tools available natively with VB6. VB.NET dramatically improves upon the situation, but there's still a lot of VB6 code out there that might benefit from resources.

Generally speaking, you have two "types" of resource files where VB6 is concerned.

  • the resource file the can be "included" in the project and is available to your code while you're running in the IDE
  • Any resources "added" to your applications EXE/DLL/OCX file AFTER you compile it.

Why the distinction?

There's one specific kind of resource that you very much should want to include in your compiled file, but which VB is notoriously lacking about. The Version Info Resource.

VB only allows you to specify the Major, Minor, and Build version numbers (although VB calls the Build number, the "revision" number, mysteriously).
Windows executables, on the other hand, support a Major, Minor, Revision, and Build.

Now, the truth is, VBs support is generally fine for utilities, hobbiest programs and the like. But real, commercial applications really should make use of all four numbers, and that's something that is impossible using VB alone.

Ah, you say, VB does have that "Resource Editor" add-in, just use it! Not quite. You can't create a version info resource in it, and even if you could, VB's compiler replaces any version info element within that resource file with the information from the project properties window.

The solution is relatively simple and still preserves all the great things that resource files in VB can do for you.

The IN-THE-IDE Resource file

For this resource file, you have 2 choices, use the VB Resource Editor Add-In, or create an RC resource script file, and compile it to a RES binary format file that VB expects. I prefer the later, simply because scripting the resource file makes it much easier to include things like big chunks of text (xml, scripts, icons, what-have-you), and you can leave all of those things external to the RES file without having to manually pull them in via the Editor add-in every time they change.

I usually create an RC file with the same name as the VBP file, but with an RC extension

test.RC

// Test Resource Compiler file
// used to automatically compile the RC file into a RES file
// BEFORE the project itself is compiled
// This makes the Resource data available to code while in the IDE
//
//-----------------------------------------------------------------------------------
// Arbitrary Text File Resources
//
//----------------------------------------------------------------------
TEXTRES1   TEXTRES_DEFS PRELOAD DISCARDABLE TextRes1.txt
TEXTRES2  TEXTRES_DEFS PRELOAD DISCARDABLE TextRes2.txt

//-----------------------------------------------------------------------------------
// Bitmap Resources
//-----------------------------------------------------------------------------------
IMG_MAIN  BITMAP PRELOAD  DISCARDABLE ".\test.bmp"

Note that test.bmp is just some random bitmap file, and that TextRes1.txt and TextRes2.txt are arbitrary text files.

Then, you can access those resources via a little bit of VB code

To get the text file resources

Dim a() As Byte
dim buf$
a() = LoadResData("TEXTRES1", "TEXTRES_DEFS")
buf$ = StrConv(a, vbUnicode) 'need to convert the raw ansi text file content to UNICODE to make VB happy

Or to load the bitmap

Set form.Picture = LoadResPicture("IMG_MAIN", vbResBitmap)

Icons, and string tables are a little more difficult, esp. with respect to XP and VISTA format icons, so I'll worry about them later.

You can compile the RC file using a command line similiar to the following:

rc.exe /r /fo "test.res" "test.rc"

Make sure the RC.EXE resource compiler is on your path for it to run right. The RC.EXE file itself should be somewhere in the VB6 installation folder under Program Files. For a muhc more thorough explanation of the Resource Compiler, check here. Microsoft has some very good RC information here also.

Alternatively, you can put this command in a BAT file, and execute it quietly:

cmd /Q /c rc.ex /r /fo "test.res" "test.rc"

One caveat. If you decide to use the RC file, be aware that VB loads the compiled RES file when you load the project. So if you make a change to one of the component resource files (say, an ICO or BMP file), you'll need to exit VB, recompile the RC file to a RES file, and then RELOAD the project in VB. Since RES files don't change all that much once initially created, this isn't a huge problem.

Another note: You can only include one resource file in a single VBP project, so it has to contain all the resources the app will need (except, of course, for the Version Info Resource).

And a final note: You can easily add a resource file to a project by
1) compiling the RC file to a RES file
2) Opening your VBP project
3) dragging the RES file from Explorer to the VB Project Window.

For next time, handling the Version Info Resource....

posted on Saturday, April 21, 2007 10:09:59 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions;