Unix SDK for Windows

by Jon Davis 20. December 2007 02:31

Yeah I know Windows has had a UNIX compatibility layer for some time. I know that it is based on what was previousy a third party solution called Interix.

But I think it's expanding?? It seems bigger than the Windows Vista option and I don't recall Vista throwing in an SDK and calling it as such.

On the other hand, running Setup, it's offering me "Reinstall/Repair, or Uninstall". *shrug* Running install.

Currently rated 1.0 by 8 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Software Development | Cool Tools | Microsoft Windows

Cascading .NET Versioning In The Path

by Jon Davis 16. December 2007 15:21

The .NET Framework v3.0 and v3.5 both broke some versioning rules, and I suppose there was good reason. Version 3.0 was just version 2.0 plus a few new DLLs for WPF, WCF, WF, and CardSpace. But those new technologies were huge, huge enough to give the .NET Framework a new version number. Meanwhile, though, the C# language and .NET Framework 3.5 forked off cosistency again, in a way that was unnecessary, and with double the damage. C# 3.0 runs on .NET 3.5 -- that is way too confusing. C# 3.0 compiles to the .NET 2.0 CLR. That is way too confusing, too. .NET Framework 3.5 builds on top of .NET Framework 3.0 and 2.0. That would make sense, except that v3.0 and v2.0 are sort of seperate entities.

If you open up C:\Windows\Microsoft.NET\Framework, you'll find each of these .NET Framework versions deployed in their own directory..

08/29/2007  12:30 AM    <DIR>          v1.0.3705
08/29/2007  01:01 AM    <DIR>          v1.1.4322
12/15/2007  03:13 PM    <DIR>          v2.0.50727
11/02/2006  08:15 AM    <DIR>          v3.0
11/19/2007  09:49 PM    <DIR>          v3.5
08/28/2007  05:22 PM    <DIR>          VJSharp

Incidentally, notice that v3.0 and v3.5 don't have build numbers, while the others do. Refer back to my rant about inconsistency. (Personally, I never liked the build numbers being there anyway.) Meanwhile, VJSharp is completely unversioned.

Then there are tons of utility files that do not belong in this directory at all, and Microsoft allowed a mess to be made in here:

08/29/2007  05:39 AM    <DIR>          1028
08/29/2007  06:58 AM    <DIR>          1030
08/29/2007  02:57 AM    <DIR>          1031
08/29/2007  03:10 AM    <DIR>          1035
08/29/2007  04:13 AM    <DIR>          1036
08/29/2007  06:05 AM    <DIR>          1040
08/29/2007  03:55 AM    <DIR>          1042
08/29/2007  07:27 AM    <DIR>          1043
08/29/2007  06:31 AM    <DIR>          1044
08/29/2007  05:16 AM    <DIR>          1046
08/29/2007  03:39 AM    <DIR>          1049
08/29/2007  03:23 AM    <DIR>          1053
08/29/2007  04:33 AM    <DIR>          2052
08/29/2007  04:53 AM    <DIR>          3082
11/01/2006  11:33 PM            72,704 NETFXSBS10.exe
02/20/2003  06:44 PM            36,354 NETFXSBS10.hkf
09/18/2006  02:32 PM            41,392 netfxsbs12.hkf
11/19/2007  09:09 PM            16,896 sbscmp10.dll
11/19/2007  09:09 PM            16,896 sbscmp20_mscorwks.dll
11/19/2007  09:09 PM            16,896 sbscmp20_perfcounter.dll
11/01/2006  11:33 PM             5,120 sbs_diasymreader.dll
11/01/2006  11:33 PM             5,120 sbs_iehost.dll
11/01/2006  11:33 PM             5,120 sbs_microsoft.jscript.dll
11/01/2006  11:33 PM             5,632 sbs_microsoft.vsa.vb.codedomprocessor.dll
11/01/2006  11:33 PM             5,120 sbs_mscordbi.dll
11/01/2006  11:33 PM             5,120 sbs_mscorrc.dll
11/01/2006  11:33 PM             5,120 sbs_mscorsec.dll
11/01/2006  11:33 PM             5,120 sbs_system.configuration.install.dll
11/01/2006  11:33 PM             5,120 sbs_system.data.dll
11/01/2006  11:33 PM             5,120 sbs_system.enterpriseservices.dll
11/01/2006  11:33 PM             5,120 sbs_VsaVb7rt.dll
11/01/2006  11:33 PM             5,120 sbs_wminet_utils.dll
11/19/2007  09:09 PM            16,896 SharedReg12.dll

Now we're one step closer to looking like the infamous Windows Registry. Each Microsoft employee or department gets to put his own file or entry wherever he wants, see? I wonder how many Microsoft employees have decided to move their office desks to the middle of the front lobby, besides the nice front desk lady(ies).

