Robert McLaws: FunWithCoding.NET

Public Shared Function BrainDump(ByVal dotNet As String) As [Value]

News

<script type="text/javascript"><!-- google_ad_client = "pub-4330602465258980"; google_hints = "ASP.NET, VB.NET, C#, C#.NET, WindowsForms, .NET Framework, VS2005, Visual Studio, XAML, WinFX, Windows Workflow, WPF, WCF, Atlas, NetFX3, Visual Studio Orcas"; google_ad_width = 120; google_ad_height = 240; google_ad_format = "120x240_as"; google_ad_type = "text_image"; google_ad_channel ="4997399242"; google_color_border = "B6C9E7"; google_color_bg = "EFEFEF"; google_color_link = "0000FF"; google_color_text = "000000"; google_color_url = "002C99"; //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<!--
-->

You should feel free to challenge me, disagree with me, or tell me I'm completely nuts in the comments section of each blog entry, but I reserve the right to delete any comment for any reason whatsoever. That said, I will most likely only delete abusive, profane, rude, or annonymous comments, so keep it polite, please.

Blogroll

Cool .NET Articles

My .NET Tools

My Builder.com Articles

My MSKB Articles

March 2004 - Posts

My First (And Last) Experience With ComponentOne

I'm going to take off my component vendor hat for a minute, and talk about my experience as a customer of ComponentOne. I'm going to try to be objective about this here, and over on my corporate blog, I'll talk about how that experience will alter the way my own company does business.

As many of you know, I've been working on a new tool called VisualBlogger 2004. One of the features I really wanted it to have was the ability to check the spelling of a post. Now, I've seen articles on how to do it with Word... blah blah blah. I wanted a decent spell-checking experience without having to write a lot of code. A few months back, I had received the Visual Basic .NET Resource Kit from Microsoft. It said it had a bunch of free controls in it, so I finally decided to install it, and see what goodies I could add to the tool to beef it up.

After an extremely lengthy installation process, I finally had a the kit installed. But it didn't install any of the components, it just copied a bunch of installers to the hard drive, without so much as a single detail on how to install them from there. Poor planning on Microsoft's part. Should have had an integrated installer. So I install the different libraries individually, and finally I get to ComponentOne.Spell for .NET. I'm thinking, "man, this could really be useful, I can't wait to try it out." Looking over the features, I see that you can even do spell checking as you type, with the red squiggilys like in Word. By this point, I'm super excited. The party didn't last long.

Implementing the control was an OK experience. I didn't have as much flexibility as I would have liked. I had no control over the visual styles of the dialog box, which was about as unsexy as watching an obese woman digging a thong out of her butt while snacking from a tub of lard. The method of specifying a custom dictionary file was less than intuitive, and I thought the API was generally lacking in intuitiveness as well. Those were the least of my problems.

There was a method called CheckHTMLString that is supposed to accept an HTML string to check, and returned the checked HTML string. Well, they got half of it right. It accepts the HTML input just fine, kicks up the dialog box, and does it's thing. The only problem is, it returns the input as the output... the checked string doesn't get returned. Further, there was an array boundschecking error, and the component would always error out after all the words were checked. So I went online to their support newsgroup, and tried to investigate. Sure enough, both problems showed up several times. There was a fix available, so I went to download the fixed builds. Now the real fun begins.

The license that came with the VB.NET ResKit was for their Q3-2003 subscription. Well, three quarters have passed since then, and the license only lets you upgrade to the Q4-2003 edition. Well, the problem wasn't solved until Q2-2004. So now my license (Whereever it gets stored, I have absolutely no control over that) has been corrupted, and any new build I try to install throws up this retarded dialog box at runtime. I can't shut it off, I can't fix it, and I can't get a version of the spell checker that actually works.

So I write to the support team, very politely mentioning that the control was not working as advertised in the kit, and I'd like an upgraded license for just that component, so that I would get my project working. Their response:

Hi Robert,

Thank you for contacting ComponentOne Technical Support.
Regarding your query, Resource kit contains the version which are eligible for builds released prior to Q3 but since you would be requiring build 47 which is released in Q2 of year 2004, one can go in for our annual subscription offer from ComponentOne in order to use the build.  For more information on this, you may contact sales at sales@componentone.com

