Thursday, July 09, 2009

image I've written here about how to embed arbitrary fonts in a flash file. This approach works, but it has several downsides.

  1. You have to have Flash. It's not necessarily cheap.
  2. You have to go through a pretty arduous process to embed the fonts.
  3. You end up with a swf file that can be quite large, especially if you have a lot of fonts you need to embed. This can have a very negative impact on your bandwidth and the user's experience with your site.

I understand that SilverLight has a method for using embedded fonts as well, though I've found very little information on it.

But I did recently come across True Font Family.

It's not a 100% solution, since it essentially replaces specifically styled text on your site with dynamic images of that text in the font of your choosing. But, it's got some great benefits.

  • It's cheap, as in 27$, no royaties
  • It's easy. Just a simple Javascript include, and a little CSS markup.
  • It's double plus easy. You just upload the fonts you need to use as TTF files to your webserver somewhere. No messing with conversions of any kind. And since the fonts you use can be locked up in a secure spot on your server, there's no worries of font use violations that might come from allowing end users to actually download the fonts you need for your site.

Plus, they've got a newer version coming out sometime in the fall that'll do all sorts of special effects on the text as it's rendering it.

Depending on your needs, this might be a very viable alternative to Flash.

posted on Thursday, July 09, 2009 8:51:51 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 

One project I'm working on now involves showing a "preview" of a user's selected options in a window on a web page.

The options involve font selection, styles (bold, italic, etc), color, and even mirroring (reversing the text as if it was going on the inside glass of a window).

Most of that would be relatively easy in javascript and CSS, except for the font.

How the heck can you display fonts to a user that doesn't actually have those fonts installed on their machine?

Well, there's likely a number of different possibilities, but Flash represents one of the cleaner (if not mind-bogglingly complicated) approaches to the problem.

There are a number of articles on the web concerning embedded fonts in flash, so I'll try not to rehash that here. But there are a few gotchas that proved very difficult to hunt down, with virtually no mention of them on the web that I could find.

The Setup

First, I'm using Flash CS4 and ActionScript 2.0.

Create two files in Flash. I called one Test2.fla and the other Fonts.fla.

image

The Fonts.fla will be our external Fonts Resource file. Why external? Why a separate file? Well, technically, once you've gotten your fonts together, it'd be nice to not have to continue to have them installed on your machine. Separating the fonts from the flash files that will use them allows you to build the font resource SWF file once, remove all those fonts, and then still be able to work on your actual Flash file (the one with your actual movie/code in it).

Note the properties for my actual movie fla file:

image

Its basically the same settings for the Fonts.fla file, although, technically you could set it as ActionScript 3.0, I suppose. There's no script necessary for the Fonts.fla file.

Setting Up The Fonts.FLA file

Switch to the Fonts.FLA file and show the Library. Press Ctrl-L to show it if it's not already showing.

Then, Right Click in the empty space and choose New Font:

image

You'll get the Font Symbol editor window. This is where the magic happens (or doesn't, if you get it wrong).

image

There's a lot going on here, so, starting at the top.

  1. The NAME field must NOT be left as just the name of the font, no matter how tempting that may be. I suffixed the normal version of every font I embedded with "Normal", but it doesn't really matter. Just make sure it's NOT the actual name of the font.
  2. The Font field just allows you to pick the font. This means the font you want to embed MUST be actually installed on the machine. A pain, but that's what ya gotta do.
  3. The Style box will only be enabled when the font you've chosen actually has a specific style (Bold, Italic or Bold Italic) defined within the font itself. Most fonts don't, so this box will likely be disabled. If it IS enabled, choose whichever style you need to embed.
  4. The Faux Bold and Faux Italic checkboxes are enabled when the font doesn't already define a Bold or Italic style. if you want bold or italic, check the appropriate box. HUGE NOTE: These boxes are ANDed, which means if you check both, you get a faux BOLD/ITALIC font. You do NOT get a bold version of the font and an italic version. This is very important and I'll get to why in a bit.
  5. You'll need to check the "Export for ActionScript", and when you do so, the Identifier field will enable (for ActionScript 2.0 at any rate). Be sure that the name entered here IS NOT the actual font name. It needs to be something different. I usually make it the same as the NAME field above.
  6. And finally, check the Export for Runtime sharing. Since this is going to be an external font resource swf file, we need to export the font so other SWF files can reference it.

