I don't know how no one is bothered by this. May be because it affects Longhorn. But anyway, everybody would agree that while .Net solved the DLL Hell issue, it created its own which I affectionally call Assembly Hell and had my rants loud from the start. I'd high hopes when I heard Jeff Richter is on the team. But be hold, they come up with the statement that the problem is "mathematically" unsolvable and some fuzzy argument to back up that statement and then they reveal possibly the worst versioning scheme I've heard in a decade for anything: divide the assemblies in "platform" and "library" groups! I can't even start to imagine someone could think of this kind of stupid idea for things that will hit the entire planet on massive scale. Must be an outcome of long meetings for days :).
I'd been burned a lot by missing gaps in .Net versioning and problem is pretty simple if you had been in this mess. The solution is even amazingly simple for what it appears like a monster.
The fundamental flow in the .Net versioning is that it doesn't allow to put a version number on assembly without breaking the compatibility. Once you understand this, lot many problems would be simplified. The 'assembly version' is what we usually use for checking whether the file is really the one what we want and for deployment modules to make an update. While 'compatible-to version' is for the run time to check if it should throw an error. So 'assembly version' is different then 'compatible-to version' and are not tied with each other. So all we need is one AssemblyXXX attribute that can let us specify what is the build number for this assembly and another AssemblyYYY to specify the version to which this assembly is still compatible from interface as well as behaviour point of view. You always auto-increment your assembly number on each build, but you do not change "compatible-to" number unless you really change the interface and behavior. And the problem is solved.
Infect, here is a final surprise: you can do this right now in 1.x and 2.x. Use AssemblyVersion attribute to specify "Last Compatible-To" version and AssemblyFileVersion attribute to specify the build version. Things have been worked out perfectly for me with this scheme. Now when I hear about dumbest idea since COM versioning and 'plateform' and 'library', I just think we are in for huge additional mess waiting that will take another release (another 10 years?) to clean up. Whether you agree or not, people, speak up!!
This is collection of several reusable components to use in your WinForms application. I'd been building it up and reusing in my own personal applications such as BrowserHistoryAnalyser and NotepadX and others. It contains editable drag-n-drop enabled TreeView, RichText editor control with toolbar, Worksheet editor control, Password Input Form, MRU, custom attributes you can use for your assemblies, more easily usable hidden property editor control, advanced About Dialog, Application Options management and Assembly Info Viewer Control.
Warning: This program was written circa Oct 2004. It is currently considered obsolete for most practical purposes. There are no plans to update it and no support is provided.
WinFormsCommonUtils is now archived at Github
X-Setup is perhaps the most comprehensive Windows tweaking utility. I always end up spending half a day enabling all the hidden advanced settings using this thing. Fortunately it provides Recording mode and creation of a REG file. This is really cool because now with just a click I can make any XP/2003 machine more geekier and end lots of "default" annoyances. If you are interested you too can use my final REG file. It would enable a whole range of features – everything from showing additional control panel applets, using double pans in explorer, removing Outlook attachment restrictions, showing file attributes in tooltip, adding new items in Explorer context menu, removing Shutdown Reason UI, kill everything quickly when shutting down and so on...
I like to preserve logs of my browser history. Apart from recalling useful webpages I'd discovered, it helps to build kind of "journal" reflecting problems I was facing, things I was in to, things I was shopping and so on. An ability to look back and see what you were up to in any point of time is really important, not just useful. Unfortunately there is no easy way to export history from IE or Firefox, let alone query that data in an useful way. So this is the program I'd been putting some time on and off. The first version I'd made meant only for my personal and was a quick and dirty program in VB6 more then 5 years ago. Its latest incarnation is now rewritten from scratch in .Net 2.0 Beta1 and provides loads of functionalities in nice user interface. You can do all of followings:
- Export the browser history in to MS Access database
- Search your browser history with speed like Google
- Merge several history databases i to one (useful if you used multiple machines)
- Look at all the queries you performed on Google, MSN and Yahoo
- Statistics of how many websites you visit a day, how many unique URLs and domains you have visited so far
- Ability to filter "noice" and random popup URLs
- Statistics of how much time you spend per page, how much time you spend per day in browsing websites
- Chart the statistics
The architecture of this new version is fairly extensible and you can plug-in more modules as you go. I'll be implementing more public plug-in architecture and using plain XML files instead of MS Access databases and FireFox support (this is becoming important for me because I've 100% switched over to FireFox). So this is not yet the "release" version. Also note that you need .Net Framework Beta 2.0 Beta1 + VB.Net resource Kit if you want to compile the code. But results are beautiful!
Warning: This program was written circa Nov 2004 and last updated around Mar 2005. It is currently considered obsolete. There are no plans to update it and no support is provided.
BrowserHistoryAnalyzer is now archived at Github
I never liked being forced to use DataView just to speed up my searches. Why not DataTable.Select() have an overload to generate internal indexes and do some smart things? But anyway, most people searching DataSet eventually would realizes that performance really sucks and they have no choice but to use DataViews, sometime whole bunch of it prepared for all sorts of queries you want to fire. Here are two things you should watch out (MSDN docs aren’t clear about this):
1. If you call myDataView(someIndex).Delete anywhere in your code, watch out that you do not access any other rows with index > someIndex. If you do, you might either get a run time error or even worse, you might be accessing row underneath that’s different then you actually wanted without any error. Another corollary: Never delete rows in DataView in forward loop.
2. If you are changing/adding row in DataTable or other DataViews, do not forget to call row.BeginEdit and row.EndEdit. If you don’t, your changes will not appear in other views you have.
Well, performance gains through DataView is still pretty sweet thing to have 🙂
If you need to store certain data in file, most of the time you will obviously think about storing it as XML file. Then soon you start drawing XML schemas and think about generating XSDs... Well, stop! You might be making same mistake as many other people. The better idea is to design XML schema which is loadable in DataSet rather then just XMLDocument. This has tremendous advantages then your custom schema:
- Instead of thinking in hierarchical terms, you can now think in relational terms. I've often found that this simplifies lots of things. This means you can think how you will be storing your data in tables rather then XML hierarchies.
- Schema generation gets simplified: You can draw actual database schemas using drag and drop in Access visually, set various properties for fields and generate XML schema using my utility.
- You can load your XML file right in to DataSet, create various relationships and access your data far more easily and with less code then directly using XMLDocument.
- Once you have stuff in DataSet, you can do data bindings directly for quick demos or even use typed datasets - which is far more safer then always late bound XMLDocument objects.
- In future, if you change your mind (and in most cases you will) to store your data in high performance databases rather then plain XML files, using DataSet in first place makes your job far more easier. Using DataSet compatible schemas allows you support plain XML files as well as real databases as your storage.
- If you don't want to use SQL Server, its still a good idea to include possible support for Access mdb file along with plain XML file as your storage. Unlike plain XML files, Access single file databases allows you to fire far more complex queries rather then just XPath, generate reports write VBA scripts, set constraints, use security features and use other tons of utilities out there. Using DataSet compatible schemas lets you do that.
- Use of dataset will let you migrate your application as becoming a Groove tool with far more ease. Once your app can sit in Groove transceiver, it would suddenly become a marvellous magic collaboration product! However note that Groove has not included their ADO.Net support in their 3.0 version but there are rumours that they eventually will. Currently the only way to have it is to use Groove 2.5 or upgrade from it to 3.0.
- If you manually enter data in your XML file (usually you might have to for unit tests, bug repro etc), you can do it in Access tables which is far more easier and save whole database as XML using my utility.
This might make you wonder is there is any negative points in using DataSet compatible schemas. There are some, indeed:
- Some data which is inherently hierarchical are better represented using custom schemas. Trying to fit in relational table structure will cause to create several many-to-many map tables and complicate the whole thing.
- If XML file becomes large, there ways to read it using SAX parser rather then loading whole file in memory. Using DataSet directly will always load the whole file in memory and in general uses more of it.
- Custom XML schemas are more "purer" to share across the platforms. However if you plan to use Mono, it already supports DataSets and that won’t be a problem.
If you installed .Net Framework 2.0 Beta and suddenly VS2K3.Net refuses to attach to your existing 1.1 apps with a very cool error message “Unable to attach to process”, don’t get panic! Looks like side-by-side promise of Framework versions doesn’t work in some rare cases (which somehow I always get in to). Unfortunately you can’t uninstall 2.0 (even though it gets installed in separate folder, core DLLs such as mscorlib.dll is already replaced by 2.0 version). The best way to make things work is to live with it and add this little snippet in your [myapp].exe.config:
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Even better way is, off course, install betas only in your VPC!
PS: If you ask what was that rare situation: This happens with Groove tools you write with 100% managed code. In this case, you expose your DMD with CCW which Groove loads dynamically using ProgID and somehow it gets bind to 2.0 version. One more thing, I’ve heard that 2.0+ Frameworks will upgrade existing framework version rather then getting installed side-by-side. That might be it! In any case, your VS2003.Net will get screwed up, so above step is necessary.
This Task Manager for Windows rocks. Besides doing everything that you ever wanted from a thing called Task Manager (even showing open files for every process), it has one of the sweetest option that your application should provide: Replace Windows native [equivalent thing]! I just keep wishing if there had been free and with-source Calculators and Explorers and everything else Windows that I can just replace with a click like this and move on rather then waiting for a decade on Microsoft to improve their age old featureless apps. So when you are getting cool skinable Windows? In next 3 years? Yeah, right.
This innocent little puzzle formed from some of the recent code I was writing. Lets see if it gets you!
object p = 2;
object q = p;
p = 4;
System.Diagnostics.Debug.WriteLine("Answer is " + q.ToString());
Meanwhile I'm having fun asking it to my colleagues 😉
This is probably the best Wizard User Interface I've seen so far ;).