Let me know incase I could be of further help.

Regards
Sam

So, in other words:

We're sorry our component doesn't work. Since it was free anyways, you could hardly expect it to work EXACTLY as advertised. We don't give bug fixes away. To get a working version, please spend $700 and buy the full suite.

Sincerely,
Someone who knows very little about customer service.

Why would I wan't to buy the subscription at this point? This is how they keep a customer happy? This is how they take care of a community member and consultant with the power to persuade others to buy their products? How does that look on Microsoft, who allows ComponentOne to put these components into their resource kit?

I sent them an e-mail stating plainly that this was not an acceptable option. I wanted the component to work as advertised, and if they gave a subscription away, then I should get bug fixes for free as well. I didn't want new functionality, I wanted existing functionality that operated properly. I had thought that this was a reasonable request, and not out of the question. <shrugs>... I guess I was wrong. Two weeks later, and still no response. I forwarded the e-mail to their support complaints address. Two weeks later, still no response.

So, as I'm nearing a Beta 1 build of VisualBlogger, at this point I feel compelled to remove the Spell Checker and Thesaurus, since they offer no functionality at this point anyways. Which is really sad, because it would have been a great feature, and I would have loved to sing ComponentOne's praises. Oh well. I'm going to start looking for other spell checking options. If any of you out there know of any solutions that don't involve MSOffice, please let me know. And check my trackbacks shortly for my commentary with the component vendor hat back on.

And oh yeah, I would recommend avoiding ComponentOne. They seem to be more interested in taking your money than providing working components and adequate customer service.

Provider Model Test Post

This is a post testing the new provider model usage in VisualBlogger 2004. I've abstracted the system out, using a modified version of ScottW's .Text object model, so that I can map internal Entry objects into external objects as necessary. This particular test is using the primary DotText95BlogProvider, which uses the http://weblogs.asp.net/yourblog/services/aspnetweblog.asmx web service entry point. This one is still live in all distros, and has more functionality than the SimpleBlogService. It will be superceded by the dottextapi.asmx web service in .Text 0.96, but for now this works well.

I have been trying to test this for over 2 hours now, and I finally have a solution. I could not get the post configuration to work properly, and could not figure out why. Finally, I checked the enumeration as specified in the web service Reference.vb file. They were totally off. If you decide to use the web service in your own projects, you need to modify the file as follows:

1    '<remarks/>

2 <System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://www.aspnetweblog.com/services/aspnetweblogapi/"), _
3 System.FlagsAttribute()> _
4 Public Enum PostConfig
5
6 '<remarks/>
7 Empty = 0
8
9 '<remarks/>
10 IsActive = 1
11
12 '<remarks/>
13 IsXHTML = 2
14
15 '<remarks/>
16 AllowComments = 4
17
18 '<remarks/>
19 DisplayOnHomePage = 8
20
21 '<remarks/>
22 IncludeInMainSyndication = 16
23
24 '<remarks/>
25 SyndicateDescriptionOnly = 32
26
27 '<remarks/>
28 IsAggregated = 64
29 End Enum
VS.NET's proxy will create an enum with values "1,2,4,8,16,32,64,128", respectively. That's it from me this evening. Now that everything is working, I can actually go to sleep. More from me in the morning.
Imagine Cup Competition Today @ ASU
Just wanted to give a shoutout to Andy Lim at ASU. He's putting together the Microsoft Imagine Cup competition for Arizona State University, which I have the pleasure of judging in about 5 hours. I'm looking forward to seeing what the students come up with. I'll be gone the rest of the day, but when I get back, I'll blog about the experience, what I saw, who won, etc. Andy's worked hard to put it together. Good luck today guys!
Screenshots and Update for VB2004

