I think this is a great rant against the .Net runtime, so I like to post Joel's note as it is, because I share the same feeling. It's true that for Web applications, we have no problem.
But why we can't build ourselves a light embedded version of the runtime in our Windows projects, having only the libraries we need ? Joel give a good 'real world' example. I still have users with Windows 98, and I still have the pain to check that they have the right framework.
From Joel on software:
For some reason, Microsoft's brilliant and cutting-edge .NET development environment left out one crucial tool... a tool that has been common in software development environments since, oh, about 1950, and taken so much for granted that it's incredibly strange that nobody noticed that .NET doesn't really have one.
The tool in question? A linker. Here's what a linker does. It combines the compiled version of your program with the compiled versions of all the library functions that your program uses. Then, it removes any library functions that your program does not use. Finally, it produces a single executable binary program which people can run on their computers.
Instead, .NET has this idea of a "runtime" ... a big 22 MB steaming heap of code that is linked dynamically and which everybody has to have on their computers before they can use .NET applications.
Runtimes are a problem, much like DLLs, because you can get into trouble when application version 1 was designed to work with runtime version 1, and then runtime version 2 comes out, and suddenly application version 1 doesn't work right for some unpredictable reason. For example right now for some reason our internal company control panel is rounding sales figures to four decimal points, as a result of upgrading from 1.0 to 1.1 of the runtime. Usually the incompatibilities are worse.
In fact .NET includes an extensive technology system called "manifests" which are manifestly complicated and intended to insure that somehow only the right runtime will be used with a given application, but nobody I know can figure out how to use them.
This calls for a story. At the Fog Creek New Year's Eve party, we wanted a bunch of computer screens in the main room to display a countdown until midnight. Michael wrote an application to do this in C# with WinForms in about 60 seconds. It's a great development environment.
My job was getting countdown.exe to run on three computers. Sounds easy.
Nope. Double click the EXE, and I got a ridiculously user-hostile error message about mscoree.dll or something, followed by a gratuitous dump of my path. No mention of the fact that the problem was simply that the .NET runtime was not installed. Luckily I'm a programmer and I figured that must be the problem.
How do you install the runtime? The "easiest" way is through Windows Update. But Windows Update really wanted me to get all the critical updates first before I installed the runtime. That's reasonable, right? Two of the "critical" updates were a Windows service pack and a new version of Internet Explorer, both of which required a reboot.
All told, for each computer I needed to run this little .NET application on, I had to download something like 70 or 80 MB (good thing we have a fast net connection) and reboot three or four times. And this is at a software company! I know how long it took, because the first time it started downloading, I put Office Space on the big screen TV, and by the time the movie was over, the installation process was almost finished. Every ten minutes during the movie I had to jump up, go to each computer, and hit OK to some stupid dialog box.
This is frustrating enough for our in-house apps. But think about our product CityDesk. Almost all of our users download a free trial version before buying the product. The download is around 9 MB and has no additional requirements. Almost none of these users has the .NET runtime yet.
If we asked our trial users, usually small organizations and home users, to go through a movie-length installation hell just to try our app, I think we'd probably lose 95% of them. These are not customers yet, they're prospects, and I can't afford to give up 95% of my prospects just to use a nicer development environment.
"But Joel," people say, "eventually enough people will have the runtime and this problem will go away."
I thought that too, then I realized that every six or twelve months Microsoft ships a new version of the runtime, and the gradually increasing number of people that have it deflates again to zero. And I'll be damned if I'm going to struggle to test my app on three different versions of the runtime just so I can get the benefit of the 1.2% of the installed base that has one of the three.
I just want to link everything I need in a single static EXE that runs without any installation prerequisites. I don't mind if it's a bit bigger. All I would need is the functions that I actually use, the byte code interpreter, and little bit of runtime stuff. I don't need the entire C# compiler which is a part of the runtime. I promise CityDesk doesn't need to compile any C# source code. I don't need all 22 MB. What I need is probably five or six MB, at most.
I know of companies that have the technology to do this, but they can't do it without permission from Microsoft to redistribute bits and pieces of the runtime like the byte code interpreter. So Microsoft, wake up, get us some nice 1950s-era linker technology, and let me make a single EXE that runs on any computer with Win 98 or later and no other external dependencies. Otherwise .NET is fatally flawed for consumer, downloaded software.
http-equiv has identified a vulnerability in Internet Explorer, allowing malicious web sites to spoof the file extension of downloadable files.
The problem is that Internet Explorer can be tricked into opening a file, with a different application than indicated by the file extension. This can be done by embedding a CLSID in the file name. This could be exploited to trick users into opening "trusted" file types which are in fact malicious files.
Secunia has created an online test:
http://secunia.com/Internet_Explorer_File_Download_Extension_Spoofing_Test/
This has been reported to affect Microsoft Internet Explorer 6.
NOTE: Prior versions may also be affected.
Source: Secunia
Other thing, Microsoft plan to launch a patch to disallow the format username and password in the URL, like user:password@mysite.com.
"This decision (to remove the behavior) has been a long time coming. Removing this feature will go a long way towards preventing IE users from being taken by phishing scams," said WhiteHat Security founder Jeremiah Grossman. As more IE users patch, phishing scammers will need to resort to other methods."
Phishing schemes are socially engineered attacked intended for the sole purpose of obtaining site passwords, credit card numbers and other personally identifiable information.
Commenting on its decision, a Microsoft spokesperson told BetaNews, "This change in functionality will improve user security because the use of this URL syntax can potentially expose the user's name and password in plain text within the URL for the displayed page. An example of the security danger is that in a cross-frame or hidden-frame scenario, script in pages from visited Web sites can easily access the URL, parse it, and determine the username and password for other sites."
From: Betanews
BlogJet 1.0.0.13 Release Notes
January 27, 2004
FEATURES
* Added plain Blogger and MetaWeblog APIs.
BUG FIXES
* Proxy error fixed.
* Inserting lj-cut on image error message removed.
* F1 shortcut now works properly.
---
BlogJet 1.0.0.12 Release Notes
January 27, 2004
FEATURES
* Voice attachments. Wow!
* Blogware weblogs support.
* lj-cut tags for LiveJournal/DeadJournal.
* Custom path for image uploading.
* Paste Special: normal, plain text or HTML code.
* Shortcuts for Save, Open, View Blog Page, etc.
* ESC key closes Recent Posts window.
CHANGES
* Menu: Post renamed to Post As Draft.
* Menu: View Blog Page, Change Account, and Preferences
moved to Tools menu.
BUG FIXES
* Fixed minimizing to notification area on startup.
* Fixed various issues with categories in .Text accounts.
* Receiving of MovableType/TypePad categories corrected.
* MetaWeblog API (and .Text) problems fixed.
* Fixed lots of bugs with Account Wizard.
* Fixed problems with connection when using "http://" in
host name.
* New Post button now sets focus to Title.
* Other fixes.
KNOWN ISSUES
* Progress indicator for history is temporarily disabled.
* There is no help available.
Download BlogJet 1.0.0.13 BETA
An interesting idea via Stefano Demiliano. A list of .Net bugs.
I post it back here for the Microsoft crowd in case they want to comment ;-)
Known .NET Bugs
| ID |
Description |
Probability* |
Severity* |
Fixed |
| 1 |
Form refuses to close If a form A contains control B that contains control C that contains control D, and D is removed while it has the focus, the user won't be able to close the form. Details. |
High |
High |
1.1 |
| 2 |
SoapFormatter and BinaryFormatter don't serialize some object graphs properly If three or more classes have the same name but are in different namespaces, are part of the same hierarchy, and contain variables that have the same name, they will not be serialized properly. Details. |
Low |
High |
1.1 |
| 3 |
Text in the Windows Forms combo box cannot be selected using the mouse Mouse selection simply does not work in a Windows Forms combo box. Details. |
High |
Low |
1.1 |
| 4 |
Arrays of structures that implement ISerializable do not deserialize correctly Details. |
High |
High |
1.1 |
| 5 |
Windows.Identity doesn't work under Windows 98 On Windows 98, You cannot use the Windows.Identity to retrieve the user login name, it returns a system level token and a null user name is returned when you access the .Name Property. Details. |
Low |
Medium |
No |
| 6 |
C# optimizer produces bad code when a try-finally block is inside if-else If a try-finally block is the last thing inside the if block of an if-else statement, the code inside the else block is always executed when compiling in Release mode. Details. |
High |
High |
1.1 |
| 7 |
Structs within structs cannot be deserialized If you have a struct A inside struct B, and If a struct A is inside struct B which is inside object C, deserializing is going to throw a SerializationException. Details. |
Medium |
Low |
1.1 |
| 8 |
Problems removing an ActiveX control from its parent If an ActiveX control is removed from its parent, any action that makes the parent invisible, such as closing the form on which it is on, throws an exception. Details. |
Medium |
High |
1.1 |
| 9 |
Font.GdiCharSet hardcoded to 1 The property GdiCharSet of the font class is hard-coded to 1. Details. |
Low |
Low |
No |
| 10 |
.NET Runtime leaks large chunks of memory If you allocate a block of memory larger than some treshold, the .NET garbage collector will never reclaim it. Details. |
High |
High |
1.1 |
| 11 |
Instances of NumericUpDown and DomainUpDown are leaked It seems that the NumericUpDown and DomainUpDown controls forget to remove a listener to a global event, thus always staying locked in memory. Details. |
High |
High |
No |
| 12 |
SoapFormatter chokes on some strings It seems SoapFormatter cannot handle strings that contain characters in the range 0x01 - 0x1f. Details.
Update SOAP being XML based can't handle many characters in the 0x00 - 0x1f range because they are illegeal in the XML spec. |
High |
High |
No
Not a bug |
| 13 |
FileStream becomes unusable when writing to a removable drive When writing to a FileStream on a removable drive, and the FileStream gets out of space, it sometimes gets in a state where no other method can be called on the stream, not even Dispose. Details. |
Medium |
Medium |
No |
| 14 |
Mixed-mode assemblies can deadlock C++ .NET apps can deadlock on startup. Details. |
Low |
High |
No |
| 15 |
ComboBox Data Binding Bug ComboBox doesn't update the data through data binding when its style is set to DropDownList. Details. |
Medium |
Medium |
No |
| 16 |
Each Windows Form leaks two GDI handles Details. |
High |
High |
No |
| 17 |
Alocation fails for certain sizes If you try to allocate an array with a size range between 0x027fefbd and 0x027fffec, the framework throws exceptions. This range corresponds to memory block of little under 40MB. Details. |
Medium |
High |
No |
| 18 |
No way to access Environment.HasShutDownStarted This property is not static even though it should be. |
Low |
Low |
1.1 |
| 19 |
Thread.Abort cannot abort suspended threads If a thread is suspended, trying to abort will not work and the CPU will be pegged to 100 percent. Details. |
Low |
High |
No |
| 20 |
Control.Width and Height are silently truncated to 32,767 If you attempt to set a control's Width or Height property to a number larger than 32,767 it will be truncated. Details. |
Low |
Low |
No |
| 21 |
ListView.Cursor set property has no effect. Details. |
Low |
Low |
No |
| 22 |
RegistryKey.SetValue does not store large integers as DWORD Call RegistryKey.SetValue with an integer over 2,147,483,647 will result in the value being stored as string, and not as a DWORD. Details. |
Low |
Medium |
No |
* Probability represents the probability that you will encounter this bug. Severity measures how much the bug hurts when it happens.
Do you know other bugs?
Eli Robillard has a great article on MSDN about Error Handling.
Summary: Adding your own custom error handling to your ASP.NET Web applications can ease debugging and improve customer satisfaction. Eli Robillard shows how you can create an error-handling mechanism that shows a friendly face to customers and still provides the detailed technical information developers will need.
Well I have a subject where I have a lot to learn, and it's caching. For the moment I don't really get it. I tried to use some cache functions in some of my projects, but I failed almost all the time.
I can't really find a clever article on all the different options, and it seems that the Cache class in .Net is overcomplicated. I discovered that for example timespan is more important than I could imagine, and it's really hard to tune up precisely the different parameters to have something really working and universal. I mean working well with the different browsers, different platforms, etc...
Last time I used the server cache, it was working well for a week, and suddenly I had to deal with a lot of Internal errors, you know the so infamous error you can't catch.
I removed the cache and now it's working very well. Of course the performances are surely not the same, but I can't afford any crash on a live website.
Unless somebody has a great web link on the subject, I give up on this for the moment.