I didn't mention the SIZE file. I've put 30 there, but, from what I can tell, you should be able to put just about anything you want. The process of embedding the fonts actually converts the glyph vector outlines into a Flash friendly format, but they're still vectors, so they can essentially be scaled to any size.

That said, often at small sizes there are hints embedded in the font for particular sizes that might not make it into the embedded font vectors. I'm no font expert though, so I can't be sure of this.

Fonts, Fonts

What if you need more than one font? What if you need the Bold version of a font? What if, heaven forbid, you need the normal, bold, italic and bold italic versions of the font?

First off, even though it may alarm the Flash purists out there, there are occasions when such things are necessary. The downside, however, is that your fonts.swf file could get rather large quickly. The reason is that you're actually embedding all the font glyphs into the file. But it's worse than that.

Flash, treats every style of a font as a completely separate font. So, if you want normal and bold, well, that's two fonts. Normal, Bold and Italic? That's three complete sets of glyphs. Normal, bold, italic and bold italic? That's 4 complete sets of glyphs for that font.

Needless to say, the swf file can get large fast. Something to be aware of at any rate.

So, let's say you want to include the BOLD version of Tahoma.

image

Just repeat the above steps, but with Tahoma, the STYLE combobox is enabled (Tahoma has the Bold style predefined). Drop down the Style Combo and select Bold. Then, make sure the Name and Identifier fields are set to SOMETHING OTHER THAN "Tahoma". I just used "TahomaBold" to keep things simple.

Now, repeat those steps for EVERY FONT and EVERY STYLE of font you want to embed. What's worse, I looked for quite some time for any way to automate this process and failed. The only way to do it that I could find was completely manually. Yuck!

In the end though, you should have a library pane that looks like this (I've dragged all the fonts into the Fonts folder, but you don't have to).

image

Again, the KEY TO THIS is that NONE of the font NAME fields or the IDENTIFIER fields can be the same as the actual font.

Flash is smart enough that when you ask for "Tahoma" with a style of Bold, it'll match things up properly. But if any font is actually named "Tahoma" (i.e. in either of those two fields), Flash will only ever choose that particular named font/style, regardless of what you might ask for. Peculiar, yes, but that's what it appears to be doing.

posted on Thursday, July 09, 2009 8:26:42 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 

In case you've missed it, MSBuild is, essentially, the "new" version of that most ancient of build tools, MAKE.

Basically, it's just a way to script out the steps required to build a project from end to end, possibly including

  1. Retrieving files from a Source Respository
  2. Altering them and checked the changes back in
  3. Compiling various application projects
  4. Copying files around
  5. Compiling an installation
  6. Sending email notifications of the build success or failure

and a host of other possibilities.

In the good ol' days of MAKE and NMAKE, you had to use a particularly arcade file format to describe all this.

With MSBuild (oddly enough, it appears to come bundled with the .NET runtime, instead of one of the dev tools like Visual Studio, why is beyond me), you now configure everything through a relatively nice to look at XML file, usually named with a PROJ extension.

While MSBuild is fairly capable in it's own right, there's quite a number of things that typically need to happen during a build that it can't handle directly, such as manipulating the contents of files, setting environment variables, etc.

That's where the very thorough MSBuild Extensions pack comes in. Be sure to install it, then read the help file on how to hook up the XML Schema's so that Visual Studio can show Intellisense for the extra functionality. It just requires copying a few XSD files around, so I won't go into that here.

The Problem

One of the first things I had to do with the Extension Pack was alter the content of an RC (resource script) file that contains the version I need to use when stamping the files with a version number. I use a single, shared RC file so that it's easy to update the version number for all files in the build.