Anyway, the reason why I posted here is because, ironically, the .NET Framework does not appear in the PATH for some strange reason. I've always had to manually add "DOTNET", pointing to C:\Windows\Microsoft.NET\Framework\v1.1.4322 or ...\v2.0.50727 to my environment variables, then add %DOTNET% to my PATH. I used this regularly for tools like my own AssemblyLister so I could easily pre-JIT my assemblies for faster boot time (even if the trade-off is slower runtime performance). But this broke with v3.0 and it is still broken in v3.5, because there is no CLR and Framework directory that runs .NET Framework v3.5. .NET Framework v3.5, like v3.0, is just some add-on assemblies to v2.0. But if I were to reference only the v2.0 directory, I would only have the v2.0 framework (plus the GAC, which, fortunately, contains the v3.0 and v3.5 DLL assemblies, but not their utilities).

Fortunately, you can cascade the .NET versions in the PATH. I don't know why I didn't do this a long time ago, but the PATH environment variable, which is a semi-colon delimited list of directories in which to search for files in the file system shell without referencing their complete paths, is already a cascading list. In other words, when searching for a file using the PATH, the first directory listed is scanned first, then the second, and so on.

One thing I like about the .NET Framework versioning that Microsoft claimed that they are committed to when they were working on v2 was that the .NET Framework will try to be forwards-compatible and will always be backwards-compatible to assemblies targeting different versions of the CLR. This means that a v1.1 assembly can be run in a v2.0 CLR, and a v2.0 assembly might be able to run in a v1.1 CLR. In the end, it's just MSIL that the CLR breaks down into machine code at runtime (unless it's pre-JITted).

So as long as you're using an environment (such as cmd.exe or PowerShell) that splits the PATH string into multiple directores, recursively finding more %variables%, and scans them one by one in cascading order, you can effectively use a single environment variable to reference all of your .NET Framework directories at the same time, with the newer .NET Framework files taking priority over the older files. To do this, just add each .NET Framework version, starting with v3.5, then v3.0, then v2, then v1.1 (if v1.1 is installed), into a DOTNET environment variable, and then add %DOTNET% to your path.

  • DOTNET = C:\Windows\Microsoft.NET\Framework\v3.5; C:\Windows\Microsoft.NET\Framework\v3.0; C:\Windows\Microsoft.NET\Framework\v2.0.50727; C:\Windows\Microsoft.NET\Framework\v1.1.4322; C:\Windows\Microsoft.NET\Framework\v1.0.3705
  • PATH (virtually on %PATH%, not literally) = %PATH%;%DOTNET% 

By "virtually on %PATH%, above, all I mean is that you would replace %PATH% with what it already is, then append ";%DOTNET%".

If I wanted to use the 64-bit versions of the .NET Framework, I could do the same, using C:\Windows\Microsft.NET\Framework64\, but meanwhile also adding the x86 paths for compatibility.

  • DOTNETX64 =
     
    C:\Windows\Microsoft.NET\Framework64\v3.5; C:\Windows\Microsoft.NET\Framework64\v3.0; C:\Windows\Microsoft.NET\Framework64\v2.0.50727; C:\Windows\Microsoft.NET\Framework\v3.5; C:\Windows\Microsoft.NET\Framework\v3.0; C:\Windows\Microsoft.NET\Framework\v2.0.50727; C:\Windows\Microsoft.NET\Framework\v1.1.4322; C:\Windows\Microsoft.NET\Framework\v1.0.3705
     
    - or -

    C:\Windows\Microsoft.NET\Framework64\v3.5; C:\Windows\Microsoft.NET\Framework64\v3.0; C:\Windows\Microsoft.NET\Framework64\v2.0.50727; %DOTNET%
  • PATH = %PATH%;%DOTNETX64%

Unfortunately, though, this brings another issue into the mix. Which one do you want in your PATH, %DOTNET% or %DOTNETX64%? This is an important question. I do ASP.NET development in 32-bit and I debug my apps in explicit x86 CPU build mode (because Visual Studio doesn't let me perform edit-and-continue tasks in 64-bit, which is already the default environment for the "Any CPU" build mode). But without compiling to 64-bit, CLR assemblies can hit the RAM registry space ceiling, quickly running out of RAM (OutOfMemoryException or something similar), and this has happened to me already while building a search engine server based on Lucene.NET.

To be honest, I'm still not sure. I'm going to try using the 64-bit path variable (%DOTNETX64%) for now and see if it brings me any problems. I think Windows is defaulting to that one already. Meanwhile, though, I can still continue to target x86 CPUs in my builds.

So to test this out, I try where in Vista to see the cascading effect. (Note that any time you change the PATH environment variable, or any environment variable(s), you must close the command shell window and restart it before the variables will propogate. They will not propogate into the GUI shell until you log out and log back in.)

C:\Users\Jon>where ngen
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\ngen.exe
C:\Windows\Microsoft.NET\Framework\v2.0.50727\ngen.exe
C:\Windows\Microsoft.NET\Framework\v1.1.4322\ngen.exe

So it seems to work, which is nice.

Meanwhile, I still need an environment variable to single directory for my primary CLR, which contains ngen.exe and csc.exe and other CLR essentials.

  • CLRDIR = C:\Windows\Microsoft.NET\Framework64\v2.0.50727

There's one last change I need to make, though. It might make more sense to change the environment variable %DOTNET% to %NETFXX86%, and then change %DOTNETX64% to %NETFX%. This way, apps that target a %NETFX% environment variable can properly target the environment's complete and CPU-targeted environment rather than just focus solely on x86 compatibility.

So, here's what I have in the end:

  • NETFXX86 =
     
    C:\Windows\Microsoft.NET\Framework\v3.5;
    C:\Windows\Microsoft.NET\Framework\v3.0;
    C:\Windows\Microsoft.NET\Framework\v2.0.50727;
    C:\Windows\Microsoft.NET\Framework\v1.1.4322;
    C:\Windows\Microsoft.NET\Framework\v1.0.3705
      
  • NETFXX64 =
     
    C:\Windows\Microsoft.NET\Framework64\v3.5;
    C:\Windows\Microsoft.NET\Framework64\v3.0;
    C:\Windows\Microsoft.NET\Framework64\v2.0.50727
     
  • NETFX = %NETFXX64%; %NETFXX86%
     
  • DOTNET = %NETFX%
     
  • CLRDIR = C:\Windows\Microsoft.NET\Framework64\v2.0.50727
      
  • PATH =
     
    C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin; %SystemRoot%\system32; %SystemRoot%; %SystemRoot%\System32\Wbem; %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\; C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\; C:\Program Files (x86)\Microsoft SQL Server\80\Tools\Binn\; C:\Program Files\Microsoft SQL Server\90\DTS\Binn\; C:\Program Files\Microsoft SQL Server\90\Tools\binn\; C:\Program Files (x86)\Microsoft SQL Server\90\DTS\Binn\; C:\Program Files (x86)\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\; C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\; C:\Program Files (x86)\QuickTime\QTSystem\; C:\Program Files (x86)\Common Files\Adobe\AGL; C:\Windows\SUA\common\; C:\Windows\SUA\usr\lib\; C:\Program Files\Microsoft Network Monitor 3\; E:\filez\dev\IronPython-1.1; C:\Program Files (x86)\GnuWin32\bin; C:\ruby\bin; C:\MinGW\bin; C:\cygwin\bin;
    %NETFX%

Now I can use "native" .NET apps like csc.exe or ngen.exe, and have all tools and assemblies on hand, without manually loading the SDK command shell.

I created an EXE to auto-configure this: SetNetFxEnvVars.exe [source] Note that it will require an immediate reboot. Note also that if you're using Internet Explorer, in order to run the EXE you must download it and then unblock it (right-click it, choose Properties, then click Unblock).

kick it on DotNetKicks.com

Currently rated 3.0 by 2 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , , , , ,

Software Development | Microsoft Windows

What Slows Windows Down

by Jon Davis 16. December 2007 15:19

Speaking of performance, here's an article I stumbled upon today that is very telling. I'm shocked as much that instant messaging is a culprit to poor system performance as I am shocked that I haven't seen this kind of test done before, measuring all popular software and not just anti-virus software, etc.

 http://www.thepcspy.com/read/what_slows_windows_down/3

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Testing Silverlight Instancing Scalability

by Jon Davis 14. December 2007 00:49

I have been curious for several months as to how scalable Silverlight is for instancing. That is, not how scalable will Silverlight perform within itself, but rather how many instances of Silverlight can fit on a web page at a time? Is it feasible to go so far as to actually use Silverlight controls where one would normally use PNGs to decorate a page, for example?

I finally got around to digging out these numbers myself by doing a test of my own.

My test consists of an HTML file with Javascript that, when a button is pressed, will generate an instance of Silverlight with a radial gradient and add it to the HTML DOM. If the button is pressed again, another instance is generated and appended to the HTML document.

I pressed the button 100 times and manually measured each one for RAM usage. The test was performed on a x64 environment, with Internet Explorer 7.0 as the browser and Silverlight 1.1 Alpha as the Silverlight build.

My hardware environment is an AMD Athlon X2 6000+ dual core system with 4GB RAM.

Test files:

The RAM usage was a tiny bit better than I expected. Rather than taking up 2 MB or so that I feared to be the worst case scenario, the reality was only an average of roughly 300KB of RAM per instance.

The CPU usage was another story. I don't have the measurements to show for it, but let's just say that at about 80-90 instances, it took about as many seconds, divided by ten, to be able to click on the "Add Silverlight Instance" button again. That is to say, the 85th click caused me to wait about 8 or 9 seconds before I could click again. I think the CPU overhead is actually rendering and invalidating the Silverlight controls, even the ones that are below the visible threshold of the page, because when the CPU goes back down to 0% and I scroll down, I have to wait another 9 seconds before Internet Explorer will stop locking up. Clearly, there are regional invalidation issues with Silverlight, but that's perhaps due to design, since regional invalidation works differently across platforms.

I ran into some hiccups along the way; had to restart my tests once (the RAM usage was within a MB to where I left off), and lost one measurement.

By the time I got to my 100th instance, the wait was more like 20 seconds. The CPU overhead apparently seemed to escalate very quickly at 90 instances.

I'd like to see someone do the exact same test in Flash. If no one volunteers here I'll try to find the time this weekend.

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Computers and Internet | Software Development | Web Development

Bypassing Cross-Site Scripting Using A Proxy

by Jon Davis 13. December 2007 09:46

When I implemented Sprinkle, which is a client-side includes (CSI) system I came up with that doesn't use IFRAMEs, I kept running into the scenario where you may want to fetch HTML from an external web site besides your own. This is sort of what Web 2.0 is all about, being able to mashup the world with not just your crap but everyone else's crap as well.

I threw together a trivial solution. This is ASP.NET-only, I might come up with a PHP-based equivalent. The idea is to implement a really trivial proxy server and cache the data for a period of time. In this particular implementation, I cache it directly into the web Application's in-memory collection.

Here's what using it might look like ..

        <%-- Client-side includes with server-side cross-site proxying --%>
        <script type="text/javascript" src="
http://sprinklejs.com/sprinkle.js"></script>
        <div src="proxy.aspx?url=http://www.sprinklejs.com/info.html" />
       
        <%-- Server-side includes with cross-site proxying--%>
        <ssi:ProxyControl runat="server" ID="GoogleInsertion"
            SourceUrl="
http://www.google.com/"
            DetectImposeBase="true"
            BaseUrl="proxy.aspx?url=http://www.google.com/" />

In the server-side include implementation, the DetectImposeBase and BaseUrl properties are really just hacks where I force-inject the proxy URL to any src and href element attributes.

If you try to use the above-referenced proxy.aspx file from an external web site, it should fail. The referer header can only be on the same host.

If you try to reference a very large binary file or something, it will fail. Maximum file size is enforced, so as to not overload the Application in-memory collection that hosts the proxy cache.

This implementation doesn't work flawlessly and it's sort of a prototype thing, it only took about an hour to hack together (plus some time I spent struggling with Visual Studio puking on me), but anyway, here it is.

Download: http://sprinklejs.com/SSI_Proxy_ASPNET.7z

kick it on DotNetKicks.com

w00t

by Jon Davis 12. December 2007 11:38

http://www.reuters.com/article/oddlyEnoughNews/idUSN1256278120071212

I know everyone saw this by now but I had to say, ..

.. this is surely the first time l33t sp33k ever made it into the standard U.S. English dictionary. What a monumental moment, a day to remember.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , ,

Computers and Internet | PC Gaming

Flashback to 2002: My Javascript Console

by Jon Davis 12. December 2007 03:33

Here's something I did five years ago in IE-DHTML (Internet Explorer DHTML): 

http://www.jondavis.net/javascriptConsole.htm

Doesn't seem to work in Firefox.

I had AJAXy plans back then to callback to a server and execute a few console commands. I never followed through with that. I should revise that plan and come up with something kewler, maybe something RESTful.

Currently rated 1.0 by 1 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Open Source | Computers and Internet | Web Development

Cool Tool: Folder Size for Windows Explorer

by Jon Davis 10. December 2007 02:00

Windows Explorer (the file explorer, not Internet Explorer) is missing a key feature: The ability to asynchronously count up and display folder sizes without pulling up the Properties view. This proves quite important when trying to track down what directory contains big, bloated files. Someone created something for this, though, here:

http://foldersize.sourceforge.net/ 

I tried it on Windows Server 2003 R2 and it just works; it causes Windows Explorer to just add the column as a column option (choose columns).

Unfortunately, however, it doesn't work with Vista. Why? Because Microsoft killed the Win32 API call for it. Apparently, they replaced it for file metadata support as is found in MP3 files. (Garbage. OK, this is stupid. I'm becoming a Microsoft basher now?) http://foldersize.sourceforge.net/vistasucks.html

I sent a $15 CAD donation to ask the developer to continue to look into a workaround for Vista.

Update: He sent me an e-mail and said he wants to focus on Ubuntu. That makes it a different product altogether; essentially, I take it as "no, I won't support FolderSize for Windows Explorer anymore". Quick, Windows Vista users, send him more $$!!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Open Source | Cool Tools | Microsoft Windows

Option Of The Unthinkable: Boycott Internet Explorer

by Jon Davis 6. December 2007 18:26

I'll confess, I am a Microsoft fanboy. I always have been. I really got started in programming as an adult trying to make a living when I got inspired by Microsoft's migration from Internet Explorer 3.0 to Internet Explorer 4.0. I had already wholeheartedly embraced Internet Explorer 3.0. Microsoft had gone way out of their way to recognize the value of rich client plug-ins (ActiveX) and a strong scripting engine (Active Script) that, frankly, kicked Netscape Navigator's butt. But then Internet Explorer 4.0 was announced, and the world beheld the news with much awe. Netscape 4.0 had, only months prior, announced support for "dynamic HTML", which in retrospect was little more than what I call "flying layers" and dynamic styles. It didn't really have a DOM. It didn't support dynamic content, for example. You couldn't say, "element.innerHTML = ...", for example. All you could do was put stuff in <layer> tags and position them on different parts of the web page or hide them -- flying layers. Whoopty doo. I'm a programmer, give me an object model, argh! But Microsoft knew the need. They are a developer platform company. They get it. Or got it, in the days of IE4. Internet Explorer 4 revolutionized the way software was made. Even just by introducing the Internet Explorer document object model, Microsoft gave us a powerful yet simple object lesson (pun unintended) about objects (again, pun unintended). It was the combination of playing with the DOM and reading Java books that my comprehension about OOP and the value of objects-based programming (a la business objects in VB5) began to sink in. And then I became a man.

Fast forward to 2007. The genuises behind Microsoft's Trident team, who built the amazing and spectacular browser that was Internet Explorer 4.0, had long ago abandoned Internet Explorer to go off and develop a Windows technology that was more suited for scalability and rich graphical layout. That technology was code-named Avalon, and released as Windows Presentation Foundation. Apparently, either some of them, or a completely different group of engineers (Macintosh engineers, perhaps) went off and developed WPF again, from scratch, duplicating WPF's efforts, in a microcosmic bundle called WPF/Everwhere or, as we now call it, Silverlight. Meanwhile, who knows who else was involved in the building of Expression Web, but apparently a whole spanking new layout and rendering engine was created for Expression Web, rather than the traditional Trident that was used previously with FrontPage.

All this while, Internet Explorer has been resting on its laurels, improving only by making minor bug fixes in CSS support and security, and adding tabs. The tired old Trident engine is still a powerful one, but it has apparently become too kludgy to risk too many more changes, and it is too heavily used throughout the industry with its COM interface to risk breaking third party apps by rewriting it.

At the same time, Safari, Netscape Navigator, and Opera are constantly evolving. Now Firefox has componentization, not unlike Internet Explorer's COM object. Now they're the ones embracing and extending, leaving Internet Explorer trailing behind. Now they're the ones setting the rules. They're the ones teaming up, forming working groups like WHATG to demand improvements on the development environment that is the web browser. Now Safari, Opera, and Firefox are innovating with proposing HTML 5, with or without Microsoft's cooperation, rendering up a canvas using simple Javascript and markup, and, most importantly, winning and maintaining respect from the community by trying to maintain openness about standards and interopability using open Internet protocols and standards.

Microsoft knew what they needed to do to play their cards right. They demonstrated this with their openness with Visual Studio 2008 and related tools, sharing CTP releases more than a year before its release. They demonstrated it in Internet Explorer 4 by making jaw-dropping, astounding promises that were not only kept but demonstrated many months ahead of release.

These days, however, Internet Explorer has become something akin to Microsoft Excel. It gets a revised toolbar, but the core engine is a tired old bag that doesn't want to be exercised. Microsoft's IE team apparently retains a few dedicated and hard-core developers to sit around and poke at its CSS support and security issues. All the while, though, it finds itself too heavily patched, too bloated, too encumbered with baggage, that it simply cannot keep up with the world in which it lives--the Internet.

So it comes as no surprise to me that a blog post like this would pop up on Microsoft's web site:

http://blogs.msdn.com/ie/archive/2007/12/05/internet-explorer-8.aspx

This kind of communication is extremely forthcoming about what Microsoft thinks of Internet Explorer. It tells us just how much they have forgotten their first love of their browser. It tells us that there are people over there who are doing their jobs, day in, day out, keep their mouths shut, keep the gears turning, make some improvements, go home to the kids, sleep well, come back in and do it again. They're not passionate; they're corporate grunts. It reminds us that Microsoft forgot what "laurels" means in the dictionary:

Idiom:

rest on (one's) laurels
To rely on one's past achievements instead of working to maintain or advance one's status or reputation. 

It also reminds us that Microsoft has completely forgotten that Internet Explorer is a development platform. Not only that, but it is a Windows-only development platform, one that Microsoft should care deeply about for their own proprietary sake. And development platforms, as was demonstrated in Visual Studio, demand early communication.

My first love with programming came from Internet Explorer itself. DHTML jumpstarted me to make me who I am as a developer. It's what made me proud to be a Microsoft bigot, proud to choose Microsoft over the others, proud even to break the common sense rules of web site design and actually not bother to build web sites that worked okay in Netscape Navigator, knowing that the huge market saturation that became of Internet Explorer was sufficient to tolerate the losses of those who could not experience what I was implementing into the browser. (I haven't done that in many, many years. For this long, I have respected the expressions of frustrations throughout the Internet of animosity with this practice. However, my patience is wearing thin with Microsoft's incapacity to keep up with the rest of the community with regard to established standards, the perfect opposite and equally disruptive practice of what they did back in the days of IE4.) Sure, Active Server Pages and Visual Basic's powerful COM objects and MTS and SQL Server--the whole DNA platform--contributed to my attitude about Microsoft early on. I saw it all as extremely powerful and leveragable, a developer's dream. But it was IE that made the Microsoft platform fulfilling and enjoyable.

But now I am feeling such an aching burden in my heart. I feel like Microsoft's complacency has developed into betrayal. They don't care about client-side web developers anymore, I feel, not unless those are Silverlight folks.

The above-referenced link to that blog post is really what riled me up to post my blog post here. These words in its comments from other readers describe how I feel as well:

  • "'In the meantime, please don’t mistake silence for inaction.' Too late... while MS might not be keen to adapt to the culture of the web, the internet as a whole generally values openness, transparency and communication. For such an important tool that holds huge influence on the web, the pain caused to web developers and users alike by the MS's silence is magnified."
     
  • "In the end, silence is a good way to create false expectations and alienate your developers and customers who care enough to follow this blog.  People who follow this blog are not exactly your casual users.  We are your power users.  We are your core developers.  We are your fans."
     
  • "I cannot believe that 1 year after the release of IE7 that the first "news" about the next version is that you have FINALLY decided on a name?  As Microsoft proved with with IE6, it would totally be irresponsible of anyone to mistake silence with inactivity - oh wait - that is exactly what silence meant.  Given Microsoft's recent track record with IE, why should anyone assume otherwise?"
      
  • "The next version of Internet Explorer will likely have hundreds of millions of users during its life-cycle. By ignoring the developer community you once had, and now making light of your horrendous business strategy, you've done nothing but destroy what credibility you once had and you've earned the animosity and contempt of people who will eventually work with your product on a daily basis. Also, you hurt my feelings."

There were a few that I couldn't help but laugh at -- I don't agree (of course) but, knowing where they come from and what pain caused to provoke them, they are appreciable. Like, "Kill it and kill yourselves. Douse yourselves in gasoline and set yourselves on fire."

Let me just say this about Silverlight. Dude, you're stealing from us what matters, which is Microsoft's time, money, and infatuous love and devotion. A decade of HTML 4 and XHTML 1 (which Internet Explorer never fully supported) is a REALLY long time in Internet years. My co-workers have been working in the industry for half that much time; perhaps most of Microsoft's development teams are in the same boat! I'll care about Silverlight when it goes beyond being a toy video player, and beyond being a plug-in viewer that can run C#/Python/Ruby apps (with flying layers), and becomes the basis on which a new Internet Explorer engine is built.

Now perhaps Expression Web's new layout engine is better suited to replace Internet Explorer's layout engine. Neither Expression Web nor Silverlight support IFRAMEs, framesets, COM/ActiveX controls, Java applets, or browser plug-ins of some other kind. I'd place my bets that Expression Web is much further along in being available to support these things, as it already supports HTML whereas Silverlight does not.

On the other hand, perhaps I was mistaken, or heard incorrectly, that Expression Web has a new layout engine that's completely distinct from Trident. I don't know.

In any case, I am so disgusted by Internet Explorer's complacency that I've decided to draw a line. Microsoft will surely prove that they care about Internet Explorer in the context of client-side web developers, and give the browser the kind of innovations that a competitive browser market demands, then there will be no more room to grumble. I can understand Microsoft's dissatisfaction with the industry that it would provoke Microsoft into the courtroom with regard to browser tie-ins with the operating system. To that, all I can say is, lighten up, pretend, just pretend, that you were wrong and they were right, and figure out how to plan your operating system integrations more adaptable in the future.

Microsoft of all people have a great rendering engine in WPF that they can leverage into HTML 5's canvas, and another great rendering engine in Expression Web that they can pound into the browser shell we know as Internet Explorer, if they can be sure to get their network stack, COM support, and more, all working correctly.

If, however, Internet Explorer 8 is just another name, with a prettier toolbar, a few new CSS additions, and no real look at HTML 5, then I'd say, forget 'em. By then, which will be at least another year from now, the clock will be reset, and we will be waiting for IE 9, hoping that that one will have something worth shouting about. That clock will require another two years. And it's really just not worth it.

So here, I'm drawing a line. What's it going to be? Does Microsoft care?

Microsoft is family. I've never been employed by Microsoft--and believe me, I used to dream of being employed by Microsoft but I couldn't handle being over there without making splashes of rocking the boat as one of their annoying little junior programmers--but I've invested almost entirely into them and placed all of my chips on them. I've "worked with" them, as a third party, for a decade now, and I know how they think. Yes, they've been complacent with Internet Explorer. Yes, they've forgotten how to innovate on that platform.

However, I think they have the talent and technology bases available at their disposal to make an overhaul of Internet Explorer possible.

While little if any of the following is going to happen, just imagine the innovative integration of all of these into the same web browser:

  • Expression Web's layout engine, add CSS2 flawlessness, limited CSS3 support, full support for frames, plug-ins, and COM objets
  • Silverlight's "script engine" (Jscript, C#, VB.NET, Ruby, Python) fully exposed two-ways between the CLR and the W3C DOM, and the basis for a Canvas context and SVG support
  • Scaled-down implementation of Visual Studio 2008's powerful and introspective script debugger (but perhaps integrated into the browser, and without the vulnerability of registry/tie-in corruption of the script debugger)

Add to this HTML 5 support and proper XHTML support (with in-line DTD extensions support) and you've got a winner.

Chances are, we'll see less than half of this. But if we only see a few security improvements and a few new improvements to CSS, or somesuch, I'm sorry, I'm afraid I will find myself returning the favor of betrayal, and get on board with the other bandwagon. I will tinker with Firefox's componentization, something I've been wanting to tinker with anyway for a long time, and I'll start building my client-side code out based on features that Internet Explorer just doesn't have, like next-gen ECMAScript support and Canvas support.

IE will be there as a standby for plain old HTML 4 apps. But meanwhile, if I want Silverlight, I'll host it in Firefox or use Firefox's canvas, thanks.

So here's where I stand on this. Microsoft, if you're reading this, and care at all about my mere opinion, let me tell you what I think. When you say, "don't confuse silence for inaction," I think that your actions are meaningless. We don't want timely deliverables, so much as we want quality and feature-complete ones that are kept in check with the demands and expectations of your user base. I'll gladly wait until 2010 if I can JUST KNOW by your own word when it is coming, and that it is feature-complete. We don't necessarily want you to tell us what you're up to on your blog. We want to know that you to listen to what we think of the product when we all say the same things about your product in our blogs. We want to know that you care not for your reputation in your keeping silent, but for your user base, which means the web developer, not just the end user. We don't want your authortiative declarations of what is coming. We want your outspoken observations of what you are finding us most commonly demanding.

And we want those observations converted into promises. Promises that can be kept. Promises that you care about Windows playing nice with the Internet community by submitting to standards bodies outside of your own ego--CSS3, HTML5, SVG, and PNG, not just XAML, C#, and VBxx.

Project manager(s), you've got a big responsibility on your shoulders, millions of people are depending on your product. Deal with it. Stop cowering under your desk--get out there and shake hands with the people who care the most about your product, the web developers.

You're losing us.

See Also: http://people.opera.com/howcome/2007/msft/

ASP.NET: Rotated / Pivoted GridView

by Jon Davis 6. December 2007 11:17

I needed to rotate the content of my GridView control. I was databinding using business objects. Why is there no boolean pivot switch?

So I made my own control that inherits GridView. This is just a C# file; to use it, put it in the App_Code folder, and add <%@ Register Namespace="CustomControls" TagPrefix="Custom" %> to the ASPX file.

Not sure if it's buggy or not but it currently passes initial tests.

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;

namespace CustomControls {
    public partial class PivotDataGrid : System.Web.UI.WebControls.DataGrid
    {
        public PivotDataGrid() : base() { }

        public enum Pivot
        {
            /// <summary>
            /// Rotates the grid by rotating the data source in a replacement matrix. (not implemented)
            /// </summary>
            PreRender,
            /// <summary>
            /// Rotates the grid by converting the output to XML and rotating the cells.
            /// </summary>
            PostRender
        }

        private Pivot _PivotMode = Pivot.PostRender;
        public Pivot PivotMode
        {
            get { return _PivotMode; }
            set { _PivotMode = value; }
        }
        protected override void Render(HtmlTextWriter writer)
        {
            switch (PivotMode)
            {
                case Pivot.PostRender:
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    System.IO.StringWriter sw = new System.IO.StringWriter(sb);
                    HtmlTextWriter htw = new HtmlTextWriter(sw);
                    base.Render(htw);
                    System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
                    xDoc.LoadXml(sb.ToString().Replace("&nbsp;", "&#160;"));
                    System.Xml.XmlDocument xDoc2 = new System.Xml.XmlDocument();
                    xDoc2.LoadXml(xDoc.OuterXml);
                    XmlNodeList rowNodes = xDoc.SelectNodes("//tr");
                    XmlNode trParent = null;
                    if (rowNodes.Count > 0) trParent = rowNodes[0].ParentNode;
                    rowNodes = xDoc2.SelectNodes("//tr");
                    XmlNode trParent2 = null;
                    if (rowNodes.Count > 0) trParent2 = rowNodes[0].ParentNode;
                    for (int i = rowNodes.Count - 1; i >= 0; i--)
                    {
                        rowNodes[i].ParentNode.RemoveChild(rowNodes[i]);
                    }

                    RotateRows(trParent, trParent2, xDoc2);
                    writer.Write(xDoc2.OuterXml);

                    break;
                default:
                    base.Render(writer);
                    return;
            }
        }

        protected override void DataBind(bool raiseOnDataBinding)
        {
            switch (PivotMode)
            {
                case Pivot.PreRender:
                    RotateDataSource();
                    base.DataBind(raiseOnDataBinding);
                    break;
                case Pivot.PostRender:
                    base.DataBind(raiseOnDataBinding);
                    break;
            }
        }

        void RotateDataSource()
        {
            //object src = base.DataSource;
            //System.Reflection.PropertyInfo[] srcProps = src.GetType().GetProperties(System.Reflection.BindingFlags.GetProperty);
            //Dictionary<string, Dictionary<string, object>> newSource = new Dictionary<string, object>();
            //DataKeyArray keys = this.DataKeys;
            throw new NotImplementedException("PivotMode of Pivot.PreRender has not yet been implemented.");
        }

        //Cell[,] RowsToCells
        void RotateRows(XmlNode sourceParentNode, XmlNode targetParentNode, // bool rotate
            XmlDocument targetContext)
        {
            bool rotate = true;
            XmlNodeList trNodes = sourceParentNode.SelectNodes("tr");
            int rowLen = trNodes.Count;
            int colLen = 0;
            if (rowLen > 0) colLen = trNodes[0].SelectNodes("td").Count;
            Cell[,] cells;
            List<XmlAttribute>[] rowAttribs = new List<XmlAttribute>[rowLen];
            if (!rotate) cells = new Cell[rowLen, colLen];
            else cells = new Cell[colLen, rowLen];
            for (int r = 0; r < rowLen; r++)
            {
                rowAttribs[r] = new List<XmlAttribute>();
                for (int a = 0; a < trNodes[r].Attributes.Count; a++)
                {
                    XmlAttribute attrib = targetContext.CreateAttribute(trNodes[r].Attributes[a].Name);
                    attrib.Value = trNodes[r].Attributes[a].Value;
                    rowAttribs[r].Add(attrib);
                }

                for (int c = 0; c < colLen; c++)
                {
                    XmlNode tdNode = trNodes[r].SelectNodes("td")[c];
                    Cell cell = new Cell();
                    //cell.Attributes = tdNode[c].Attributes;
                    cell.Attributes = new List<XmlAttribute>();
                    for (int a = 0; a < tdNode.Attributes.Count; a++)
                    {
                        XmlAttribute attrib = targetContext.CreateAttribute(tdNode.Attributes[a].Name);
                        attrib.Value = tdNode.Attributes[a].Value;
                        cell.Attributes.Add(attrib);
                    }
                    cell.InnerXml = trNodes[r].SelectNodes("td")[c].InnerXml;
                    if (rotate) cells[c, r] = cell;
                    else cells[r, c] = cell;
                }
            }
            //return cells;
            for (int cR = cells.GetLowerBound(0); cR <= cells.GetUpperBound(0); cR++)
            {
                XmlNode rowNode = targetContext.CreateElement("tr");
                for (int cC = cells.GetLowerBound(1); cC <= cells.GetUpperBound(1); cC++)
                {
                    Cell cell = cells[cR, cC];
                    XmlNode colNode = targetContext.CreateElement("td");
                    for (int a = 0; a < cell.Attributes.Count; a++)
                    {
                        colNode.Attributes.Append(cell.Attributes[a]);
                    }
                    colNode.InnerXml = cell.InnerXml;
                    if (rotate)
                        for (int rA = 0; rA < rowAttribs[cC].Count; rA++)
                        {
                            if (colNode.Attributes[rowAttribs[cC][rA].Name] != null)
                            {
                                colNode.Attributes[rowAttribs[cC][rA].Name].Value = rowAttribs[cC][rA].Value;
                            }
                            else
                            {
                                XmlAttribute newAttrib = targetContext.CreateAttribute(rowAttribs[cC][rA].Name);
                                newAttrib.Value = rowAttribs[cC][rA].Value;
                                colNode.Attributes.Append(newAttrib);
                            }
                        }
                    rowNode.AppendChild(colNode);
                }
                if (!rotate)
                    for (int rA = 0; rA < rowAttribs[cR].Count; rA++)
                    {
                        rowNode.Attributes.Append(rowAttribs[cR][rA]);
                    }
                targetParentNode.AppendChild(rowNode);
            }
        }

        class Cell
        {
            private List<XmlAttribute> _Attributes;

            public List<XmlAttribute> Attributes
            {
                get { return _Attributes; }
                set { _Attributes = value; }
            }

            private string _InnerXml;

            public string InnerXml
            {
                get { return _InnerXml; }
                set { _InnerXml = value; }
            }

        }
    }
}

kick it on DotNetKicks.com

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Open Source | Software Development | Web Development


 

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Jon Davis (aka "stimpy77") has been a programmer, developer, and consultant for web and Windows software solutions professionally since 1997, with experience ranging from OS and hardware support to DHTML programming to IIS/ASP web apps to Java network programming to Visual Basic applications to C# desktop apps.
 
Software in all forms is also his sole hobby, whether playing PC games or tinkering with programming them. "I was playing Defender on the Commodore 64," he reminisces, "when I decided at the age of 12 or so that I want to be a computer programmer when I grow up."

Jon was previously employed as a senior .NET developer at a very well-known Internet services company whom you're more likely than not to have directly done business with. However, this blog and all of jondavis.net have no affiliation with, and are not representative of, his former employer in any way.

Contact Me 


Tag cloud

Calendar

<<  October 2018  >>
MoTuWeThFrSaSu
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar