smithvoice.com
 Y'herd thisun? 

“Essentially nobody understands calculus the first time they take it. I didn't understand calculus the first time I took it. In fact, for most of us who teach calculus, the time we understood calculus was the time we taught it... and I recommend this as a method for learning anything.”

from Change And Motion: Calculus Made Clear by Professor Michael Starbird

VB Must Be Killed!

TaggedCoding, CSharp, VB

So I'm on amazon checking out the reviews of some book and I see this reviewer going way off because some of the code samples were in VB.net. Did you see that? I don't remember what book it was but I'll never forget how over the top that guy was, between the lines you could see the veins popping out all over his head.

As the tedium goes on over the merits of VB.net being more CLS-compliant and C# having temporary extensions to accomodate to-be-patched inadequacies in the v1 Framework the bottom line remains: the vbc beats the csc as often as the csc beats the vbc. It's a tie.

So if we're getting paid for results with a bonus for early delivery and the only examples we can find to match some requirement are in a different syntax-on-top-of-the-Framework than what we like, it's faster to port what's available and wrap a dll around what can't be ported than to wait for the rest of the world to come to their senses and realize that we are the center of the universe.

Most folks know that the anger behind all of the language flamewars is misplaced anyway. Every single feature is part of a language, or not part of it, simply because the different language teams made the decision to include it or not. C# and VB.net are products planned with a lot of research and made by people, not magical gifts from the heavens. All development languages in the world could offer everything, but the companies that sell those products choose what they want to provide customers with for the same reasons we choose the release features of our own apps: mostly deadlines and development costs.

Plus, in the bigger sphere where Accountants live, Microsoft has no big need to change the designs so long as the rage continues; It's like WNBC having Imus in the morning and Stern in the afternoon: the audience of one hated the other and both audiences listened to both to keep up on "their" battle ... and NBC took in double the money that they would have from a traditional radio war because they owned both camps. Get the idea? All of the other male-targetted stations in the tristate (the actual competitors) lost marketshare because of well-planned and well-managed core audience infighting.

Anyway, I got to thinking about this guy who firmly believes that all incarnations of VisualBasic should be erased from human memory like the Zohar from Nazi Germany and I imagined him putting out his first .Net program (probably sometime next year since he's got to wait for the C# syntax book to come out). And I see his company VP of Marketing struggling to XCOPY it to the Chairman of the Board's AMD64bit 17" widescreen laptop (running Windows 98, of course). And I see that perfectly object-modeled UnSafe-switched C# mortgage calculating applet pop up "mscoree.dll not found."

oops.

To users, the concern isn't in the details of the .Net language we chose... it's the detail of the that first startup. If they don't have the Framework installed then C#, VB.net, Managed C++ and even Eiffel ENViSioN all look like crap.

LongHorn might come out in 2005, probably it'll be 2006. And thus, by tradition, it will be 2007 or 2008 before it's widely deployed so doing a Framework check before starting any .Net app is going to be important for quite some time. But how do you get out of the Catch-22?

You could include the dotnetfx.exe installer in every app you deploy. 24MB added for the "maybe" might be ok with you if you're sure that none of your potential users will ever be an old timer with a 56K dialup or be anyone who might wonder how "Quick and Easy" that "Quick and Easy Mortgage Figure-Outer" can be when it checks in at 25MB. Or maybe you could somehow convince your company to buy into Thinstall (Isn't Thinstall the coolest ever? ... if only companies we work for could see the need. Too bad we can't tell them the need because from a high-level, non-geek, person-who-signs-the-purchase-orders point of view the explanation makes .Net look bad. Another Catch-22.)

The better route is to just casually, but clearly, specify somewhere near the app's download link that the .Net runtimes are required AND do a quick check for the Framework on startup of all of your apps using a non-.Net "loader".

And, here it comes: For that loader you've gotta truly use the "right" tool.

This means a tool that has NO dependancies, NO VMs, NO runtimes. It has to have the ability to read the registry and check that a Framework is installed and check that the version of the Framework is correct for the application. It has to be able to shell to the main assembly if the correct version of the Framework is found and, if not, pop up a messagebox telling the user what they need to do to get the Framework. It should get you quickly from idea to compile so a real RAD tool would be best.

And y'know what? Gravy would be if it could detect an internet connection and bring the user right to the download location.

And if there is no internet connection then it should still make it clear that the app can't start unless the machine has what's needed

Is that so much to ask?

Not for Delphi Classic.

Talk about a language war: C# v.s. VB has nothing over VB v.s. Delphi, and since both were RAD trendsetters made by competing vendors the arrows shot from both sides actually had strong points. Even if a development professional passionately hates VB, they'd be pretty hard pressed to deny that when young Billy Gates teamed BASIC with Alan Cooper's Ruby form engine it was a stroke of genius and the result, good or bad, was truly a revolution in RAD development. And even the most hardcore VB user should think twice before publicly claiming that Delphi didn't take the ball and run off with it; had it not been for the Pascal semicolons and braces looking so much like dreaded C++, Delphi could have taken a huge bite out of VB's marketshare.

Microsoft did another perfect combination when they bought the Daddy of TurboPascal and Delphi (and an expert in the VBRT/VM RAD fundamentals due to it being his primary direct competitor for so long), Anders Hejlsberg, to put the broad strokes together in C# and in the architecture of The Framework itself.

So why Delphi for the Loader? Because as long as you don't need to hit a database or use DirectX, Delphi Classic makes completely linked executables requiring no runtimes even if they're full of visual flashiness.

Have a loader, my treat

All you do is put one self-contained exe in the same folder as your main assembly and rename it to be the name of your assembly plus "_loader.exe". So if your exe is MyCoolCalculator.exe then you name the loader file to be MyCoolCalculator_loader.exe, if your app exe is "GolfMaster.exe" then rename the loader "GolfMaster_loader.exe" and so on. The exe names are case insensitive.

Obviously you should make the loader exe the entry point to the program in your Wise or InstallShield setups. If you're XCopying, tell the user to create a shortcut to the loader exe (You know, XCOPY is nice but for most non-geek users it's best to at least make a VBScript batch file that does the XCOPY and creates a shortcut for the user. But that's just my opinion.)

Click here for the exe.

And for your head, even if you don't have Delphi, here's the code. It's Delphi5 because the nice Inprise folks gave me a copy when it came out but it's very simple code and should port up to UnManaged Delphi8 just fine. I admit that it says "Refactor Me!" all over it and from a Delphite point of view it's bad form, but I don't use the tool every day. Style warts aside, it does the spec. Plus, free and available now beats doggin' it too much and not getting the benefit, right?

 

program svLoader;
uses
Windows,
SysUtils,
Controls,
Forms,
Dialogs,
ShellAPI,
Registry,
Wininet,
Classes,
StdCtrls;
var
bHasFramework: Boolean = False;
bHasFramework114322: Boolean = False;
function IsUserOnline:boolean;
 var
connect_status:dword;
 begin
connect_status := 2 {user uses a lan}    +
1 {user uses a modem.} +
4 {user uses a proxy}  ;
result := InternetGetConnectedState(@connect_status,0);
 end;
function LeftStr(const S: String; i: Integer): String;
begin
Result := Copy(S, 1, i);
end;
procedure DetectFramework();
 var
Reg: TRegistry;
sRet: string;
 begin
Reg := TRegistry.create;
try
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKey('\SOFTWARE\Microsoft\.NETFramework', False);
sRet := Reg.ReadString('InstallRoot');
except
on ERegistryException do
MessageDlg('Problems accessing the registry!', mtError, [mbOK], 0);
end;
If Length(sRet) <> 0 then bHasFramework := true;
finally
Reg.CloseKey;
Reg.Free;
end;
end;
procedure DetectFrameworkVersion();
var
Reg: TRegistry;
sRet: string;
begin
Reg := TRegistry.create;
try
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKey('Software\Microsoft\.NETFramework\policy\v1.1', False);
sRet := Reg.ReadString('4322');
except
on ERegistryException do
MessageDlg('Problems accessing the registry!', mtError, [mbOK], 0);
end;
If Length(sRet) <> 0 then bHasFramework114322 := true;
finally
Reg.CloseKey;
Reg.Free;
end;
end;
function FrameworkCheck():Boolean;
 var
sMessage: String;
dlgResult: Integer;
 begin
sMessage := 'This program requires the Microsoft.Net Framework 1.1' +
#10#13 +
'This operating system component is available on Windows Update.'
+ #10#13 + #10#13;
if not bHasFramework and isuseronline then
begin
sMessage := sMessage +
'To go to Windows Update now and install the .Net Framework 1.1, Press ''OK''' +
#10#13 +
'To update your computer at another time, Press ''Cancel''';
dlgResult := messagedlg(sMessage,mtInformation, mbOKCancel,0);
if dlgresult = mrOK then
begin
ShellExecute(0, 
Nil, 
Nil, 
Nil, 
SW_SHOWNORMAL);
result := false;
end
else
result := false;
end
else if not bHasFramework114322 and isuseronline then
begin
sMessage := sMessage +
'To go to Windows Update now and update your .Net Framework, Press ''OK''' +
#10#13 +
'To update your computer at another time, Press ''Cancel''';
dlgResult := messagedlg(sMessage,mtInformation, mbOKCancel,0);
if dlgresult = mrOK then
begin
ShellExecute(0, 
Nil, 
Nil, 
Nil, 
SW_SHOWNORMAL);
result := false;
end
else
result := false;
end
else if not bHasFramework and not isuseronline then
begin
sMessage := sMessage +
'Please connect to the internet and visit HTTP://WINDOWSUPDATE.MICROSOFT.COM' +
#10#13 +
'to install the .Net Framework.  Then retry this program.';
MessageBox(0,  PChar(smessage), PChar('DotNet Verification'), 
MB_OK + MB_ICONINFORMATION + MB_TASKMODAL);
result := false;
end
else if not bHasFramework114322 and not isuseronline then
begin
sMessage := sMessage +
'Please connect to the internet and visit HTTP://WINDOWSUPDATE.MICROSOFT.COM' +
#10#13 +
'to update your .Net Framework.  Then retry this program.';
MessageBox(0,  PChar(smessage), PChar('DotNet Verification'), 
MB_OK + MB_ICONINFORMATION + MB_TASKMODAL);
result := false;
end
 else if bHasFramework and bHasFramework114322 then
begin
result := true;
end
 end;
Procedure DoChecks();
var
exepath: string;
exename: string;
begin
DetectFramework;
DetectFrameworkVersion;
if FrameworkCheck = true then
begin
//trim to get the target exe name
exename := ExtractFileName(Application.Exename);
exename := LeftStr(exename, Length(exename) - 11);
//shell the app
exepath :=  ExtractFilePath(Application.ExeName) + exename + '.EXE' ;
ShellExecute(0, 'open', PChar(exepath), nil, nil, SW_SHOWNORMAL);
end
end;
begin
// the entry point
DoChecks();
end.

 

You still here? Cool. You get a special door prize. Here's an autorun exe you can stick on any cd or dvd-rom to kick off an html page.

Use this for your program install cds or to automatically show Aunt Martha a cd full of family pictures.

Like I said, making great looking and highly interactive startup screens with Delphi is a breeze (Can you say DemoShield-killer?) but making great looking web pages only takes a working knowledge of Notepad. The problem is that cd/dvd AutoRuns only work against actual executables. So this is a real executable; It does nothing more than shell the user's default web browser to open an HTML page located in the same folder.

Name the page you want to start "Default.htm" and save it to the root directory of the cd, drop the autorun.exe and autorun.inf text file in the root directory of the cd.

If you want the cd to have a special icon in the My Computer drive list, add a 32x32 or 16x16 icon file to the root folder and specify that icon in the AutoRun.inf file.

Instant magic. Click here and it's yours as my gift.

Hope that helps.

Robert Smith
Kirkland, WA



home     who is smith    contact smith     rss feed π
Since 1997 a place for my stuff, and it if helps you too then all the better smithvoice.com