My first shot was something like this:

   <Target Name="UpdateBuildNumber">
      <MSBuild.ExtensionPack.Framework.DateAndTime TaskAction="GetElapsed" Start="1 jan 2000" Format="Days">
         <Output TaskParameter="Result" PropertyName="BuildNum"/>
      </MSBuild.ExtensionPack.Framework.DateAndTime>
      <Message Text="Build Number to use: $(BuildNum)"/>

      <ItemGroup>
         <CommonRCFile Include="Common.rc" />
      </ItemGroup>

      <MSBuild.ExtensionPack.FileSystem.File TaskAction="Replace" RegexPattern="(?'Leader'\#define BUILD \s*).*" Replacement="${Leader}$(BuildNum)" Files="@(CommonRCFile)" />
   </Target>

The Resource file itself looks like this (a snippet):

#define MAJOR          1
#define MINOR          5
#define REVISION       0
#define BUILD          100


#define COMPANYNAME       "My Company"
#define PRODUCTNAME       "My Product"

What I was looking to do was replace that "100" for the build number with a number that corresponded to the number of days since Jan 1 2000, which would yield a nice number around 3470+, decent for a contantly incrementing build number and it fits within what a resource file can declare for the BUILD field.

I ran it can immediately ran into the first problem. The elapsed days was being returns in floating point,  so I got a days value of something like 3745.5763527589. That would definitely NOT going to work as a build number.

After some tinkering, I ended up having to add a string SPLIT action to split off the integer days part, as in:

<MSBuild.ExtensionPack.Framework.TextString TaskAction="Split" String1="$(BuildNum)" String2="." StartIndex="0">
   <Output PropertyName="BuildNum" TaskParameter="NewString"/>
</MSBuild.ExtensionPack.Framework.TextString>

The trick here is that "StartIndex" property. That indicates which part of the split up string you want returned into the "Output PropertName" named property. A 0 means the first split element. Since I'm splitting on a "." that will give me the number of days with no fractional portion.

I'm sure there's a better way to do this, but I haven't dug it up yet.

One problem down, so I ran the build and everything appeared fine till I compiled the RC file, at which point I got a very strange error about the file having unexpected values.

So I pulled up Araxis Merge to compare the old and new versions of the file, and something peculiar had happened. For the resource COPYRIGHT and TRADEMARK entries, I had used the copyright and registered ascii symbols (Ascii characters 169 and 174), but once the file went through that ExtensionPack FileSystem Replace action, those values had changes to something else entirely.

I suspected encoding was the culprit, and sure enough, there is a TextEncoding property for the Replace Action that apparently can control the encoding that is performed.

Ok, just find the right encoding...

  • I tried UTF8.... Not recognized
  • UTF-8...Recognized but same result
  • ASCII...recognized but totally scrambled other parts of the file.
  • ASCII-8... not recognized
  • ASCII8... not recognized.
  • US-ASCII...recognized, but just converted the suspect characters to ? chars.

At this point, I'm starting to get a little annoyed.

Eventually, I stumbled across a blog post that mentioned a "windows-1252" encoding and sure enough, Success at last! The build number is replaced, but the rest of the file is left as it was.

So the target entry I ended up with was:

<Target Name="UpdateBuildNumber"> <MSBuild.ExtensionPack.Framework.DateAndTime TaskAction="GetElapsed" Start="1 jan 2000" Format="Days"> <Output TaskParameter="Result" PropertyName="BuildNum"/> </MSBuild.ExtensionPack.Framework.DateAndTime>

<MSBuild.ExtensionPack.Framework.TextString TaskAction="Split" String1="$(BuildNum)" String2="." StartIndex="0"> <Output PropertyName="BuildNum" TaskParameter="NewString"/> </MSBuild.ExtensionPack.Framework.TextString> <Message Text="Build Number to use: $(BuildNum)"/> <ItemGroup> <CommonRCFile Include="Common.rc" /> </ItemGroup> <MSBuild.ExtensionPack.FileSystem.File TaskAction="Replace" RegexPattern="(?'Leader'\#define BUILD \s*).*" Replacement="${Leader}$(BuildNum)" Files="@(CommonRCFile)" TextEncoding="windows-1252"/> </Target>

