Thursday, January 28, 2010

I was working on a server issue this morning when I ran into something strange. I could no longer access a server that had been running for quite some time without any problems.

I tried a PING and got back an IP address for the server that made no sense at all. It wasn’t even part of my local IP range!

So I did all the normal stuff:

  1. Checked my HOSTS file
  2. ran IPCONFIG /FLUSHDNS
  3. ran IPCONFIG /REGISTERDNS
  4. ran IPCONFIG /RELEASE
  5. then IPCONFIG /RENEW

No joy. A ping was still returning the same bogus address.

So I checked my server’s DNS service. Not even an hit of that address.

Hmmm. So, where the heck was it coming from? A little googling didn’t turn up much, but eventually, I read a blog post that made an offhand mention of WINS.

Now, I don’t really know all that much about WINS. Just never had a reason to, I suppose. Mostly, I’ve always relied on and stuck with plain DNS. But, Ok, I’ll check it.

Go over to my server, and load up the WINS app (it’s under Admin tools)

image

The left hand window was completely blank. It took a second to realize I had to “query” to retrieve the WINS records, they aren’t automatically just shown.

image

And AHA! There, in the result list of “Active Registrations” was the bogus address for my server. (I’ve already removed it in the image below, but it was in the highlighted column).

image

Case closed. I’m still wondering what changed that suddenly, WINS was being used to resolve the server name when it must have not been before. The only thing I can think of is changing internet providers to Verizon FIOS from Time Warner Cable, and the resulting swap out of the main incoming router.

Granted, for a seasoned network guy, this is likely old hat. But for a software dev who only moonlights as a network guy, it might be some useful information!

posted on Thursday, January 28, 2010 2:04:42 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, December 31, 2009

If you haven’t checked it out already, DirectShowLib.net is pretty much THE way to get at direct show functionallity in VB.net (that is unless you want to spend $$$). Thing is, it’s only a paper thin wrapper over the DirectShow COM api stuff, so there ain’t no hand holding here.

I’d mucked with it for a while and with the help of some of the sample code, got video playing in a form in VB.net fairly easily, but, I needed to flip and/or rotate that video under some circumstances.

After many googles, I finally came across the IVMRMixingControl9 interface that the VideoMixingRenderer9 exposes, but, no matter what I did, I could not cast from a VMR9 to the MixingControl, like so:

Dim Mixer = DirectCast(VMR9, IVMRMixerControl9)

I kept getting an “Interface not implemented”. Then I happened across a post about a wholly different problem, but buried within it was a comment about needing to set the VMR into “mixing mode” in order for it to implement that IVMRMixingControl9 interface. Ugh! DirectShow is nothing if not interfaces. And odd dynamically implemented interfaces at that. Oh well.

A little more digging, and it turns out to be quite easy. Just obtain the IVMRFilterConfig9 interface from your VMR9 object, and call SetNumberOfStreams on it (with and argument 1 or more).

The end result is code that looks like this (remember, this is with a reference to DirectShowLib.net):

DIM FGM = New FilterGraph
Dim VMR9 As IBaseFilter = New VideoMixingRenderer9

FGM.AddFilter(VMR9, "Video Mixing Renderer 9")
Dim FC As IVMRFilterConfig9 = VMR9
FC.SetRenderingMode(VMR9Mode.Windowed)
FC.SetNumberOfStreams(1)

Dim Mixer = DirectCast(VMR9, IVMRMixerControl9)
Mixer.SetOutputRect(0, New NormalizedRect(1, 1, 0, 0))
Mixer.SetAlpha(0, 0.2)

Note that in this case, the SetOutputRect is reversing the output rectangle, so the video is going to end up flipped and upsidedown, exactly what I was needing. I’ve also set the alphachannel to .2, meaning the video is somewhat transparent.

Unfortunately, there doesn’t appear to be any way to rotate the video using the MixingControl, so that is my next topic of research.

posted on Thursday, December 31, 2009 12:11:22 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [1] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, December 09, 2009

image My system had been getting less and less stable recently, to the point where I’d blue screen and crash the entire machine while just browsing the web in FireFox.

So, when in came up that I’d need to have access to a 64bit OS, I finally decided to pave this machine and lay down a bright and shiny new Windows 7 installation.

Of course, doing so meant a couple of things.

  1. I had to make sure I had my old system available, just in case I needing any config files or whatnot. I keep all my data on a network server so that’s never been an issue. I used wbadmin (the Vista backup utility) to create a full VHD image of my Vista installation to a USB drive for this purpose.
  2. I did not want to wipe out my current raid, even though I had the backup. So I picked up 2 1.5TB Samsung drives to form a new RAID1 array.
  3. My mobo is the Intel Bad Axe 2 (D975xbx2), so it actually has support for the Intel ICH7 Sata raid controller and the Marvell Raid controller. Both can control up to 4 drives, so I figured I’d install the two new drives on the Marvel controller, leaving the existing Intel raid alone for now.

Problem 1

Unfortunately, idea 3 was my first problem. I couldn’t get Win 7 to see the Marvell raid. I spent the better part of a day fiddling with it, before I took the chance and disconnected the drives on the Intel raid. Sure enough, suddenly, the Win 7 installer could now see the Marvell raid.

Problem 2

My joy quickly soured though, when, about 20 minutes into the install, I got a message that the installation was “unable to read installation source files”. That’s it.

Hmm.

Could the CDRom image I burned be bad? Nope: a verify confirmed it was fine.

Maybe the raid array had problems? I reattached my Intel raid, booted Vista, and I could see the Marvell raid drive just fine. I scanned it anyway. Not a single problem.

Maybe I didn’t have the right F6 drivers for the Marvell controller? Some googles turned up that there was in fact, problems with the version of those drivers that Intel makes available, but even the older drivers direct from Marvell resulted in the same error.

Maybe my bios needs an update? Mine was several years old so I pulled the latest and uploaded. Still no dice.

With most of weekend gone, I decided to through a hail mary and try connecting the 2 samsung drives to the Intel raid controller ports. The concern was that, if I disconnected two of the existing raid drives on that controller, would I be able to boot back to the old raid if things still didn’t work? Or would the old raid be toast?

Deep breath, unplug the old, plug in the new, fire up the install, and…

It worked!

Problem 3

Way back, the main issue with 64bit Vista was I had no way to connect to our companies Cisco VPN with it. Well, I still couldn’t find Cisco 64bit drivers, and the 32bit versions won’t install into Win7 64. But, I’d come across the Shrew Soft VPN client before, so I thought I’d give it a shot.

I did need to dig up my Cisco configuration file, but once I found and imported it into Shrew Soft, I was connected first attempt. Pings to servers worked. Connected!

Problem 4

Toolbars. Little thing, granted, but I have run with a toolbar auto hidden on the left, as well as the taskbar at the bottom for ages. It’s comfortable and it put everything I typically use right there.

And Win 7 dropped that feature!

Yep, a feature that’s actually useful and MS drops it. Sigh. In reality, that decision seems to be getting quite a lot of bad blog, so I’m not alone in my sentiments anyway.

Fortunately, a feature in a program I’ve used for quite some time came to the rescue. The program is True Launch Bar from Tordex. I’ve written about TLB before, actually. It’s come in handy for a variety of purposes. For the past few years, when I’ve needed a handy gizmo and thought I’d have to download yet another widget, 9 times out of 10, TLB could already do the job.

This time, I used their “Standalone” version (included with the base package) to duplicate the functionality of the disconnected side toolbar, even though Win7 doesn’t support it directly.

If you like having a highly configured taskbar/toolbar, I (again) highly recommend True Launch Bar. It’s not free, but it’s cheap, and well worth the price.

Taming my Desktop Icons

One last note about my configuration. In the process of setting things up, I came across Fences by Stardock. It’s free. It does one thing, but it does it very well indeed.

image

Essentially, it allows you to “group” your desktop icons, and they stay in those groups, unlike under normal circumstances, where changing desktop resolution, or other things will tend to scramble your carefully arranged icons quite often.

It actually works on OS’s from Win 7 back to XP. Check it out.

A Minor Incompatibility

I’ve use DiskMapper by MicroLogic for ages. It’s a wonderful way to visualize your disk space usage. Yes, there are similar alternatives out there (like Zero Assumption’s Disk Space Visualizer), but I always seem to come back to DiskMapper.

Well, I tried the install and got an “incompatible application” error. Something about being a 16bit app. Yikes! 16bit!

Well, I pulled my DiskMapper installation files (post install) from the backup image I made, ran the app itself, and, after a quick paste of my registration details, I was up and running. So it would appear that the incompatibility was with the installer and not the app itself. Good news. And another good reason to make sure you have a full backup of your original system before making a switch like this.

And What About Win 7?

I’ve only been using it for a few days, so I’ll reserve some judgment for now. But I will say it feels a bit snappier, plus having the full 4gb ram usable (as opposed to only about 3.4gb under a 32bit os), is definitely a plus.

The ability to mount VHD files directly via the Logical Drive Manager is great. It’s my understanding that you can actually boot the machine into a VHD as well, but I haven’t tried that out yet.

Other than that, it really feels more like Vista SP2 than a really new OS.

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

If you've ever loaded up an MSBuild project in VS, you have likely seen some warning messages in the Error List window, essentially saying that either the first item in a custom ItemGroup is invalid or the first Property in a custom PropertyGroup is invalid.

The problem is that the MSBuild designers wanted to provide a schema to you'd get some nice intellisense functions when editing a proj file, but, they had to allow for custom properties and items because, well, that's what MSBuild is all about, after all!

So, those custom elements by definition, can't be included in the generic schema and, bingo, validation warnings.

The warnings don't actually harm anything and MSBuild effectively ignores them, so one solution is to do just that. Ignore all those new warnings in your Errors window. That's even what MS recommends <sigh>

For me, though, ANYTHING in that errors window is a red flag.

Getting that Nice, Clean Errors Window

After digging around, it turns out there's essentially 2 options to get rid of those warnings.

  1. Edit the Microsoft.Build.xsd file and include ALL the custom Property and Item names you might be using
  2. Or tell VS to not validate the proj file against any schema.

I can't imagine bothering to try to keep that xsd file up to date constantly as I change proj files, so that option was out.

Fortunately, telling VS not to validate the project file is relatively easy, and pretty easy to undo as well.

First, open the proj file in Visual Studio (if it's an actual VBPROJ or CSPROJ file, you'll need to unload the project first, then right click on it again and select Edit Project).

Click in the project editing window, then in the Properties box, Click on the Ellipse button to change the schemas property.

image

You should see this (though, the red Xs will be green checks):

image

When you get the dialog showing all the schemas against which the file is validated, select each one and choose "Do not use this schema"

image

Click ok and repeat for any other PROJ files you need to handle this way.

When done, you should no longer see any validation warnings in the error window.

Unfortunately, this also means that the proj file won't be pre-validated at all anymore and you won't get any intellisense anymore. But, really, once you've got your proj file setup, you shouldn't be needing to edit it much.

And if you really need to, just reverse the above process to turn the schema validation back on.

posted on Wednesday, October 14, 2009 9:07:08 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, August 04, 2009

image (No not that kind of volume!)

Seems like such a simple thing. If I'm on Skype or in general trying to use a mic in Vista, the sounds from the mic end up projecting out the speakers.

No big deal until the volumes get loud enough that you get a feedback loop. Then, look out! Dogs and cats (and wife and children) will run screaming from the house!

I'd dealt with this problem for far too long (Skype was almost unusable) but couldn't find anything on the web addressing the issue, at least not for Vista.

So I started poking around.

After far too much searching, I finally came across the secret room in Vista where the souls at Microsoft have stashed the hidden switch.

First, right click the speaker icon in the system tray (at the bottom right of the screen), and select Playback Devices:

image

On the next dialog, select Speakers and click properties:

image

On the next dialog, select the Levels tab

image

And make sure that little speaker icon under Input Monitor is DISABLED (like it is in the above screenshot).

If not, just click it to disable it.

This will prevent the mic input from being echoed out through the speakers, and thus prevent any kind of feedback.

Sure, it's simple now. \:\-\)

posted on Tuesday, August 04, 2009 7:10:08 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, July 25, 2009

image In my travails with MSBuild lately (the latest 3.5 version), I recently ran into some rather puzzling behavior. Essentially, it boils down to this.

