Friday, February 11, 2011

InstallShield Build Error -6199


Recently we started having a problem building an InstallShield installer on some of our build machines. Yes, some of them -- this is what made it so frustrating.

The error we'd see, using the standalone build is:

ISDEV : fatal error -6199: Internal build error

Not a very informative error, and not much in terms of diagnostic information out there on the web or in Flexera's KB.

I was finally able to track down the cause: character encoding. The .ism is (typically?) supposed to use a UTF-8 encoding, but there are some caveats. If you are editing the .ism directly (e.g. Notepad), your editor /may/ be encoding it in a format that the IS standalone compiler doesn't understand, an you end up w/ a -6199. Adding to the frustration is that it may compile w/ some standalone builds, including the IDE, but will fail on others for reasons unknown.

Regardless, the simplest solution is to open the offending script in the ide and then force a save. Alternatively, you can edit the file with a binary editor and remove the leading "" from the line 1.

Friday, March 5, 2010

Router Throughput Issues

We have a small office network and recently became aware of some substantial Internet<->network slowdowns. I spent some time trying to isolate the issue and found the culprit to be our Cisco VPN Router (RVL200). When the 'firewall' option was enabled, external traffic was slowed by a factor of 10. Granted the RVL200 is a low-end business-class router, but a slowdown of 10x is beyond the pale.

Our Internet connection speeds are rated at 20/1.7 MB/s by our ISP. Here's my findings:

ISP: Cox, cable broadband rated at 20/1.7 (download/upload).
Broadband Cable Modem: Motorola Surfboard SB5100, firmware version 2.3.6.0
Primary router: Cisco/Linksys RVL200 VPN Router, firmware 1.1.10.1
Router: Linksys Wireless G Broadband Router WRT45GS v7, firmware 7.50.8
Router: Netgear Wireless-G Router WGR614 v10, firmware 1.0.2.4_39.0.39NA

Speed test: http://www.speakeasy.net/speedtest
My location: Las Vegas
Test location: Los Angeles
Methodology: Asus netbook computer, Windows XP SP3, physical wired connection to devices, nothing else connected. Tests run a couple of times to confirm consistency.

Test 1: Surfboard: 14.13/4.85
Test 2: RVL200 (firewalled): 2.46/2.79
Test 3: RVL200 (not firewalled): 20.04/5.32
Test 4: RVL200 (firewalled, other settings disabled): 2.35/2.88
Test 5: WRT54GS (firewalled): 20.39/4.92
Test 6: WGR614 (firewalled): 20.8/5.41


Conclusion: the RVL200 doesn't have a firewall, it has a *brick* wall. We've since moved to a Sonicwall appliance for our VPN, so the RVL200 is looking for a new home...

Monday, January 4, 2010

Unable to Connect to SQL Server While VPN Active

I've had the following problem for quite some time now, and finally resolved. At first blush, it seems like a simple enough issue to resolve, but in my particular case, it wasn't.

Basically what happened is that I have an instance of SQL (Express) installed on my primary development machine that is used as part of design, development, and building of the various applications I'm working on. I also have need to connect to a particular customer network via VPN (Aventail/SonicWALL). Everything was working fine until a few months ago when the customer updated the VPN client (from 9? to 10), at which point I was no longer able to access my SQL instance through trusted connection.

For example, if connected to the VPN and attempting a command line query, I'd see the following:

C:\>osql -S localhost\sqlexpress -q -E
Login failed for user ''. The user is not associated with a trusted SQL Server
connection.

In checking the event log, I'd see the following error:

SSPI handshake failed with error code 0x8009030c while establishing a connection with integrated security; the connection has been closed. [CLIENT: nnn.nnn.nnn.nnn]

If I disconnected the VPN, the above works as expected (no error).

?

My first conclusion was that the new VPN client was tunnelling ALL traffic through the appliance, and local requests back to my machine, and therefore SQL was considering the request as 'remote' and denying it. I tweaked the necessary SQL properties to allow remote connections -- nada.

After spending a lot of time trying to diagnose, I temporarily gave up and just resolved that I'd either be able to do VPN work or SQL work, but not both simultaneously.

Not satisfied with that 'solution', I resolved to spend more time on it. I'll leave out the countless things that I did try and didn't work and mention what I did find that actually solved the problem for me -- hopefully it will help someone else:

I started looking at the SQL configuration a little more closely (Start Menu\Programs\Microsoft SQL Server 2005\Configuration Tools\SQL Server Configuration Manager) and noticed some differences from some of the other typical SQL installations I have floating around. Specifically:

Under SQL Server 2005 Network Configuration: all protocols were enabled.
Under Aliases, there were several aliases using the tcp protocol.

I reset the above to coincide with what appears to be the default configuration:

SQL Server 2005 Network Configuration
  Shared Memory - Enabled
  Named Pipes - Disabled
  TCP/IP - Disabled
  VIA - Disabled

Deleted all SQL Native Client Configuration Aliases.

After that, my VPN/SQL issues were resolved! I'm not exactly sure what was the cause (protocol or alias), but a little more post-fix experimentation leads me to believe tha that the aliases were the problem. How that relates to the updated VPN client, or if it was purely coincidental, I don't know, but it is fixed and I'm satisfied!

Friday, November 13, 2009

Agile Development & "When will it be done?"

I've been doing XP/Agile development & management for 5 years now, and I've come to the conclusion that as soon as you have to answer "when will it be done?" you are back on the path to Waterfall.

Friday, October 16, 2009

What is the meaning of GC.KeepAlive()?

What is the purpose of GC.KeepAlive(object obj)? From the method name, it sounds like it will keep obj from being garbage collected after the call. In fact, the opposite is true, it will keep obj from being garbage collected before the call. On the face, that sounds like a pretty absurd method, doesn't it.

The problem is that the method is named incorrectly. Better, but more verbose, names would be GC.MakeExplicitlyElligibleForGarbageCollection() or GC.DontCollectObjectBeforeNow().

So, what's really going on here? As you are presumably well aware, memory is reclaimed in the .NET framework through garbage collection, which can happen at any time, for any object that has no outstanding references (but don't confuse with reference counting). For example:

public void SomeMethod()
{
 SomeClass o = new SomeClass();
 GC.Collect(); // no references to 0, it may be collected
 return;
}

Not very exciting, and makes sense, right? o isn't being used after the point of instantiation, so the collector is free to clean it up and reclaim the memory*.

But suppose that for some reason or another you need o to remain 'alive' until after SomeMethod() exits. In order to guarantee that, you would need to add some reference to 0 at the end of the method so that it can't be collected. That is the purpose of GC.KeepAlive().

So, all that GC.KeepAlive() does is create an artificial reference to 0 so that it can't be collected prior to the GC.KeepAlive() call:

public void SomeMethod_V2()
{
 SomeClass o = new SomeClass();
 GC.Collect(); // reference to 0 below, it will NOT be collected
 GC.KeepAlive(o);
 GC.Collect(); // no more references to 0, it may now be collected
 return;
}

So, hopefully the above makes it clearer what GC.KeepAlive() does, although we do need to figure out a better name...

*Note: In order to facilitate debuggers, when an application is compiled in Debug mode, the JIT will NOT collect locally-allocated instances until after the method exits. So, in this example, if compiled under Debug, o will never be collected until after SomeMethod() returns. In Release mode, locally-allocated instances can be collected after the point of last reference, even before the method has returned.