One final comment. This required messing with .NET regular expressions, which I'm certainly no expert on.

I ended up coming across a very handy Regular Expression Tester by Francesco Balena (a favorite author of mine from way back), called YART. One .net EXE, just unzip and use. Supports find and replace, plus has context menus for all the various .NET Regex syntax bits and pieces. This definitely saved me a pile of time.

My opinion is still up in the air about MSBuild, but, with the Extension Pack, its capabilities are certainly quite formidable.

Give it a shot!

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

VB has long been my favorite development language, but, as is typical, even it can definitely be improved in innumerable ways.

One aspect of VB that has always bothered me is string literals. Since VB treats EOL as significant, you can't have strings that wrap across multiple lines in the environment. This is especially problematic when you deal with SQL queries, report formatting strings, and the like. For instance, this is generally what you see when you have to deal with long SQL queries in VB code.

Dim q as String = "Select *" & vbcrlf
q &= "From MyTable" & vbcrlf
q &= "Where MyColumn = 1"

Now, you can do a few formatting tricks and clean it up a little, but even then, it's going to be cumbersome to work with.

One workaround has always been to embed these long, multi-line literals in a Resource file. The VS 2008 IDE even goes so far as to allow you to enter multi-line strings in the resource editor, although you have to use Ctrl-Enter to get a new line:

image 

If you look at the RESX file for the above resource, you'll see something like this:

image

All this is certainly workable, and, in many cases, isolating strings to a resource file (of some sort) can be a really good thing, but in other cases, it's just a pain.

In VB10, Microsoft is finally doing what VB should have done all those years ago. They're adding "intelligent line continuation" which is to say, you can continue a line in certain syntactic situations simply by continuing the code on a new line. No need for the line continuation underscore char, etc.  It won't necessarily work everywhere (esp in places where it the code would end up ambiguous), but hey, that only makes sense.

In the meantime, you can actually have multi-line string literals in VB.Net without too much pain.

The trick is to use XML Literals. Generally, I'm no fan of XML literals. Once they get peppered with variable references, embedded For loops and other code, they become just so much spaghetti code, albeit with a modern twist.

But, they can be handy for multi-line string literals.

Dim q as String = <String>Select *
From MyTable
Where MyColumn = 1
</String>.value

So what's going on here? First, I dim the result variable Q as a string (technically, this isn't necessary as VB can infer the type, but you get the picture).

Then, I declare the XML Literal with the <String></String> tags. Everything between those tags (even across lines), gets treated as part of the string, no quotes or line continuation needed.

Finally, since the result of the <String></String> tags is going to be an XElement object, and what I want is a string, I need to invoke the value property of the XElement object to retrieve its string value.

And there you go.

But, as with anything good, there are a few caveats.

  1. line breaks AND whitespace are preserved in the string, which means if you indent those lines, you'll get space characters where you might not have wanted them.
  2. if you want to include certain characters that are illegal in XML (for instance, the "<" or ">" characters), you'll need to escape them.

Handling Escape Characters

One option you have for handling escape characters is to use the XML escape sequences, as in:

Dim q as String = <String>Select * as My&gt;Test&lt;var
From MyTable
Where MyColumn = 1
</String>.value

The &gt; and &lt; will be replaced with > and < respectively. You can escape any arbitrary character with &#nnn; where nnn is the ascii code of the character.

But this is code, dammit, not XML, and, at least for me, I'd much rather see normal C-style escape sequences (\r\n anyone \:\-\) ) here than have to muck with XML "&" sequences. If we're talking about web pages and HTML, that might be a different story, though.

At any rate, you can have your cake and eat it to, as it turns out.

Just feed that string through System.Text.RegularExpressions.Regex.Unescape to convert those sequences, hence:

Dim q as String = System.Text.RegularExpressions.Regex.Unescape(<String>
Select * as MyTestvar \r\n From MyTable Where MyColumn = 1 </String>.value)

Notice how the XElement.value is simply passed through to the Unescape method to process that \r\n into a normal carriage return/linefeed pair.

Using that, you can now easily embed C-style escaped multi-line strings in your VB code.

