This TLA (Three Letter Acronym) littered post is about how to add PDB (Program
DataBase) files to the GAC (Global Assembly Cache).
Today my current client had the need to get the true source of an exception.
They had a catch statement which logged the exception (via log4net) to a file, but
the location in question was a poorly designed component with hundreds of lines of
code all wrapped within a very large Try-Catch which logged errors. The error
was likewise unhelpful as to the source because it was an array out of bounds exception,
and this code did alot of string array manipulation. The solution was clear
to me, we needed to load the PDB files onto the server so that when an exception was
thrown there would be line number information to go with it.
The problem? The assembly was being called by BizTalk Server and as such it
was strongly named and in the GAC.
The solution? Add the PDB files to the GAC, of course.
The Global Assembly Cache which is located at %WINDIR%\assembly (“c:\windows\assembly”
on most boxes) is in fact organized into many different directories all of which exist
under %WINDIR%\assembly but which by default are hidden from view by Explorer.
Fortunately, the command prompt does not suffer the same problems. If you open
a command prompt and “cd %windir%\assembly” and do a “dir” you will see several
directories as you can see in the first image.
you change directory to “GAC” you will see a directory for every single assembly in
the GAC. From here, cd to the directory for the assembly you want, in my example
nunit.framework, and you will see another interesting set of directories. Here
you will see one directory for every combination of version number and public key
in the GAC. You need to know what version you are working with, and the public
key for that. cd into that directory and you will find a copy of your assembly.
Now all you have to do is copy your PDB file to this location and your next exception
should contain line numbers for the offending code.
Since the work to generate line numbers is only done when an exception is being thrown
there is little to no reason not to include the PDB files in all your production deployments
to the GAC. Yes, generating them takes time, but if you’re throwing an exception
this shouldn’t be a problem. After all, you are treating exceptions as exceptional,
Tom posted some pictures of the event here. Cool!
Ingo posted the demos he so brilliantly gave on his blog.
We had a client incident where there was an issue with the BizTalk WSE adapter that was resolved by the BizTalk WSE Apadter Service Pack 1. The comment from someone on the product team was that not many people seemed to know about this service pack, even though it had been available for some time.
So, there you go, I’ve done my bit to get the word out 🙂
Show of hands, who has opened up a map created by someone else and been filled with
dread at the concept of modifying the map, even for something relatively simply.
I’m willing to bet the answer is nearly everyone who has ever done mapping.
It usually starts when you open a map and see something like this:
[Yes, that is from a real client. No, I won’t say who.]
As if that alone wasn’t enough to make one cry, layouts like that lead to property
dialog boxes like this:
So to help you avoid leaving wonderful presents like these for someone else who follows
you onto your projects, I’d like to suggest the following guidelines to follow when
you are working with the Mapper.
- Organize on Pages – The Mapper will allow you to create an infinite
number of pages on which to organize your maps. You should use this to great
advantage. Find a system of organization that works for you and stick with it.
The two most common systems are a “destination structure” approach where a page is
used to organize the contents of a particular element on the destination schema and
the “mapping concepts” approach pages tend to get names like “Direct Links” and “Looping”
to indicate that type of mapping that is occuring on that page. Personally I
like to mix the two depending on the problem in front of me.
- Label your Links – If you select a link (a line) in the mapper and
look at the Properties window you will see that it has a property named “Label”.
This is the most under used property in all of BizTalk. If you label a link
(and a label can be any string value) then when you open the properties dialog box
of your next functoid you will see the label next to the icon, rather than the above
property box you’ll end up with something like this:
I’ve realized that I never understood the full potential of the Visual Studio Database Project. None of the projects I’ve worked on has had a effective process on handling changes and versioning of the database schema. Test data, build scripts, changes to the local development database versus the test and production base has also been a bit bumpy. I’ve haven’t understood that working with the Database Project potentially could solves a lot of these challenges .
A chapter from the Database Access with Visual Basic® .NET book describes some features in the Database Project.
I’ve realized that I never understood the full potential of the Visual Studio Database Project. None of the projects I’ve worked on has had a effective process on handling changes and versioning of the database schema. Test data, build scripts, changes to the local development database versus the test and production base has also been a bit bumpy. I’ve haven’t understood that working […]
A while ago Microsoft released the CSS Control Adapter Toolkit for ASP.NET 2.0. It finally makes it possible to use all the time saving ASP.NET controls in 2.0 without all the horrible HTML they used to produce. The toolkit gives access to the now improved source of the following adapter controls:
Make sure to have the […]
Recently I was working with a custom pipeline component in BizTalk 2006. As you know, a change was made to how these components behave in BizTalk 2006. That is, now they can be placed in the GAC as well as in the \Pipeline Components directly. So what does this mean? Put them in both place, one place, who knows?
In general, the rule is when working with custom pipeline components on a development system put the components in the \Pipeline Components folder and put them in the GAC on non-development systems. Although this is not really the approach the help guide says (under Developing Custom Pipeline Components), this approach works great since it simplifies deployment.
Today, I found a big GOT YOU with this approach if the custom component is not GACed before it is used inside the designer. All in all, you must GAC the custom pipeline components as soon as your create them and BEFORE adding them to the Visual Studios Toolbox.
Let's take a look at what happens when you add an unsigned and unGACed custom pipeline component to a project.
When you add the component to the Toolbox and drag it into the design surface, a reference is added to the pipeline component. As seen below, when the component is not signed and not in the GAC a reference is added to the component in the \Pipeline Components folder.
Fig 1: Unsigned and unGaced
Now, let's take a look at what happens when you add a signed and GACed custom pipeline to a project.
When you add the component to the Toolbox and use it in a pipeline, a reference is added to the pipeline component (as before). But this time, the signed and GACed pipeline is referenced to the GACed version of the pipeline component as seen below.
Fig 2: Signed and GACed
So why does this matter? Well, the problem I ran into was I added my custom pipeline component to my pipeline before I signed and GACed it. So when I went to deploy my solution to the development server with the pipeline component only in the GAC, I got a .net error saying it could not find the pipeline.
Something else to point out is that the pipeline must be GACed before you add the pipeline component to the Toolbox. Just being signed is not good enough.
The moral of the story: If you only want to put your component into the GAC and not into the Pipeline Component folder make sure you GAC it before you use it.