If you set a property value via a PropertyGroup element within a target, and then use CallTarget to call another target, the property values you set won't be visible to conditions on that called target.

If, on the other hand, you set those same property values from a PropertyGroup within a different target that your main target refers to via the DependsOnTargets attribute, then those properties will be visible to conditions on the called target.

Yeah, you read that right \:\-\)

Here's a test MSProj project file that illustrates the problem.

<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
    <!-- Define various properties to use during the build here -->
    <PropertyGroup>
      <TestValue>false</TestValue>
    </PropertyGroup>

    
    <!-- A DependsOnTargets target -->
    <Target Name="DetermineTestValue">
        <PropertyGroup>
            <TestValue>true</TestValue>
        </PropertyGroup>
        <Message Text="TestValue=$(TestValue)" />
    </Target>

    
    <!-- The test condition fails here and this target is skipped -->
    <Target Name="DoTheBuildSkips" 
            Condition="'$(TestValue)' == 'true'">
      <Message Text="Did the Build (skipped)" />
    </Target>

    
    <!-- The test condition DOES NOT fail here and this target is executed -->
    <Target Name="DoTheBuildWorks" 
            Condition="'$(TestValue)' == 'true'">
      <Message Text="Did the Build (works)" />
    </Target>


    <!-- Root Target just Executes two different test targets -->
    <Target Name="Build" DependsOnTargets="PropertyIsNotSeenProperly;PropertyWorks" />
    
    <!-- First test target, set the TestValue to true and use calltarget, this fails -->
    <Target Name="PropertyIsNotSeenProperly">
        <PropertyGroup>
            <TestValue>true</TestValue>
        </PropertyGroup>
        <!-- the TestValue is true at this point but false when evaluated from DoTheBuildSkips -->
        <Message Text="TestValue (place1)=$(TestValue)" />
        <CallTarget Targets="DoTheBuildSkips" />
    </Target>    

    <!-- Second test target, set the TestValue to true from the DependsOnTarget
         and the "DoTheBuildWorks" target is executed because the condition is true -->
    <Target Name="PropertyWorks" DependsOnTargets="DetermineTestValue">
        <!-- the TestValue is set to true from within DetermineTestValue and is ALSO true
             when evaluated from DoTheBuildWorks -->
        <CallTarget Targets="DoTheBuildWorks" />
    </Target>    

</Project>

Just drop it into a folder and run MSBuild. Be sure to use the /v:diag command line switch so you see the full output.

I piped the results to a file and (with some bits trimmed out) this is the result:

Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3074]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 7/23/2009 4:25:13 PM.
Project "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj" on node 0 (default targets).
Initial Properties:
ALLUSERSPROFILE = C:\ProgramData
...Many env vars cut out here
TestValue = false

Building with tools version "3.5".
Target "PropertyIsNotSeenProperly: (TargetId:4)" in file "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj" from project "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj":
Using "Message" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "Message" (TaskId:0)
  TestValue (place1)=true (TaskId:0)
Done executing task "Message". (TaskId:0)
Using "CallTarget" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "CallTarget" (TaskId:1)
Target "DoTheBuildSkips" skipped, due to false condition; ('$(TestValue)' == 'true') was evaluated as ('false' == 'true').
Done executing task "CallTarget". (TaskId:1)
Done building target "PropertyIsNotSeenProperly" in project "Test.proj".: (TargetId:4)
Target "DetermineTestValue: (TargetId:0)" in file "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj" from project "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj":
Task "Message" (TaskId:2)
  TestValue=true (TaskId:2)
Done executing task "Message". (TaskId:2)
Done building target "DetermineTestValue" in project "Test.proj".: (TargetId:0)
Target "PropertyWorks: (TargetId:5)" in file "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj" from project "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj":
Task "CallTarget" (TaskId:3)
Target "DoTheBuildWorks: (TargetId:2)" in file "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj" from project "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj":
Task "Message" (TaskId:4)
  Did the Build (works) (TaskId:4)
Done executing task "Message". (TaskId:4)
Done building target "DoTheBuildWorks" in project "Test.proj".: (TargetId:2)
Done executing task "CallTarget". (TaskId:3)
Done building target "PropertyWorks" in project "Test.proj".: (TargetId:5)
Done Building Project "O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj" (default targets).

Project Performance Summary:
      107 ms  O:\Dev\Darin\Articles\MSBuild Property Failure\Test.proj   1 calls

Target Performance Summary:
        0 ms  Build                                      1 calls
        5 ms  DoTheBuildWorks                            1 calls
        5 ms  DetermineTestValue                         1 calls
       11 ms  PropertyWorks                              1 calls
       21 ms  PropertyIsNotSeenProperly                  1 calls

Task Performance Summary:
       12 ms  Message                                    3 calls
       13 ms  CallTarget                                 2 calls

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.11