But wait, that Unescape call is fairly nasty to look at and use. Wouldn't it be nice if that was more or less automatic? Well, with a nice Extension Method, it can be.

<System.Runtime.CompilerServices.Extension()> _ Public Function UnEscaped(ByVal v As XElement) As String Return System.Text.RegularExpressions.Regex.Unescape(v.Value) End Function

.....

Dim q as String = <String>Select * as MyTestvar \r\n From MyTable Where MyColumn = 1 </String>.Unescaped

First, define an Extension Method that would apply to the XElement object. This is a very simple method that just takes the associated XElement object, retrieves it's value, and runs that string through the Regex Unescape method.

Since the extension method extends the XElement itself, you can now simply call the Unescaped method directly on the long string definition (the very last line in the code above).

You can't get much cleaner than that. Or can you? Let me know!

posted on Monday, July 06, 2009 6:54:14 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; 
 Thursday, May 21, 2009

image Sad news from several days ago. Apparently, 3D-Realms, the team behind the original Duke Nukem 3D, has called it quits.

I'd known the follow-up to the original was long overdue, but I guess there were more problems than just getting the code done.

At any rate, in reading about this story, I discovered something very cool. A complete port of the original Duke Nukem 3D, targeted for Windows, called EDuke32, using all modern support code, including updated audio drivers, and support for OpenGL rendering engines.

Not only that, but there's a whole fan base that have re-rendered all the level textures in full hi res! The difference is absolutely astonishing and really breaths new life into a wonderful old game. I actually found a deathmatch level I'd designed back in the day (sept 22, 1996 to be precise, the file still had the last modified date on it), loaded it up with EDuke32 and, with the textures from the hi-res pack, it looked spectacular. Far better than it ever did originally.

If you were a fan of Duke back in the day, it's definitely worth the download.

posted on Thursday, May 21, 2009 9:45:37 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; 
 Monday, May 04, 2009

image I had the opportunity to take on a Flash project recently. Never touched Flash before but I'd had it ever since I picked up a copy of Dreamweaver MX (the 2004 version, version 6, I still use FireWorks regularly).

From what I can tell, there's been lots of improvements to Flash and ActionScript, but mostly in the areas of video and multimedia, which, for this, I didn't need.

The idea is to create a preview of a text message, with font selection, sizing, coloring, etc. Initially, maybe only a half-dozen options, but eventually, incorporating a plethora of options (wavy text, anyone?).

It took a good deal of web queries and tinkering to get past the initial Flash hurdles (like how the heck to you actually place a movieclip onto the stage, much less create a new movieclip!). Is it just me, or is making the user "create a new symbol", a completely non-intuitive way of creating a new movie clip? Maybe it's just the old version. But I'm not sure I want to pay big $$$ to find out if any of that non-sense ever got straightened out.

Initially, I'd placed a chunk of code in the action area for the main frame, (there's only one frame in this "movie"), but when I ran it, I happened to notice that it was being run over and over again. I'm guessing that's because Flash, is, at it's heart, an animation/movie creator, so that made a certain amount of sense.

I also found through combing the help file, that what I probably needed was the OnClipEvent On Load event. But that was only available on an actual movie clip object, and I couldn't seem to create one of those.

Long story short, I've gotten something working in relatively short order, it was less painful than I expected, and in the process, I've gained a whole new level of appreciation for those guys out there cranking out Flash games.

posted on Sunday, May 03, 2009 11:06:25 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Monday, April 13, 2009

Working on a VSTO 8 Word addin recently, I discovered to in order to deploy it, you must "strong name" the assembly.

I'd already obtained a Verisign certificate for digital code signing, and had a password protected PFX file containing both my public and private keys, so I figured I had what I needed.

So, I loaded the project, set the signing options to use my PFX file and compiled.

Full stop.

"Interop.Word.dll" is not strong named

Doh.

A little research later and it turns out that if you strong name one assembly, every single assembly that it references must also be strong named!

Yikes. In my case, I have almost a dozen, plus piles of interop assemblies for accessing legacy COM libraries.

First, the .NET assemblies. Setting them to be strong named using the same PFX file is easy, just use VS, under the project properties.

image

But, if your .net code refers to any COM components, it's very likely you also have references to "interop" assemblies. These are DLLs that VS creates for you "behind the scenes" to act as convenient .net wrappers around the COM library objects.

The problem is that VS won't automatically strong name those interop assemblies, and if you strong name your .net assembly, those interop assemblies also must be strong named.

First, I tried just creating an interop assembly.

I chose the Word 2000 object library to initially play with, but just about any COM dll or TLB or OLB file will do.

tlbimp "{path}\msword9.olb" /verbose /out:Interop.Word2000.dll /sysarray

(note, {path} is the path to your copy of this file, and the /sysarray option appears to be required if your working with just about any COM based interface). Worked like a champ.

So, I add in the keyfilename argument:

tlbimp "{path}\msword9.olb" /verbose /keyfilename:mycert.pfx /out:Interop.Word2000.dll /sysarray

and TLBIMP responds with an "Incorrect strong name arguments specified" error.

I then tried the PUBLICKEY option, like so:

tlbimp "{path}\msword9.olb" /verbose /keyfilename:mycert.pfx /out:Interop.Word2000.dll /sysarray

This appeared to work, until I actually tried to run my application. It failed, indicating that the "Strong Named Assembly was corrupt or was not signed with a private key". Apparently, PUBLICKEY means just that, that the public key is used for one part of the signing process, and that you have to use a private key for the other.

I really didn't want this to be a two step process so I kept looking.

Eventually, I discovered that signing an assembly is a completely separate process from "Strong Naming" an assembly.

Strong Naming an assembly doesn't guarantee that you wrote it, but it does provide a way for one assembly to guarantee that it is loading the exact same assembly that it was compiled to work with, a subtle but significant difference.

Signing an assembly, on the other hand, requires a certificate from a signing authority, like Verisign. Signing does guarantee that an assembly was written by who the certificate says it was written by.

From what I can tell with VS2008, signing an assembly automatically strong names it, but the reverse is not true.

And certain assemblies need to be signed, (such as the primary assembly for an Office Addin), but others don't.

And still others need to be strong named, but don't necessarily need to be signed (such as any assembly or interop assembly referenced by an Office Addin.

But when you do this, you might notice that you end up with another unexplained dll in your output folder, called Office.dll.

After some digging, it turns out that TLBIMP will also create interop files for those COM libraries referenced by the COM library that you're creating an interop file from. And you'll need to include those additional interop files with your app for everything to load properly.

This is where the /reference option comes in. First, generate a strong named interop file for the referenced COM library, and then for the COM library you actually care about, like so:

tlbimp "{path}mso9.dll" /out:Interop.Office2000.dll /sysarray /verbose /keyfilename:mycert.snk 
tlbimp "{path}msword9.olb" /out:Interop.Word2000.dll /sysarray /verbose /keyfilename:mycert.snk /reference:Interop.Office2000.dll

The first line will create the Interop file for the Office.dll, which is referenced by Word.

The second line will create the interop file for Word itself, but note that it uses the /reference option to indicate that this interop file should reference the just created interop file for the Office library.

Finally, a note about namespaces. You'll notice that I specified an OUT filename of Interop.Word2000.dll.

TLBIMP appears to automatically assume that when you do that, you want the classes defined within that interop file to exist within the "Interop.Word2000" namespace (ie the file name minus the ".dll").

image

This may be appropriate, but it may not be, depending on your needs. Why might you want to change it? The only reason I can think of offhand is that you are referencing multiple versions of a single COM interface. A common example would be the need to reference both the Office 2007 Primary Interop files (available directly from Microsoft), and the Office 2000 interop files you created yourself (because MS doesn't provide them).

It is possible that the two Interop files would have the same namespace and would collide.

Changing the namespace of one of them will allow your assembly to reference both interop files with no collisions. This is one element of .net that is, at the same time, unfortunately complicated, but incredibly useful.

posted on Monday, April 13, 2009 9:18:42 PM (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;