Made some major headway in the past 24 hours, so I thought I'd show off where we're at so far. As soon as Jamie Cansdale gets back from his week-long ski trip (lucky bastard), I can wrap up the VS.NET integration code. Just so you know, VisualBlogger 2004 will operate in two modes: Standalone and IDE Integrated. You'll be able to use this program just like Microsoft Word if you want, or you can dock it in the same place as the Output window in VS.NET, and blog from the dev environment. You could even use it as a real simple HTML editor if you want. We don't have any table support yet (don't know if we ever will) but you could always add those in manually.

OK, now for the screenshots. The first one is of the main screen. I'll let VB2004 herself tell you about that herself..

The next dialog shows the cross-posting options. I want to add client-side category caching, but right now, I snag the categories from the web service ever time you hit the right-arrow button. If you only select items from the first list, it will post your entry without any categories. If you select options from the list on the right, it will post to each blog with the specified category.

This screenshot is of the code formatter. It's just a plain textbox to post code, and the 3 buttons on the right specify the syntax. It support C#, VB, and ASPX / XML / Config files. I may add code snippet library support at a later date, but it's not planned for the first release. You can see samples of the output in several os my previous posts.

Finally, the last screenshot is of our feedback form. Today I installed and configured Axosoft OnTime 3.0, and we're now using it as our central bug and feature management system. This form submits customer feedback right from that central system. When an exception is thrown, you will get an option to send error data to us. If you choose yes, the bottom box will be automatically populated with properties of the System.Exception class for further troubleshooting.

There is much more that I want to do before V1 goes live. After I'm done cleaning up the codebase, I'm going to hand it off to Brady Gaster, who is going to abstract the post model and implement BlogEngineProviders for me. Then we're going to add support for all the major blogging engines (dasBlog, Movable Type, Blogger, etc.) At that time, you'll be able to edit existing posts, since the existing .Text SimpleBlogService web service does not support getting existing posts to edit.

Well, that's about it from here. Hope you like it. It will be done soon, I promise. It really has made me much more willing to blog now that I don't have to log into 6 different web-based consoles. I hope it helps you guys too.

VisualBlogger CategoryPost Test #9

The WinForms adventure continues. The CheckedListBox control has been giving me all sorts of problems. For one thing, if you put one in a TabControlPage, and then switch pages, it doesn't hold its state. It took me a little bit of experimentation, but I came up with the following code to help out:

1    Dim chk1 As New ArrayList

2 Dim chk2 As New ArrayList
3
4#Region " OptionsTabPage.Leave Event Handler "

5
6 Private Sub OptionsTabPage_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
Handles OptionsTabPage.Leave
7 chk1.Clear()
8 chk2.Clear()
9 Dim tmpChk1 As CheckedListBox.CheckedIndexCollection = BlogList.CheckedIndices
10 For y As Integer = 0 To tmpChk1.Count - 1
11 chk1.Add(tmpChk1.Item(y))
12 Next
13 Dim tmpChk2 As CheckedListBox.CheckedIndexCollection = CategoryList.CheckedIndices
14 For z As Integer = 0 To tmpChk2.Count - 1
15 chk2.Add(tmpChk2.Item(z))
16 Next
17 End Sub
18#End Region
19
20#Region " Tab Control Page Changed Event "

21
22 Private Sub ViewTabControl_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles ViewTabControl.SelectedIndexChanged
23 Dim currentPage As TabControl = CType(sender, TabControl)
24 Select Case currentPage.SelectedTab.Name
25 Case "OptionsTabPage"
26 Try
27 For y As Integer = 0 To chk1.Count - 1
28 BlogList.SetItemChecked(chk1(y).ToString, True)
29 Next
30 Catch
31 End Try
32 Try
33 For z As Integer = 0 To chk2.Count - 1
34 CategoryList.SetItemChecked(chk2(z).ToString, True)
35 Next
36 Catch
37 End Try
38 End Select
39 End Sub
40#End Region
At any rate, this port is a test of the "PostToCategories" functionality. Now that I'm saving the state properly, and using the "CheckedIndices" property instead of "SelectedIndices" property, it should work. I'll know in about 8 seconds.
And tonight on the Countdown...

"Never mess with techies, because they know more ways of messing with you than you know of messing with them"

-Keith Olbermann on the latest RIAA website outtage.

Real Nasty Virus Alert

I was just notified by MailStreet, my Hosted Exchange provider, that there is a horrible new virus going around. I haven't heard of a virus this bad before. It brought down an entire Exchange 2003 server cluster this morning, and 50 other servers in their datacenter. I'll let the Washington Post fill you in on the details:

The "Witty" worm writes random data onto the hard drives of computers equipped with the Black Ice and Real Secure Internet firewall products, causing the drives to fail and making it impossible to restart the PCs. Unlike many recent worms that arrive as e-mail attachments, it spreads automatically to vulnerable computers without any action on the part of the user.

At least 50,000 compters have been infected so far, according to Reston, Va.-based computer security firm iDefense and the Bethesda, Md.-based SANS Institute.

The firewalls were developed by Atlanta-based Internet Security Systems. Chris Rouland, vice president of the company's X-Force research and development division, said that as many as 32,000 corporate computers could be infected. The company does not know how many home users are infected. ISS released a patch and a detailed writeup of the affected products.

Most infected computers will have to be rebuilt from scratch unless their owners instead decide to buy new ones, said Ken Dunham, a computer security expert at iDefense. "The thing looks like it will corrupt or crash most drives enough so that reinstallation is going to be required," he said. "This is a very destructive worm."

Officials at the Department of Homeland Security, which is in charge of the government's cybersecurity efforts, were unavailable for comment.

Internet worms, viruses and other malignant software often install software or open "back doors" that allow hackers to control infected computers. That often gives them access to private data that people keep on their computers, and allows them to use those computers to send out e-mail spam that cannot be traced back to its real owner. The Witty worm is different and in some respects more destructive because it renders the computer useless.

Johannes Ullrich, chief technology officer for the SANS Internet Storm Center, said that the worm does not create files on infected computers so most antivirus software will not detect it.

Security vulnerability research firm eEye Digital Security identified the flaw last Wednesday. The Aliso Viejo, Calif.-based company discovered that it could trick some versions of Black Ice and Real Secure into processing Internet traffic that would allow attackers to transfer dangerous data to vulnerable computers.

The Witty worm gets its moniker from a message buried within its code that says: "insert witty message here." That comes just before the code that overwrites the infected hard drives.

Joe Stewart, a senior security researcher at Chicago-based security services company Lurhq, said he expects the worm to die out over the next few hours as vulnerable computers quickly become useless hosts.

"With all these hard drive problems, the infection rates are going to shrink pretty quickly as all these affected machines grind themselves to a halt," Stewart said.

If you have these programs on your system, I cannot overstate the need to patch immediately. Unless of course, you don't mind buying a new hard drive. Here's a link to ISS' website where you can download the patch.
Walking the Call Stack

Does anyone know how to walk the call stack on a calling assembly? I blogged earlier about a new limit I was writing for XHEO|Licensing. Basically I want to limit an assembly's use at runtime, but I don't know what that assembly is going to be at compile time. I have written some code that loads up all the running assemblies into an array, and walks the array to see if the assembly is loaded. That is not the optimal way however, because someone could just reference and load the required caller, then execute my assembly separately, because the licensed caller is loaded into the AppDomain.

The code to check all the assemblies in the AppDomain looks like this:

1Assembly[] loadedAssemblies = Thread.GetDomain().GetAssemblies();

2Assembly asm = null;
3
4for(int i = 0; i < loadedAssemblies.Length; i++)
5 if(String.Compare(loadedAssemblies[i].GetName().Name, AssemblyName, true) == 0)
6 asm = loadedAssemblies[i];
7
8 // Display the full assembly information to the console.
9 if(asm == null)
10 {
11 return false;
12 }
Now. I'm thinking instead, it might be better to create the array with a recursive stack walk, backpedaling through Assembly.GetCallingAssembly(). My question is, is there an easier way to get the call tree from a given assembly? I don't have a whole lot of experience in this particular area of .NET, so I'm sure one of you has a better idea of what to do. Any ideas?
Just When I Thought I Had Mastered DTC...
...it kicked my butt again. Last week, we migrated to new servers. Well, MSDTC reared it's ugly head again. I spent 6 hours tonight tryint to track down why the DTC transaction keeps dropping the connection. The answer? I still had the old server VPNed into the network. Disconnected the old server from the network, and BAM, my SQL transactions are working again. The problem? Damned if I know. DTC wasted ANOTHER 6 hours of my life... <sigh> :(
Useless Error Message of the Month

"An unknown error has occurred while processing the request. The transaction has already been implicitly or explicitly committed or aborted."

Microsoft Distributed Transaction Coordinator error.

More Posts Next page »