Monthly Archives: June 2007

Monolithic, Client-Server, 3-Tier, n-Tier

2
Filed under Software Architecture, VB Feng Shui

You are writing all your applications with a Client-Server architecture, right?

Oh, wait, this isn’t the late 90’s.

You are writing all your applications as 3-Tier assemblies, right?

Oh, wait, this isn’t the early 2000’s.

You are writing all your applications… Oh, to heck with it.

What’s the architecture du jour these days, anyway, n-tier? x-tier? SOA? XYZ-PDQ?

So what’s all the hubbub?

I propose something radical. Logically tier your code based on functionality, not locality. If you do that properly, monolithic, Client-Server, 3-tier, n-tier, x-tier, tears for fears, it won’t matter.

Why not?

Because if the code is properly organized and logically tiered, you’ll be able to easily move it wherever it needs to go to create (and remove) whatever tiers become necessary.

For example, I once worked for a company building a sizable billing package based on SQL Server. We wanted it 3 tier (Presentation, Business Logic, and Data Access), but we also needed it to be:

  1. easy to debug and maintain, and I mean easy, not the “learn how to jump through hoops faster” easy, but really easy. The dev team was small. This was a requirement.
  2. easy to deploy in a demonstration mode. If a prospect couldn’t fire up a CD install and in 5 minutes or less be playing with it, it wasn’t going to fly.
  3. capable of scale-out deployment to accommodate multiple report generation servers, data analysis servers, etc.

In the end, we designed a server app as the BLL (it actually ran as a service), a database chock full of highly optimized stored procs as the DAL, and a fat client that contained not only the user-facing interface but also the entire server app internally. And the key to all this was that the code for the server was exactly the same code as was in the client. The code was literally shared between projects in our VCS.

When connected to an actual server component, it got all the benefits thereof. But for debugging, it was unbelievably efficient to have both the client and server right there running at one time not only in the same IDE, but actually as part of the same executable. And deployment was a snap because the demo install didn’t have to bother with a server installation, it just created the DB and dropped the client on the machine.

If we’d needed to split functionality out farther, it would have been a very straightforward process because internally, everything was already split out.

The bottom line is:

Get the logical tiers right and encapsulate with a vengence.

Note to self: Vengeful Encapsulation. Sweet band name!

MSI and Mapped Drives Part II

5
Filed under Installations, Troubleshooting

In my post here, I discussed a problem I’d run up against having to do with performing an ADMIN installation to a specific drive letter or network path, then unmapping that drive letter and remapping it to some other letter.

If you then attempt a client install, you’ll get either at 1327 error (for mapped drives) or a 1606 error (if you used network UNC paths).

After further testing, it appears that the problem comes from assigning the TARGETDIR property to the AdminProperties property.

Some background:

The AdminProperties property is a “;” delimited list of property names that should be preserved when performing an admin install. The MSI engine stores those property values as they are at the time of the administrative install into the created Client Installation MSI (the MSI file that ends up in the admin install folder). Here’s an example:

MSIRemoveTARGETDIR

and a little closer in…

MSIRemoveTARGETDIR

(Interesting bit of trivia: I have no idea how the MSI engine actually stores these properties in the MSI file, because opening the MSI file with ORCA, I couldn’t find them anywhere. I’m guessing they’re not stored as a normal table entry).

Normally, any properties you’d like to pass on to the client install (ie those collected via the User Interface during the Admin install), you would list as AdminProperties so the MSI engine will pass them on.

I had set the TARGETDIR property as an AdminProperty, because at one point, I believed it was necessary to preserve the path to the Admin installation, so the client installation could make use of it.

This turned out to be ill advised, however, because often, admin installations will be moved (for disk space reasons, reshuffling servers, etc), and preserving the TARGETDIR this way locked the Client install to always point back to the original administrative install. Instead, during a client install, I simply obtain the value of the current location of the MSI file (which, by necessity is the current location of the administrative install) and use it where needed.

At any rate, none of this should have mattered, because the documentation clearly states that the COSTFINALIZE MSI event checks the directory table for valid drive letters, not the Properties table.

However, directories stored in properties listed in the AdminProperties list are appearently special cases, and their validity is checked.

Moral of the story? Use InnoSetup<g>

But, if ya gotta use InstallShield, make sure you do not:

  1. Store the Admin Installation folder or any folder that might end up getting remapped or disconnected, into a property during the Admin install.
  2. List that property in the AdminProperties property.

This goes for the TARGETDIR property (a common one), but also any other properties you might create.

MSI and Mapped Drives

2
Filed under Installations, Troubleshooting

Don’t you just love strolling along merrily on a friday afternoon, thinking “My, the weekend is right around the corner, I believe I shall sup on crumpets and tea”, when you step right through a soft spot on the ground in fall into a viper pit?

Ever seen this error before:

(The blackout is to protect the innocent <g>)

It’s an MSI 1327 Error Invalid Drive, indicating (surprise) that a specific drive is invalid.

Basically, I got it while testing the install of an application I’m working on.

Many Google searches and a call to MacroVision later, and I still didn’t have much of an idea what was going on.

The drive letter in question WAS valid at the time I did the original administrative installation, but was no longer valid when I performed the client installation from the admin install.

To sum up:

  1. Map a folder to DRIVE X
  2. Perform an Administrative Install of your app to Drive X
  3. Unmap Drive X and remap the same folder to Drive Y
  4. Perform a client install from the administrative install that is now on Drive Y
  5. BOOM goes the dynamite

Even more interesting, I tried the same installation steps, but didn’t use a mapped drive. Instead, I used a UNC network path name, and then forced that network share to become invalid. I got a 1606 “Could not access Network location” message. Different error, but the same problem.

I turned on verbose logging for MSI and it recorded that the error occurred during the CostFinalize event. That event validates all folder entries stored in the Directory table in the MSI, but a quick perusal of that table revealed no references to the (now invalid) drive letter.

Macrovision support suggested trying the client install on another machine, which I did and got the exact same error.

Then, on a whim, I simply mapped a folder to that drive letter (the one in the message). Any folder, some share out on the network, didn’t matter what.

Viola! She workee!

Long story short, apparently MSI takes a snapshot of the drive (mapped or UNC) when you perform an administrative install. Then, when you attempt a client install from that admin install, if the drive that was in place at the time of the admin install doesn’t exist, you get the 1327 error (or if you used a UNC path, an error 1606). From what I can tell, though, it doesn’t actually use that drive for anything.

If you used a mapped drive, just creating a mapped drive with the same letter is enough to make MSI happy and continue with the client install.

If you used a UNC path, things aren’t so rosy. In fact, I haven’t found a recovery for this situation yet, though I suspect one is hiding under an MSI boulder somewhere…..waiting……

New Comment Styles

8
Filed under Blogging, CSS

I’m experimenting with a new comment style on the site.

Basically, the idea is to make comments look like they’re speech balloons. Plus, I believe it makes them a little easier to follow. Here’s an example of what it should look like now.

I saw this on a blog somewhere, just not sure where anymore, and apparently I cleared my browser history since then because I couldn’t find it again.

I’d have preferred the Names to be on top, with the arrow pointing down into the comment, but dasBlog doesn’t have any support for templated comment elements. You have to have that to move the actual pieces of the comment (the name, comment, and date, for instance). From what I have found online, they just haven’t gotten around to it yet. That made modifying the comment item format, um, shall we say, an adventure.

This is the first round. It doesn’t seem to work completely in IE (the little dialog arrow doesn’t show up), but it doesn’t completely mess things up either. It looks right in FireFox. Not sure about other browsers.

The trick, as I’ve got it now, is that I’m using the AFTER pseudo-element along with the CONTENT keyword to create an image tag where there was none before, like so:

.commentPermaLinkStyle:after {
 content: " " url('quotearrow.png');
}

Unfortunately, this doesn’t appear to be handled properly by IE. I tried a background img, but that didn’t seem to work well either.

CSS, one giant, turbo-charged erector set full of parts that don’t always fit the same way 🙁

Bad, Bad, Naughty UI

1
Filed under VB Feng Shui

Ok, how hard is it really to use a standard Windows button control on a form?

Apparently, for this app, it’s pretty difficult (and this is a big name Document Management app):

BadUI

Notice the FIND and PROFILE SEARCH buttons. They’re some kind of odd “flat button” thinggees, but right next door are two standard Windows OK and Cancel buttons (hopefully, the grokked down capture still shows this).

Maybe I’m just nitpicking here, but if you’re gonna skin an app and give it new button styles, shouldn’t you do all of them? Or just leave em alone?

My question is, Why stop at button styles? Why not make some labels bold, and others italics, just for the heck of it. Consistency is the mother of derision, right? Oh, and throw in some good colors while you’re there. It’ll help. Trust me.

The Father of Telecommuting

2
Filed under Telecommuting

I’ve telecommuted for more than 5 years now, half of which was in a management/chief architect role, so anything in the news about telecommuting interests me.

Here is a brief interview with Jack Nilles, who, from all accounts, is the father of telecommuting, having coined the term back in 1973 while working for the ASAF and NASA.

He makes some great observations, among them:

  • “They commute to the office, get on the phone and talk with someone somewhere else. What’s the point?”
  • “Most people are relatively clueless about the human interaction aspects and supervision techniques and so forth required to be good managers”
  • “Branch offices and telecommuting are similar.”

I’ve run into some of these things first hand; “I can’t see you, so I can’t manage you.” That sort of thing.

I once even got a telephone callback by one company that I’d responded to, who was a software vendor, but who’s ad was very vague about the actual kind of software they sold. Once I got on the phone and realized they made, essentially, spyware that would track websites you visit, keystrokes, time spent in particular applications, etc, I closed out the conversation quickly, turned and didn’t look back.

Their idea was that, along with a timesheet, you’d turn in this encrypted report of the log that this application generated. As the employee, you couldn’t alter the log, though you could view it. They argued that such software would encourage employers to support more telecommuting, because it would make the telecommuter’s day transparent, and it would be a “good thing” for telecommuters because it allows them to “prove” they’re doing the work they say they are. Mr. Nilles’s comments, or a good sit-down with Steve Maguire’s “Debugging the Development Process” should be proof enough that such thinking is so utterly wrong it makes the Flat Earth Society look like geniuses.

I’m sure they’ll sell the hell out of that app 🙁 .

Employees have to be judged by their work, not how long they’re in their seats, or how much time they spend with Visual Studio loaded. Successful development shops (telecommuters or no) understand this.

Automatic Process Priority Optimization

1
Filed under Utilities

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 <g>) , so my money’s on ProcessTamer now!

Just don’t go setting arbitrary processes to real time! You have been warned<g>

Google ads and slow page load

4
Filed under Uncategorized

If you’re experiencing slow page loads and the browser indicates that it’s:

“transferring data from pagead2.googlesyndication.com”

in the status bar, please let me know.

I’ve just started noticing it today. Not sure if this is just a temporary Google thing or something more insidious (weird spammer links, etc).

Vista and QuickTime

2
Filed under Troubleshooting, Vista

I like Apple, and I even owned a Mac for a time (a IIcx, yeah, it was a while back<g>).

But QuickTime is a bit annoying.

First, it keeps “offering” to install ITunes for me, even after I’ve clicked the “don’t bug me about this again” button.

And second, on a Vista machine I have, it totally trashes the video, puts little bars everywhere. You can still see what’s going on, at least enough to reboot the machine.

And reboot you must. There’s no other way I’ve found to correct the situation once it’s happened.

I started hunting for possible resolutions to this and found several mentions of this:

  • Right click the QuickTime icon in the tray
  • Select settings
  • Click the drop down and select Video Settings
  • Click the “safe mode” option
  • Close and reboot

It seemed to work for a bit but the problem came back.

So I started playing with it and found that if I unselect the Safe Mode option (ie click the OPTIONS radio button), then UNCHECK the Enable DCI and Enable DirectDraw, that seems to make things much more stable. Haven’t gotten the trash screen since.

Your mileage may vary.

Let me know if it helps.

The Running instance of Windows Media Player

13
Filed under Media, MP3s, Office, Utilities

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!