(I've highlighted the key lines)

This file essentially has a Build target that is just used to kick off two other targets, that are the actual tests.

The first, PropertyIsNotSeenProperly illustrates the problem. The second, PropertyWorks, works just fine.

Notice that the TestValue property starts out false, but in both cases, it does appear to get set to true.

However, at the point that the condition for the DoTheBuildSkips target is evaluated, the value of TestValue must be false, which should be impossible.

I've read that the CallTarget is a bit of a deprecated method anyway, so maybe this is all just a problem of old code that hasn't been properly updated along with the rest of MSBuild.

But, I've found that using CallTarget on occasion can simplify some aspects of debugging larger MSBuild scripts, so that's why I've used it. Further, for me anyway, it makes the script a lot easier to read when the steps that it entails are laid out in a list, one CallTarget after another, instead of one target being dependent on another, which depends on another, etc, etc.

Something to be aware of.

posted on Saturday, July 25, 2009 9:19:24 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Monday, July 20, 2009

image I've been working with .NET and Office interoperability for some time now, and, other than a few minor hiccups here and there, things have generally been very smooth.

But a colleague recently ran into a problem that required a good deal of hunting to resolve. Long story short, even though .NET interoperability with Office objects is virtually foolproof, releasing your references has some hidden dangers lurking amongst the weeds.

As a general rule, it's safe to let the .NET garbage collector (GC) do it's thing while your application is running.

BUT, when you're app shuts down, you need to take a few extra steps to make sure everything's cleaned up before quitting.

The details are laid on in this article on MSDN. It's from 2005, but, from what I can tell, it's just as applicable now as it was then.

Essentially, the trick boils down to this:

When you're preparing to shut your application down, you need to make SURE you've released all your references to any Office objects. This means setting all your various references to Nothing, or, more typically, letting the GC do its thing.

Unfortunately, the GC doesn't necessarily do its thing during a shutdown, so you have to force the issue. And that requires code essentially like this:

WordApp.Quit() 
WordApp = Nothing 
GC.Collect() 
GC.WaitForPendingFinalizers() 
GC.Collect() 
GC.WaitForPendingFinalizers() 

The article noted above doesn't really go into why it's necessary to call Collect and WaitForPendingFinalizers twice, but it does appear to be required. I'm guessing it's due to the way the Finalizer sweeps object references; it could be possible for it to release objects in a certain order, causing it to skip some objects. But that's just a guess.

And as a final note, if your .NET code uses any COM interoperability, it might be a good idea to do some final cleanup along these lines as well.

posted on Monday, July 20, 2009 9:32:52 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Sunday, May 31, 2009

image I recently was doing some work with some videos. Things were working just fine at one point, but then I installed the latest version of JRiver Media Center (version 13).

Whammo. My videos wouldn't play anymore. Well, actually, they'd play audio, but the video was just black.

I thought it was the particular app I was using, so I tried Media Center, and Microsoft's Media Player. Same result.

From past experiences, I figured something had hosed a codec (codecs are utility libraries installed on your machine that code and decode video and audio files, each format has it's own codec).

But, where to start looking?

So, I did some googling and found a great page that lists all the various FOURCC codes for codecs:

http://www.fourcc.org/fcccodec.htm

From that, I found a little app you run against a specific AVI to determine what codec it uses, called GSPOT:

http://www.headbands.com/gspot/v26x/index.htm

Running that against the AVI in question yielded the XVID codec.

Alternatively, just view the AVI in a hex editor and look at the header in the file:

image

You should be able to pick out the four character CC code fairly readily.

Then, from the table at FOURCC, I went to the xvid codec page:
http://www.xvidmovies.com/codec/
Downloaded and installed. Presto! Videos with audio and video again!

It's just that simple :)

posted on Sunday, May 31, 2009 8:11:13 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, May 08, 2009

image I wrote about my headaches with the Cisco VPN client some time ago.

I thought I'd resolved those problems, but as is the case with most things computer, I had not.

At least part of the problem, as I discovered some time ago, is that the 5.0.0 version of the Cisco VPN client didn't properly deal with network interfaces coming and going, so in cases where that happened, the client would often end up trying to connect to the VPN host via the wrong network adapter.

How would network adapters come and go, you might ask? After all, they're physical cards in the machine.

But not so! If you run VMWare or Microsoft's Virtual PC, those apps create "virtualized" network adapters that come online as you start the program (and in some cases when you start each individual virtual machine) and can go offline just as frequently.

The solution (or so I thought) was to do a hard reset of Cisco's VPN service. That worked, mostly. But it still wasn't 100% complete. I still sometimes had trouble connecting that would, in the end, require a reboot.

Fast-forward to yesterday, when I couldn't get connected even after several  reboots, and I decided enough was enough.

Sure enough, some Google searches revealed that there is NOW a new version of the Cisco Client, the latest I was able to find is 5.0.4.0300.

One point to note is that this is all under Vista 32. From what I understand, XP has none of these issues.

Anyway, after a lengthy and pretty painful install, this new version appears to completely fix the problem. No Service resets required at all.

The Install

The biggest problem is the actual installation of the new version.

First make sure you write down all the connection details from your existing VPN connections. Once you've got the new version installed, you'll have to reset all those details back to what they were. This includes the host name (or ip address), passwords, username, etc).

Uninstall the old Cisco VPN client. For me, this took several reboots as the uninstall appeared to hang several times. Eventually, it did uninstall itself, though.

At this point you can try to install the new version, but I received a message that the "Deterministic Network Enhancer" wouldn’t install properly.

I had to manually uninstall the "Deterministic Network Enhancer" from my network connection properties dialog before Cisco would complete a successful install.

To do that, click on the Windows button (the old "Start" button), select Control Panel, and Network and Sharing Center".

Find you network adapter listed and click View Status.

image

On the resulting screen, click Properties

image

and on the next screen, click the Deterministic Network Enhancer and uninstall it.

image

Then, you should be able to install the latest Cisco VPN Client and not have any more connection problems.

Google to find the latest version.

posted on Friday, May 08, 2009 8:47:12 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, April 03, 2009

image I've been running the Cisco VPN Client (version 5.0.0.360) for quite some time now and have consistently had another one of those "annoying but not enough to bother doing something about it" issues the entire time.

Basically, it can often be difficult to establish a connection. Once a connection is made, it stays up quite nicely (as long as there's a little bit of activity over it). But establishing the connection in the first place can really be an exercise in patience sometimes, often taking 10 minutes or more of repeated connection attempts before succeeding. It seemed to me to have something to do with a timeout, but I had no idea what to tune or even where to look.

I finally decided to go poking around for a possible solution this morning.

First stop was Google, looking to see if there was a new version out. There is, but only with relatively minor changes, it would appear.

But the "changes and release notes" page did have some possibly pertinent material on it.

In particular, this caught my eye:

Vista Window Auto-Tuning Feature Might Cause Network Timeout Problems

Vista introduces a new feature called "Receive Window Auto-Tuning" that continually adjusts the receive windows size, based upon the changing network conditions.

Some people reported that auto-tuning causes network timeout problems with some applications and routers.

To turn off this Auto-Tuning, just open an administrative access command prompt and enter:

netsh interface tcp set global autotuninglevel=disabled

Try it out. If it doesn't help, you can turn auto-tuning back on by entering enabled in the above command.

At least so far for me, with it off, I've been able to connect immediately, every time now. A far cry from before.

*UPDATE*

There's a little more to it than just the autotuning level, it turns out. Apparently, VMWare's networking support can really mess with the Cisco VPN service. From what I can gather so far, Cisco's service does not like network interfaces disappearing and reappearing. It doesn't track them internally properly. So, even if you exit VMWare to start your Cisco VPN session, the Cisco service might still be confused.

The easiest solution is to simply restart the Cisco VPN Service (called CVPND). You can do it manually through the Services control panel, or use a batch file to restart it even more easily (check here for a nice clean little batch file that handles all the nuances of restarting a service).

Finally, it's not just VMWare that can mess with the Cisco VPN service. Apparently, ANY application which causes network interfaces to be created or removed could cause similar problems.

posted on Friday, April 03, 2009 6:11:08 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, March 28, 2009

The new InstallShield supports a very handy command line argument for debugging the handling of prerequisites.

Often times, you'll have a prerequisite for your install that, for whatever reason, fails to run. When that happens, if you've properly set the launch conditions for your install to detect the installation of your prerequisites, your install will fail based on that launch condition.

This is a good thing, but it still begs the question; why did my prerequisite fail to install?

In my case, I had a preq for the .NET Framework 3.5. But my installation failed to run the prerequisite, so it failed at the launch condition because the 3.5 framework was not on the machine.

However, I had no idea why it didn't run the .NET installer.

Even turning on Verbose MSI Logging, didn't help, because IS runs prerequisites BEFORE the Windows Installer kicks in, so the verbose log won't include anything about what happens when the preqs are run.

With the new InstallShield 2009, though, your SETUP.EXE supports a new switch, /DEBUGLOG.

Use it like this:

MySetup.exe /DEBUGLOG"Path and file to debuglog"

note there's NO SPACE between DEBUGLOG and the ".

so you might use:

MySetup.exe /DEBUGLOG"c:\debug.log"

Doing so revealed that the bootstrapper was, indeed, attempting to run the .NET Framework installer, but that it was failing. Unfortunately, It did not indicate the reason for the failure. Here's the pertinent snippet from the log:

1-23-2009[01:10:15 PM]: Extracting 'Microsoft .NET Framework 3.5 SP1.prq' to C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\{D4907620-651C-4FA9-9B3F-FCE2FCADB41A}\Microsoft .NET Framework 3.5 SP1.prq
1-23-2009[01:10:15 PM]: PrereqEngine: condition,2,2,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5,SP,,1 -- Successful
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,5,1,2, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,5,2, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,5,2, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,6, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,6, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,6, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: file,AD29C3DEC8FB0CFDAFE8548371B0EE6D,<ISProductFolder>\SetupPrerequisites\Microsoft .net\3.5 SP1\Full\Helper.exe,http://saturn.installshield.com/devstudio/setuprequirements/Microsoft .net/3.5/Helper.exe,,, -- Successful,
1-23-2009[01:10:15 PM]: PrereqEngine: file,,<ISProductFolder>\SetupPrerequisites\Microsoft .net\3.5 SP1\Full\dotnetfx35.exe,http://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe,,, -- Successful,
1-23-2009[01:10:15 PM]: PrereqEngine: execute,Helper.exe,/p dotnetfx35.exe /l 1033 /v "/q /norestart",/p dotnetfx35.exe /l 1033 /v "/q /norestart",1641,3010,, -- Successful
1-23-2009[01:10:15 PM]: PrereqEngine: Id,{074EE22F-2485-4FED-83D1-AAC36C3D9ED0},http://saturn.installshield.com/is/prerequisites/microsoft .net framework 3.5 sp1.prq, -- Successful
1-23-2009[01:10:15 PM]: PrereqEngine: behavior,Optional,,Reboot,2,Failure,
1-23-2009[01:10:15 PM]: PrereqEngine: Lua,
1-23-2009[01:10:15 PM]: PrereqEngine: Hidden,1
1-23-2009[01:10:15 PM]: PrereqEngine: MsiProgress,
1-23-2009[01:10:15 PM]: Skipping prerequisite 'Microsoft .NET Framework 3.5 SP1.prq' because it was installed before the reboot

Since things seemed to point to the .NET Installer, I ran it manually. Lo and behold, it failed because I didn't have SP2 installed on this virtual machine.

Duh!

But that DEBUGLOG switch definitely helped point the way.

posted on Saturday, March 28, 2009 8:15:26 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Monday, January 19, 2009

image Here's an example of the "When software doesn't work right, it can cost loads and load of time" type bug.

I'm using an Ultimarc WinIPAC controller board for a project I'm working on. This is an awesome little controller board that looks like a USB keyboard, and supports mapping of up to 56 switch inputs to any normal keyboard key. It also has LED outputs for driving LED's or other applicable circuits.

Anyway, the IPAC comes with a simple keyboard mapper/programmer that you use to layout your buttons, then assign which key to which button and finally to upload the mapping to the IPAC (It saves the mapping in non-volatile ram on the board, which is even more fantastic).

Anyway, I'd mapped a particular key to the ENTER key, as shown here.

image

But when I was testing all my mappings out, it didn't work. Actually, it'd flash sometimes but not consistently. Every other key worked flawlessly.

I spent the better part of 3 hours trying to debug what the heck was happening, swapping wires, using a test meter to verify connections, switch operation, etc.

I even pulled the latest version of their website, but still no joy.

In the end, I discovered that it's the WinIPAC software  that doesn't quite handle ENTER keypresses properly. I opened up NOTEPAD and just started pressing buttons and all of them, including the switch I had mapped to ENTER, worked perfectly.

<sigh>

<UPDATE> I emailed with Andy at Ultimarc (these guys get back to you quickly! Very nice support). Anyway, his comment was that the WinIPAC software isn't intended as a test application, only for programming.

I pointed out that if that's the case, there really ought to be a warning somewhere to that effect, especially if you map keys whose actions can't be displayed properly in the application. My rationale was, well, it DOES properly display keyboard status for virtually all the mappable keys so why wouldn't any normal person assume it could be used as a test app? But, in the end, it's easy enough to use notepad for those tested, IF you know enough to realize you need to!

posted on Monday, January 19, 2009 1:07:13 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, April 24, 2008

For today's blog entry, I'm going to delve into a bit of Word esoterica that, if you're into this sort of thing, you might find fascinating, and if you're not, well, you have been warned\:\-\) .

If a document is changed in Word, you'd expect to get a prompt when you close the document, wouldn't you?

Well, that's apparently just expecting too much, my friend.

And if you were to load a document programmatically and simply iterate through it, without changing anything, you'd expect that the document wouldn't actually change, wouldn't you?

Well, that's also… oh, you get the picture.

It appears to be possible in Word, without programming, to create a header that doesn't actually exist, or rather, that exists but is completely empty.

If you then iterate through the headers of the document, retrieving the Range of each, the act of simply "retrieving" the range, not actually modifying it, will cause the header to be modified, inserting a paragraph mark where there was none before.

This can effectively shift the entire document down, since, in the original document there was no "paragraph" in the header, but now there is.

Even more interesting, this modification isn't logged internally by Word, so if you were to close the document, you get no prompt that a change has been made, and from what I can tell, the change isn't actually saved, although it's very visible on-screen.

You can test this by creating a document with a null header, then, adding this VBA code and running it:

Sub Test()
   Dim sct As Section
   Dim r As Range
   Dim hdr As HeaderFooter
   
   For Each sct In Me.Sections
      For Each hdr In sct.Headers
         Set r = hdr.Range
      Next
   Next
End Sub

How do you create a document with a null header? To be perfectly honest, neither I nor a Microsoft Tech could figure that one out. Please let me know if you can.

But what I did discover was that the situation yielded something you could detect.

Essentially, the problem is this:

Each SECTION object in Word has a PAGESETUP object associated with it.

And each PAGESETUP object has an associated HEADERDISTANCE and TOPMARGIN property. It also has FOOTERDISTANCE and BOTTOMMARGIN properties, but I'll only deal with headers here. Footers are handled in exactly the same way.

In a document's section, if the HEADERDISTANCE is ever >= the TOPMARGIN, any changes in the size of the header have the potential for "spilling out" over the limit of the margin and pushing the content of the section body down.

I say potential, because if the header doesn't contain anything, or if what it contains is not enough to push the bottom of the header past the TOPMARGIN, everything will stay put and all will be well.

In any case, right before you save the document, you simply need to iterate through all the headers in all the sections of the document and test if they're empty. If they are, you force the HeaderDistance back to half of the TopMargin.

Section.PageSetup.HeaderDistance = Section.PageSetup.TopMargin / 2

Why half? It essentially doesn't matter what it is, as long as it's less than the TopMargin.

But what makes up an "empty" header?

Once you get the Range of the header

set Range = Header.Range

Make sure it's not a linked header

If Range.LinkToPrevious then {it's linked so don't bother with it}

and then check the character and word counts

If Range.Characters.Count > 1 and Range.Words.Count > 0 and Range.Characters.Count > Range.Words.Count Then
   {this is NOT an empty header}
End If

If it's empty, adjust the HeaderDistance as noted above.

Fun stuff.

posted on Thursday, April 24, 2008 9:43:19 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, December 20, 2007

I recently had to rearrange some code that dealt with Tracked Changes in a Word document.

After refactoring, I ran through a series of test documents I use to verify things and was surprised to find that one of my primary test documents failed. I got an error that the method I was using (Document.AcceptAllRevisions) wasn't available because the document was protected.

This particular test doc was, in fact, protected, but only with a blank password. It also had 2 sections, the second of which was "protected for form fields". A bit complex, maybe, but certainly nothing horribly bizarre.

The reason the error surprised me is that my app attempts to unprotect any document it finds protected when it loads the file. If the doc is only protected with a blank password, my app will unprotect it and I can usually continue on with no problems.

If the doc is protected with a password, well, c’est la vie. I just throw up my hands and cry mercy!

But the unprotect didn't seem to work anymore. Why?

I started with some googling but got nowhere.

Then I figured it had to be something I had been doing before attempting to AcceptAllRevisions originally, but that I was now doing afterwards. No luck there either.

Ok. It had to be something in the load up process (loading the doc into Word, and setting things up). So I commented out everything but the essentials. Still no luck.

In desperation, I coded up a quick test app to try and replicate the problem outside my app:

Public Sub Main()
   Dim x
   Dim w As Word.Application
   Dim doc As Word.Document
   
   Set w = New Word.Application
   
   w.ScreenUpdating = False
   w.Options.CreateBackup = False
   
   '---- NOTE Pagination must be true for certain RANGE INFO functions to return valid results
   '     It sure can slow some things down though.
   '     TODO investigate this
   w.Options.Pagination = True
   w.Options.BackgroundSave = False
   
   w.DisplayAlerts = wdAlertsNone
   
   w.WordBasic.DisableAutoMacros True
   Set doc = w.Documents.Open("c:\Users\Darin\DeskTop\000-Main-New (2).doc", ReadOnly:=False, AddToRecentFiles:=False, Visible:=True, PassWordDocument:="Blahblah", WritePassWordDocument:="BlahBlah")
   On Error Resume Next
   w.WordBasic.DisableAutoMacros False
   On Error GoTo 0

   doc.Unprotect
   doc.Sections(2).ProtectedForForms = False
   
   doc.TrackRevisions = True
   
   doc.AcceptAllRevisions
      
Cleanup:
   doc.Close SaveChanges:=wdDoNotSaveChanges, RouteDocument:=False
   
   Set doc = Nothing
   w.ScreenUpdating = True
   w.Quit False
   Set w = Nothing
   Exit Sub
   
ErrHandler:
   x = 1
   Resume Cleanup
End Sub

It worked perfectly. Grrr.

To recap, run the above code on it's own, no problems. Run effectively the same sequence in my application, I get a "Document is protected" error when I execute the doc.AcceptAllRevisions line.

Now it's time for hail marys...

I tried playing with the TrackRevisions state, with various incantations against the Unprotect method, even presaving the document. No joy.

In the process, I tried checking the ProtectionType of the document. It was -1 (no protection). Ok. Good. But a bit later, I tried checking the ProtectionType of the Application.ActiveDocument. Protected!

What?!

Then it hit me, when I run my app, it's running as an AddIn within Word. So when I load this document to process, I've actually got 2 copies of the document loaded in Word, the original version, and a COPY of it (with a random filename) that I actually process.

When my test app ran, only one document was loaded in Word, so it HAD to be the active document.

But when I ran my app, even though the AcceptAllRevisions method on a Document object should certainly have nothing to do with some other loaded document (the active document), that does appear to be the case.

Long story short, I force the "active" document to be the document I'm about to AcceptAllRevisions on, like so: (Thanks to David for the heads up that my code snippet below wasn't quite complete!)

Set Doc = {whatever DOCUMENT object you are currently working with}
Set aDoc = App.ActiveDocument 'Get the "active" document, to restore it below
Doc.Activate 'Activate the doc you're working with
Doc.AcceptAllRevisions

'And finally, reactivate the originally active doc (if this is appropriate for you)
If Not aDoc Is Nothing Then aDoc.Activate
And AcceptAllRevisions works perfectly well once again.
posted on Thursday, December 20, 2007 8:53:39 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, September 04, 2007

This Vista Update, delivered 9/4/07 at about 3am (for one machine, anyways) has some serious issues, so beware.

Now, when I load Word 2007, if I immediately quit Word, it crashes. And if I attempt to load a document by dbl clicking on it, Word fails to load the document completely, just opens an empty window. Even odder though, is that I have a different machine that I pulled the update earlier for (it's set to manual update) and it's fine.

The only difference between the two that I can see, is that on the failed machine, Word was OPEN at the time of the upgrade.

Even worse, UNDOING the Patch caused the machine to fail to boot. It would start to boot up, then just shut down.

I had to use the "Boot to last known valid configuration" option, then use the System Restore Point function to rewind back to before the 3am patch.

Once I'd done that, everything ran fine again.

Ah the joys of automated updates.

posted on Tuesday, September 04, 2007 8:35:02 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
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; 
 Saturday, July 14, 2007

So I'm getting all set to upgrade my TIVO harddisk. I've downloaded and burned MFSTools, gathered all the various bits together, etc.

I thought, Hey, it'd be a good idea to try this out on a scratch HD first, just to make sure I know what I'm getting into.

So I grabbed an old 120GB drive, swapped it into my machine, and was going to reformat it as FAT32 and copy a few files on it, so act as a surrogate TIVO drive.

I swapped the drive in, restart the machine....

BOOTMGR is missing

Huh!??????

After some panicked Googling from my server, I discover that Vista has a nasty habit of writing the BootMgr sector to the "first" HD in the drive sequence according to how your BIOS is configured at the time you install Vista.

In my machine, the RAID comes pretty late in the boot sequence, so apparently, my spare 320gb drive that I was intending to use in my TIVO inadvertently picked up the Vista boot manager.

To avoid this whole mess in the first place, make sure when you install Vista, the ONLY HD that's installed is the one you're installing Vista onto.

However, if you're like me, that's not much of an option. Which leads to solution #2:

  1. Shut the machine down.
  2. Disconnect any "other" hd's (other than the one that has Vista installed). If you've got a RAID, leave only those drives in the RAID connected.
  3. Find your Vista Boot DVD
  4. Put it in and restart, boot to the DVD.
  5. The Vista installer will start up and ask if you want to install in English, etc. Click Next. This won't actually start installing Vista.
  6. The next screen, towards the bottom, has a "Repair your computer" option. Click it.
  7. Click the operating system installation (there's likely only the one Vista installation listed). Click next
  8. In the System Recovery Options dialog, click Startup Repair.
  9. Restart the computer.

Worked for me.

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

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; 
 Friday, July 13, 2007

Dealing with attachments in Outlook is a bit like entering an Ultimate Fighting match against a professional half-octopus, half-eel. It really doesn't matter what style of fighting you choose, the octo-eel is guaranteed to take you down more than once in the match, and there's really no telling whether you have a chance at winning.

An app that I'm working on deals with attachments in Outlook, more specifically, it deals with Office format attachments, so we're talking about DOC, XLS, and PPT files (and about 2 dozen other *X and *M formats introduced in Office 07).

Anything else (like BMPs, TXT files, etc) are supposed to pass on through like yesterday's iceberg salad.

However, astute customers noticed that, in some cases, the order of the attachments could change at times. If you had numerous attachments to your email, and you intended on them being in a particular order, that might not go over well.

Now, you might think, with such a nicely laid out object model as Outlook's, that preserving the order of attachments in a message would be trivial. Hell, you might even thing you could simply replace one attachment with another, simply by using a replace method or somesuch.

And you'd be wrong.

There's no replace method, unlike GroupWise. And the ATTACHMENTS.ADD method doesn't allow you to specify an ordinal. It does allow you to specify a position, but that value is only used to indicate the character position of the attachment in an RTF format email. If the email format is plain text, or HTML, the position isn't used at all.

Then there's this jewel from the MSDN documentation on the add method.

To ensure consistent results, always save an item before adding or removing objects in the Attachments collection of the item.

Special.

Add to all of that the fact that Word can also be used as the email editor (albeit in approximately the same capacity as the built-in Outlook RTF editor from what I can tell), and you have a whole lot of arms to fight with on this octo-eel.

The bottom line however, turns out to be relatively simple.

  1. First, you have to make a single pass through all the attachments in a message and for every one you plan on removing, you need to add the new one. In addition, for those that you don't plan on removing, you have to extract them, then add them again anyway, in the same order as they already exist.
    This will cause the email to end up with a double set of attachments; the originals, and all the new ones, plus a second copy of any original attachments you didn't necessarily want to mess with but have to anyway.
  2. Next, make another pass through all the attachments, removing all of the original attachments, but leaving everything else. Now, the email will contain the proper list of attachments, both new and untouched originals, in the original order, at least for plain text and HTML formats.
  3. For Rich Text, there's one more trick....
  4. When you add the new attachments (or re-add those attachments you intend to pass through, in step 1 above), retrieve the POSITION of the attachment first.
    If it's 0, make sure you add the new attachment WITHOUT specifying a position argument. Specifying a 0 for the position will only mess things up.
    If it's NOT 0, however, add the new element with a position argument of the original POSITION + 1

It sounds more complicated than it is.

If you get any part of it wrong, you'll know pretty quick. Usually, the attachments will end up in the sent email reversed in order. Worse case, some will end up missing.

One final trick. Testing all this can be a real pain, but you can make it a little easier.

Set up Outlook with POP accounts only (don't use Exchange for this). Then set it to NOT send email on startup:

image 

Anything you send will end up in the outbox, where you can examine it, use it for debugging, drag it back to the inbox to attempt a resend, or delete it. And from what I can tell, whatever ends up in the outbox is what would go. There's no additional processing done after that.

Plus, you don't even have to use a legitimate TO address, anything that looks like an email address will work.

Believe it or not, I actually like Outlook, despite it's, uh, quirks? It's been my email system since about 97. I've never had a corrupted PST file, never lost an email (that I didn't unintentionally delete with Shift-Del), and never gotten an email-born virus.

Now, excuse me, I have some serious knocking to attend to. 

posted on Thursday, July 12, 2007 11:44:17 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, July 07, 2007

Apparently, DirectX supports something called "retained mode". Not exactly sure what it is or what it does.

But I just found out that one of my favorite apps, Flying Model Simulator or FMS requires it and you get a lovely dialog that "D3DRM.DLL cannot be loaded" when you install the latest FMS 2 Alpha 85

A little digging and it seems this is quite the problem with a number of older DirectX programs. I suppose MS figured that if the app is more than a few years old, nobody would possibly want to use it anymore:-(

Anyway, this forum posting discusses the problem and pointed me to the Dell web site here to download the missing file.

Copy it to my fresh and shiny clean System32 folder and I'm flying my simulated RC heli again.

image

Here's something interesting. If I switch windows away from FMS, it pauses in the background, which is actually quite nice.

I don't recall it doing that under XP.

Something to actually like about Vista? I...feel....so....dirty.... 

posted on Saturday, July 07, 2007 12:06:28 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [3] • 
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; 
 Thursday, June 21, 2007

So ages ago, in internet time (or 9 months ago in real time), I set up a brand new machine, specifically for development with VS2005 and ASP.NET (because, well, it takes a dual core 2.66ghz, 4gb ram beast to be able to write a text file without your keystrokes backing up, but that's another story).

I'd set up a RAID 0 (that's striped), mainly for the added performance, which was pretty staggering. My intention was to pick up a couple more drives later and round it out to a RAID 0+1 (which I have in my server, protecting all my actual source, etc).

Anyway, a drive died, quite prematurely, and my machine is thus rendered a doorstop.

I sent off the RMA to replace the dead drive (still under warranty), and picked up 2 more to round the RAID out.

Then I discovered that the Gigabyte GA-965-DS3, otherwise a totally bad-ass mobo, doesn't actually do raid 0+1. It only supports a 2 drive raid, either RAID 0 or RAID 1. Doh! Tip to manual writing guy: Don't say things like...

"Before you begin

Please prepare

1) At least two SATA Harddrives...If you do not want to create a RAID, you can only prepare one harddrive.

..."

That is a quote directly from the manual.

In my book, the implication there is that you could use more than 2 harddrives in the RAID. Unfortunately, such is not the case.

So I went off to the local computer store and picked up a PCIE 4 port SATA II RAID card, thinking I'd slap it in and be done.

Nay, spoketh St. Ignacious PCMCIA of the holy hardware. That card is PCIE x4, and my Gigabyte motherboard only has 3 completely unused PCIE x1 slots.

Back to the computer store.

I could get a PCI SATA II RAID card, but SATA II drives can pump 3Gbps, whereas a PCI slot can only manage about 266MBps. Does seem right to build up a smokin' machine, then force it to breath through a pixie stick.

Ok, new mobo time.

Looks like the Gigabyte GA-965-DQ6 has all the bells and whistles, plus the right combination of RAID, PCI slots, ATI Crossfire compatibility, USB and Firewire, plus, it even has a serial port on the backplane, just right for hacking X10.

Note to self: Don't bother "presetting" up a harddrive that you might want to mirror in a RAID later. Both the Gigabyte built in RAID and Window's software RAID (via "dynamic disks") want to obliterate any disk they RAIDify.

The nice dedicated RAID cards (like the Promise Fasttrack), I believe can handle that. Hell, one I was reading specs on seemed to imply it could convert, on the fly, between RAID 1, 0, 5 or 0+1, provided you have enough free space. Now that's a good time!

posted on Thursday, June 21, 2007 5:02:21 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Sunday, June 17, 2007
A few days ago, I posted light-hearted jab about some computer problems on the ISS. Well, never one to walk away from an opportunity, karma visited yesterday with no less than a complete failure of one drive in a RAID 0 I have on my main workstation.
For those that have never run RAIDs, it stands for "redundant array of inexpensive disks" and you can run several different configurations.
  • RAID 0 - striped, 2 drives contain various pieces of files, such that you get double performance because both drives can be busy writing and reading different pieces of the same file at the same time. You get almost twice the performance and still have access to the full capacity of both drives.
  • RAID 1 - mirrored, 2 drives contain exactly the data between them. Speeds up read performance, and provided an online backup of data. You have 2 drives but the effective disk space of just 1.
  • RAID 0+1 - striped and mirrored. Best of both of the above.
  • RAID 5, 6 etc - Even better but typically requires higher end dedicated RAID cards.
I had set up a RAID 0 for performance, intending to add 2 additional drives and mirror the setup later, for fault tolerance.
Well, later didn't come quickly enough, it seems, and one of the less than 9-month-old Western Digital WD3200KS drives (sweet drives, BTW, unbelievably quiet and cool running), went belly up way before its time.
So, I'm filling out RMAs to return the dead drive and ordering two more to complete the full RAID 0+1 setup.
A question for anyone who's ever done this before. Can I setup a striped RAID 0 now, and add the 2 additional drives later to convert it to a mirrored/striped RAID 0+1 later, when the 2 drives come in, or do I have to have them all in place when I create the RAID initially?
Haven't had much luck finding an answer online.

posted on Sunday, June 17, 2007 3:29:56 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, June 14, 2007

How's this for a rough IT problem. Apparently, the ISS is having some difficulties getting several fairly important systems back online after some problems.

Of course, if they need computer help, I'd love to offer to take a trip up to help debug things\:\-\) .

Wouldn't that be an awesome GeekSquad tech call!

posted on Thursday, June 14, 2007 4:18:58 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [1] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, June 09, 2007

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\:\-\)

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.

posted on Saturday, June 09, 2007 8:28:53 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, June 08, 2007

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 \:\-\) )

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......

posted on Friday, June 08, 2007 6:44:27 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, June 05, 2007

I like Apple, and I even owned a Mac for a time (a IIcx, yeah, it was a while back\:\-\) ).

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.

posted on Tuesday, June 05, 2007 4:52:22 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions;