Wednesday, November 25, 2009

Booting from a cloned VHD in Win7

This is my attempt to make a serious "how to" contribution to the Windows 7 software development community, and, hopefully, make something that I learned the hard way simpler for someone else.

I have my Windows system on my work computer set up the way I want it, with all the utilities and programs that I use installed.  But I wanted to run the new Beta of Visual Studio 2010. However, there's a standing (and understandable) rule: no beta software on computers that you're doing production work on.  But my boss did give me permission to use it on the project I'm working on (since it won't be production ready until after the scheduled release of VS2010 in March) PROVIDED that I run it in a segregated environment such as a Virtual PC) so that it can't corrupt anything else.

I had run the beta of Windows 7 in a Virtual PC when it came out, but it was painfully slow. Windows 7 has the capability to boot up from a Virtual Hard Disk (VHD) as though it were actually a hard disk and run with minimal speed degradation (the disk access is somewhat slower, but everything else is running just as fast, because you are actually running on the hardware, not a program simulating the hardware). So I decided I would clone my existing system drive, which is configured the way I want it, and boot from that.  Should be simple, right?  WRONG!  There are a number of hidden gotchas along the way, which this post is intended to walk you through.

However, a couple caveats before you start down this road with me:  I run my systems a little different than it comes out of the box.  I have my disk partitioned in 2, similar to the way I learned to do it under Unix:  I have a system drive (C:), but all my user data is on a separate partition.  I assign the drive letter U: (for Users) to this partition.  There's a number of reasons I do this, but for the purposes of this discussion, it means my working data is available to me whether I'm booted into the real system drive or to the VHD drive.  If you have your drive setup the way Windows does it out of the box, with everything on C:, and your user data in C:\Users\<username>, then it's going to be clumsy, at best,  to access the files you write in one instance from the other instance.

The other caveat is that you need enough free space on your disk to hold the VHD in a fully expanded form.  In practice, this probably means that if your disk is more than half full, this isn't going to work for you.

Okay, that being said, here's the steps I took (on about the 5th iteration of this process). (Also, be warned that a couple of these steps can take quite a bit of time - altogether, this process could take half a workday.) (Also, if you run as a non-privileged user, most of these steps need to be run as administrator.)

1. Clean your system disk. Get rid of all the junk on it, because you're going to be cloning the disk and you want it as clean as  possible.  I use a freeware program called "CCleaner" (http://www.ccleaner.com/) which empties the Recycle bin, clears your browser cache, gets rid of temporary files, etc.  When you finish, look at the properties of the drive to determine how much space is actually being used and how much is free.  This will be important later when we resize the cloned disk.
2. Defragment your disk.  Even though Windows runs defrag periodically, and will probably tell you the disk doesn't need defragging, run it anyway, and specify the /X (consolidate free space) option.  I open an Administrative cmd prompt window (type "cmd" into the Start menu search box, then right click the "cmd.exe" option that shows up, and select Run As Administrator), and type "defrag C: /U /V /X".  The idea is that we want to end up with all, or as much as possible, of the free space at the end of the drive.  (This process will take a fair amount of time - maybe 10-20 minutes if I remember right, depending on drive size and how fragmented it is.)
3. Download and run Disk2Vhd.exe (http://technet.microsoft.com/en-us/sysinternals/ee656415.aspx) from the SysInternals group at Microsoft.  In the list of disk partitions it gives you, select just your system partion (C:).  This will clone your system drive into a virtual hard disk file.  It's okay to put it on the same drive you're cloning.  This process will also take quite a while.
4. Once that is done, use Windows' Disk Manager to Attach the VHD as another hard drive.  Right click My Computer, and select Manage.  Then click Disk Management. When the storage manager comes up , Right click Disk Management, and select "Attach VHD".  Find the VHD file you created in the previous step, and attach it.   It will show it as an additional hard disk, but it will tell you it's offline, and help will say it has a serial number conflict with an existing drive.  Well, since we cloned it from the C: drive, it has the same serial number, so that makes sense. The good news is that it's easy to fix. If you right click the newly added Disk symbol (probably Disk 1), and select "Online", it will cure the problem and put the VHD online.
5.  If your drive had multiple partitions, you will see that the mounted VHD has space corresponding to the space those partitions took up. The space will be shown as "RAW" partions.  We need to delete those. Right click each of them (except the one corresponding to your cloned system partition), and select "Delete Volume".  The space will now be shown as "Unallocated", and adjacent Unallocated partitions, if they exist, will be merged.
6. Now right click the partition corresponding to your cloned system drive, and select "Shrink Volume". It will spend a couple minutes analyzing the partition to see how much it can shrink it,  then will give you a dialog box showing you how much space is now being taken up (the full size of your original partition), and how much is available to shrink.  There will be a textbox/spinner to let you select how much you actually want to shrink it, and then shows the resulting final size after the designated shrink is applied.
There's a trade off here.   The size you shrink it to becomes, in effect, the "physical size" of the new VHD, and you want to give yourself some room for expansion.  On the other hand, when you're booted to the VHD, the system will expand it on disk to the full "physical size" specified, and you have to have room on the disk for that expansion, or the boot will fail. So, for example, if I have a 100G C: drive, with 30G used, and I clone it, the clone file may actually only take up, say, 25G.  But if the "physical size" that I've specified for the VHD is 50G, when I boot from it, the OS will expand that 25G to the full 50G, which still leaves 100-(50+30) = 20G free.  But if I now copy 25G of video onto that physical disk, then the new free space is 20G (100G - (30G+20G+25G)), but when I boot into the VHD,  the OS will try to expand it and run out of room, and the boot will fail.  So, make the size big enough to accommodate reasonable expansion, but balance that against the free space on the disk.
7. Once you've finished the shrink operation, right click the Disk in Disk Management, and select "Detach VHD".
8. We've shrunk the operating system's conception of the file, but the VHD still thinks it is the size of the original physical disk. Download VHD_Resizer (http://vmtoolkit.com/files/folders/converters/entry87.aspx).  (You will need to create an account, but it's free and appears to be innocuous.)  In our example above, the VHD still thinks it's of a 100G drive, even though it may only have 50G of content on it. Run the resizer, select the VHD file that you've created, and specify a Save location for the new, re-sized VHD that it's going to create.  You will end up, temporarily, with two copies of a pretty big file.  If you don't have space available on another partition, you may need to temporarily attach an external drive.  Specify the size that you shrunk the VHD to in the previous step as the size of the target file.  The program is going to do a sector by sector copy of the source VHD to the target VHD, so this operation will also take a while.  When you're done, you can delete the source VHD, and move the target VHD to it's final location. 9.   We probably need to rewrite the boot sector, using a program from the boot subdirectory of the Windows install DVD called bootsect.exe.  Attach the VHD using Disk Manager as before, then use the command "bootsect.exe /NT60 F: /FORCE /MBR" (substitute whatever drive letter the VHD gets attached as for the "F:"). Detach the VHD when you're done.
10. Now we need to modify the System Boot Configuration Data to add the VHD as a boot configuration.  Scott Hanselman has an excellent blog post on this, and I'll refer you there (http://www.hanselman.com/blog/LessVirtualMoreMachineWindows7AndTheMagicOfBootToVHD.aspx) for instructions.
11. Once you have done that, you should be able to restart your system, and have the new VHD entry presented in the boot menu options.  Go ahead and boot to it, then open a cmd shell and type "echo %SystemDrive%".  The response is the drive letter that was assigned to the VHD.  Don't modify anything.  Restart the system and boot back to the native drive.
12. Final step. We need to modify the registry on the VHD so that it will cause the VHD to come up as the C: drive, and move the C: drive someplace else. We need to do this because the Registry on the VHD disk is a clone of the Registry that was on the native drive, and contains lots of paths that are hard-coded to the C: drive.  If you don't modify where your VHD  mounts, a lot of things that you think are pointed to VHD will actually point to the C: drive, and you won't have an isolated environment at all. Here's what we need to do.
  • Mount the VHD in Disk Manager again.
  • Open regedit.
  • Click HKEY_LOCAL_MACHINE
  • Click File -> Load Hive
  • In the browser window, navigate to F: (or whatever drive your VHD is mounted to)\Winows\System32\Config\SYSTEM, and click Open
  • When it asks for a key name, make something up (I used "TempReg")
  • Now Click the TempReg key that you just created, and under that click "MountedDevices"
  • Right-click the key "DosDevices\C:", select Rename from the context menu, and change the C: to some unused drive letter on your system (I used Z:).  This is where your native drive will now show up when you boot from the VHD.
  • Right-click the key "DosDevices\<x>:", where <X> is whatever drive letter you found in the %SystemDrive% environment variable above.  Relect Rename, and rename it to "DosDevices\C:".   Now your VHD will boot as the C: Drive.
  • Click the TempReg key, and then click File -> Unload Hive.
  • Close the Registry Editor
  • Detach the VHD in disk manager
And (if I haven't forgotten any steps and everything has worked right), you're done.  Just to double check, while you're still booted into the native drive, create a text file someplace on that drive (make sure you know where it is).  Now when you boot to the VHD, that file should NOT be in that place on the C: drive, because it's a different C:.  But you should be able to find it on the drive you relocated C: drive (Z: in my example).

Acknowledgements

I want to thank Scott Hanselman from Microsoft (@shanselman) for his attention and assistance during this process, and Garry Martin (@garrymartin) for helping me understand the VHD expansion on boot process, and the boot sector rewrite process.  I would not have succeeded without their help.

Please feel free to leave comments or email me if this doesn't work for you.



Saturday, August 22, 2009

Building a new computer

I'm about to start building myself a new computer.  And I thought I'd document the project for myself and anyone interested.

When I tell people that I'm going to build a computer, they react something along the lines of "Wow, where did you learn how to build a computer?"

It's really not that hard these days.  If you've got the mechanical aptitude and patience to screw a few (sometimes tiny) screws in, you can probaby handle it.  It's just a screwdriver project.

But first, why?

Especially since I have 3 computers now.

I have a server computer that just sits in the corner and (mostly) stores the files that I want to keep around for long term storage.  Then I have a laptop that I got a little over a year ago (when I thought I was going to be doing quite a bit of traveling for a contracting job that didn't materialize).  And finally, a desktop computer that I actually do most of my work on.

Now, the desktop is over 4 years old, which isn't that bad in and of itself. I've extended it with more memory and bigger disks, so it does pretty much what I need. That is, when it's working. And therein lies the rub.  Recently (like the last 6 months or so), it's been getting cantankerous, and refusing to come back up when it's been powered down for a long period of time (usually several hours or more).  Most of the time, it does eventually come back up, if I just leave it alone (powered on), and wait.  Usually 12-24 hours.

But when I got back from my vacation to Costa Rica a few weeks ago,  it took me almost a week to get it up and running reliably again.  It would come up for a while, and then crash and not boot for a day or two.  And that's just too unreliable for me to use. So I decided it needed to be replaced.

The second question, then, is why am I building a new computer instead of just buying one?

In general, the argument that you can save money by building it yourself is spurious.  If you go to a computer store and buy all the equivalent parts that you need to build a computer with the same capabilities as one on the store shelf, you are going to spend very, very close to the same amount of money, perhaps a little more, than if you had just bought one off the shelf.  And you're going to have to put in the time and effort to build it yourself, plus lose out on the vendor support aspect.

But, in this case, I'll be able to re-use several of the components from my existing computer, and also tailor the system to have exactly the capabilities I want.

To build a computer, you basically need to assemble the following components:
Case
Power Supply (may come with the case)
Mother board
Processor (CPU)
Memory
Video card (may be built into motherboard)
Disk drive(s)
CD/DVD/Blu-Ray (your choice) reader/burner
Keyboard
Mouse
Speakers
Display
Software (Operating System)

Now, in this case, I think (remains to be seen) that I can use the case from the old computer, I already have an almost new power supply that will work, I will use the disk drives and DVD burner form the old computer, and, of course, I have the keyboard, mouse, speakers, and display. And I have access to the Operating System (Windows 7) because of my work as a Microsoft developer.

I'm using the lowest end of the very latest series of processors from Intel (a core i7-920), which means that, if I want more performance in the future, I'll be able to swap out the processor for one with as much as 50% more throughput (they're just kinda pricey right now, and I don't really need that much power right now.)

The choice of that processor constrained the choices of mother boards that I could make that would be compatible with it.  And all of them used a newer generation of memory (DDR3) than what was in my old computer, so I'll have to buy new memory. The good news is the price of memory has come down and the capacity has gone up.  Where I might have spent $100 for a Gigabyte of RAM when I last bought a computer, I can now get 6 Gigabytes for $100.  And the processor uses a new memory architecture called Tri-Channel that (apparently) serves up 3 times the memory information at once.  Memory speed is ultimately the biggest performance-limiting bottle-neck in a system, so this system should be blazing.

So, I needed to buy a mother board (ebay for $167 including shipping), processor (ebay for  $247 including shipping), a video card (Fry's $45 including tax after rebate), and memory ($100 after rebate, give or take. I'm on my way to get that in a little while.)  So for less than $500, I've got the machine I want, with the latest generation and a clear upgrade path, and, to have bought a similar machine would have cost in the vicinity of $1000.

All the components except the memory are now in my living room, so I'll document my progress as I go.  Stay tuned.

Why do I Blog?

I was listening to a podcast the other day (side note: I've just discovered podcasts since I got my new iPhone, and they're great for making use of drive time and workout time) with Microsoft guru Scott Hanselman and developer Joel Spolsky. Joel made a couple comments about blogging. One was that 90+% of bloggers start out their blog with big, grandiose mission statement type blog, and that's there first and last blog. They never post again. (I'm almost that bad, but I have been posting irregularly for several months now.)

But the more insightful comment was that most people blog in almost complete oblivion for a year or more, with virtually no followers (that's me!), and then, at some point, they make a blog post that get's picked up and becomes the post that they are known for (still waiting for that to happen.  Of course, it's more likely to happen if I actually post some stuff).

But he also noted that a lot of times bloggers will put stuff in their blog JUST SO THEY CAN FIND IT! Because blogs ARE crawled by Google, and, when you note something in your blog, you'll be able to find it by googling for it.

This blog is a really somewhat schizophrenic, in that I have two widely divergent interests that I tend to blog about - technology, and my spiritual journey.  These have drastically different intended audiences, and half the time I'm not sure who my intended audience is. I initially thought about making two separate blogs, but coming up with a name for one of them was hard enough.  And I looked to other Christian bloggers (notably Greg Beamer, a fairly well-known developer who writes the "Stop Making Sense" blog and signs off his entries  "Grace and Peace"), and noted that they had mixed content, so I thought I'd try it.



Monday, July 13, 2009

This I believe, pt. 3 - Jesus Christ died and rose again

Sorry it's been so long since my part 2 post.  I really meant to do these in more rapid succession.

When I say that I believe Jesus Christ died and rose again, I think that belief is supported aside from any reliance on the Bible.  I think there is more than adequate historical evidence that a man who went by the name Jesus (although I think in his native Hebrew or Aramaic, it was probably something closer to "Yoshua") lived in Israel in the opening decades of the common era, and that he was executed as a criminal by crucifixion by the ruling Roman government.  I really doubt that there are many people who would seriously dispute that.

He had a small group of close followers that we today refer to as the disciples or apostles. And several members of this group proclaimed that he rose from the dead after the crucifixion, and spent many days walking, talking, even eating with them.  Now, I expect that there are many who would dispute that.

But there is one historical fact that convinces me that it is true.  Virtually everyone of those original apostles died a martyr's death before the end of the first century, solely because of their proclamation of that fact.

So, you might say, many people through history have died for what they believed in.  That doesn't prove anything.

Yes.  People die for what they believe in.  But they DON'T die for something they know to be a hoax or a lie.  These apostles had every reason to KNOW with certainty that what they were saying about Jesus having come back to life was true.  They claimed that they had seen him, that he had talked with them and taught them, that they had touched him, that he had asked for something to eat and consumed it in their presence, that he had cooked breakfast for them over an open campfire.

Either those things were true, or else they knew that they had all conspired together to make it up for some unknown reason.  And everyone of them clung to the proclamation of its truth, even to their own death.

No one dies for something they know to be a lie.

So I conclude that Jesus did, indeed, rise from the dead.

And if he did that, then I conclude that validates every claim that he made to being the Son of God.  And it gives untold authority to everything else he said and did through his life. And it means that there are a whole lot of things I can conclude and safely rely on based solely on the things that Jesus taught.

One is the nature of the God that, in part 2, I concluded exists.  Jesus proclaimed several things about God that were revolutionary in his time.  One was addressing him as "Father", in a close, personal relationship.  This was revolutionary in the Jewish thinking. God was holy, majestic, glorious, awesome, and basically unapproachable except through the priests. But Jesus addressed him as "Daddy" (the modern equivalent of the Aramaic word he used). And he said, "You want to know what God's like?  Look at me.  He who has seen me has seen the father."

So I conclude that not only is God a being of unimaginable power and intelligence, as we can see through nature, but that he is personal, with a relationship with his Son.

And according to what Jesus taught, God cares about each one of us just as much.  And I believe his resurrection validates his teaching.

Monday, June 29, 2009

Boycott Chase!

Chase Bank doesn't get it!

The whole point of the recent congressional hearings on credit card abuse, together with the subsequently enacted rules changes, is that consumers are sick and tired of being manipulated and abused by the banks who have all the power in the credit card game.

But Chase just doesn't get it.

Earlier this week, I got this "Important Notice Regarding Changes to Your Account".  It read, in part.

"Your minimum payment due will increase from 2% to 5% of the ending balance on your monthly statement..."

Whaaaattt?   I owe over $13, 000 on that card.  That means my minimum monthly payment is going to jump from somewhere around $260 a month to $650 a month!  For no reason at all! just because they can!

In the past, whenever there has been a change to account terms, it seems like there's been a paragraph that says something like "If you do not want to accept these terms..." and basically says you can close your account and continue to pay off your balance under the existing terms.  Not this time. Uh-uh.  We're going to do it to you, and you have no choice but to take it.

I even called customer service and told them that those terms were not acceptable and I wanted to close the account and continue to pay it off under the existing terms.  He said, "I'm sorry, you do not have that option."

I asked, "How can you unilaterally change my repayment terms?"  And he replied, basically, we can to any thing we want.  This is a direct quote: "We can demand payment of 100% of the balance in the next 30 days if we choose to." The arrogance!

I'm obviously not a lawyer, and I probably haven't kept the 15 pages of fine print "terms and conditions" that they sent me when I opened the account, so I can't really say whether they legally have that right or not.  I'm going to assume that, being a big corporation with lots of high-powered lawyers, if they say they do, then they probably do. (At least under current law. Maybe that needs change.)

But whether they legally have that right or not, to exercise it in the cavalier manner they have chosen to, with total disregard for their customers,  is absolutely unconscionable.

Understand, I'm not a deadbeat.  I've occasionally run up more debt than I should, but I have always paid it off. Aside from maybe 1 or 2 statements that have gotten lost on a messy desk, I don't think I've missed a payment on any of my credit cards in the 30 years I've been using them.

I had cancer a few years ago.  During that time, I was unable to work, and my (then) wife was taking care of me, so she couldn't work.  For some period of time, we lived on the generosity of friends and, mostly, credit card advances. We ran up a very substantial credit card debt.  But even when the payments were consuming well over half of my limited disability income, I never missed a payment.   And I have completely paid off 4 of the credit cards, with only 2 to go (both of them being Chase cards).  So they had no reason to single me out for this action.

Chase (well, actually Washington Mutual, which has been acquired by Chase) has been my preferred bank for quite some time.  But I refuse to do business with a company that shows such complete disdain for the rights of its customers.  I will be moving every account I have with Chase to another bank as soon as I conveniently can, and I would call on all my readers (both of you! LOL) to do the same.

I would also call on Congress to look into further curbs on the power of big banks.  It appears that arbitrarily raising minimum payments was not one of the powers that was limited in the recent reforms.  We were warned in the press that if Congress took away the powers that banks had to stick us with punitive interest rates and fees, the banks would find other ways to stick it to us, and it appears that they have.  Congress, we need to change that, too.

Sunday, June 28, 2009

This I believe, pt 2 - There is a god

Note that I used a lower case 'g' on that title. At this stage of my apologetic, it can't be said that I'm necessarily talking about the Jehovah, the God of the Bible.

But, in my thinking, the fact that there is a supreme being of unimaginable power and intelligence is abundantly clear from the world around us. The only ones who can possibly deny that are those who have taken as a presupposition that there is no god.

Let me clarify what I mean by that. In any kind of logical reasoning, you start from some point, with some set of "givens", and construct your argument from the implications of those givens. They may be called axioms, or assumptions, or presuppositions. But within that sphere of logical reasoning, nothing can be permitted to contradict those givens.

One of the arguments heard in the evolution debate is that Christians accept God on "faith", the implication being that faith somehow contradicts reason. But the evolutionists have "faith", too - faith in their assumption that there is no god. And I conclude that it takes a great deal more "faith" in that assumption to reach the evolutionary world view than it does to accept the position that there is a god, and he created the world we live in.

I am NOT saying that one needs to start with the assumption that there is a god. One merely needs to eliminate the assumption that there is NOT a god. If you have that assumption, then you must bend and twist and look at the evidence from all manner of cock-eyed angles in order to avoid the conclusion that there is a god, because that contradicts your assumption. If you eliminate that assumption, than you are free to look at the evidence straight on, and my conclusion is that the evidence overwhelmingly points to the existence of a creator-god.

I remember some years ago hiking in Rocky Mountain National Park, and looking up in awe at the majestic rock formations towering hundreds of feet above me, and thinking, "And this was merely an afterthought of God's creative efforts." Okay, you can argue that that's merely the force of nature at work. But there are other arguments that suggest it is more than that.

I remember hearing one time (sorry, I can't remember the source) a man pick up a shoe, and saying "This shoe proves the existence of God."
And his listener replied "How?"
The man replied "Who made the shoe?"
"The cobbler."
"And who made the raw materials that the cobbler used to make the shoe."
"The cow."
"And what did the cow eat go grow?"
"Grass"
"And who made the grass?"

and so on, and so on. Eventually you get back to the "prime mover", the "first cause", something or someone made it all happen. Even if you subscribe to the "big bang" theory, where did this energy and matter that went into the "big bang" come from? Now the evolutionists at that point will say "Now you're getting out of the realm of science and into the realm of religion, and we can't answer that question." Well, duh, that's the point. You can't answer that question without violating your assumption that we there is no god, and that therefore we live in a closed universe free from anything that has to do with the supernatural.

But the thing that they miss is that the entire discussion is outside the realm of science. Evolution is not science. Science deals with the observable, the reproducible, the testable. You observe facts, you propound theories, you construct experiments to test your theories, and others can reproduce your work to verify it. Evolution does none of those. It cannot observe the origin of life, it cannot reproduce it, it cannot conduct experiments to test its theories. And just because 90%, or whatever the percentage is, of people accept a theory, does not mean that it is not still a theory.

So I believe that nature shows us that god exists, and that he is being of unimaginable power and grandeur.

But I believe nature also shows us that he is a being of supreme intelligence. I cannot understand the huge brouhaha over "Intelligent Design". It appears to me so obvious. If you're hiking in a desolate area, and you come upon, let's say, a watch, you don't pick it up and say, "My look at how these elements randomly assembled themselves into this watch." No, of course not. You conclude that someone was there before you and dropped the watch, because it's obvious that it was designed by an intelligence. [I know this is the age-old watchmaker analogy which has been "refuted", but all the "refutations" that I can find simply say, "no, natural selection can explain that design." Well, in my mind, it's a matter of which explanation makes more sense. Again, the natural selection argument is viable only if you start from a position that absolutely denies the possibility a god.] Nature in general, and the human body in particular, is of unimaginably complex design. To believe that it came about by mutations or other transformations happening randomly is beyond ludicrous. I remember someone once saying that's about as likely as an explosion in a type-setting factory producing the Encyclopedia Brittannica (obviously from a far earlier time when we still had encyclopedias!).

There is far more within the sphere of "Intelligent Design" than I want to go into here that, to my mind, clearly demonstrates that, not only is the god I believe in a god of supreme power, but also one of incredible intelligence.

And thus, I believe that god exists.

Tuesday, June 23, 2009

This I believe, pt 1

A friend posted the video below to his facebook page a week or so ago, with the comment "PLEASE TAKE TIME TO WATCH THIS VIDEO! I HOPE IT WILL CHANGE YOUR LIFE LIKE IT HAS CHANGED MINE RECENTLY!!!!" (thanks, Josh).

I found it compelling and yet disturbing. There is much that he says that I'm in full agreement with. And it's hard to say that there are things he says that I disagree with, because everything he says comes from scripture, and he's not misquoting it or misinterpreting it. And yet I find I strongly disagree with the overall message that seems to be coming through. Maybe it's what he doesn't say that I disagree with.

Watch these videos (it was posted a few days ago on YouTube in two parts, and that's the easiest for me to incorporate), and then read my thoughts below.


The Fire Part 01


The Fire Part 02

What he seems to be saying without saying it, is stop sinning so much and you won't go to hell. Nowhere does he ever talk about trusting in Christ for salvation, about being saved by God's grace, "not of works". And the monstrous problem with his message is, how do you ever know if you've stopped sinning "enough," if you've loved God "enough", if you've brought forth "enough" fruit? How can you be assured of salvation?

I heartily agree with his contention that we value the forgiveness of God far too cheaply. I agree that if we are truly saved, there will be fruit in our lives. But he seems to be saying that it's up to us to produce that fruit. He almost seems to be saying that anything less than sinless perfection means that you hate God and are going to hell.

I am a believer in Jesus Christ. I don't want to compare myself to others, but I think I take more seriously the claims of Christ and expend more effort in seeking to know him than most Christians I know. But I sin. I probably sin in areas I don't even recognize as sin. The Jews were commanded "You shall love the Lord your God with all your heart, with all your soul, with all your might". I know I don't do that perfectly, and not doing that perfectly is sin.

What this guy (Nate Pfeil, by the way) is saying strikes me as very much at odds with what I, as a lifelong "Evangelical" Christian, have been taught - that our salvation is dependent solely on our trust in the completed work of Christ, and, while it is our responsibility to surrender to God's work in our lives, it is the work of God through the Holy Spirit to bring forth the fruit in our lives.

And yet, as I said, his points are scriptural. So have I been led down the primrose path by, in his words "lying preachers, wolves in sheep's clothing?" As he says, his message is serious. The consequences of getting it wrong are too high. So it's prompting me to want to step back, re-examine and re-think what I believe and the basis for it. And I'm thinking, let's go ALL the way back, to "There is a god (and I'm not him!)". So I think that's what I'm going to do, and doing it in these pages will force me, I hope, to clarify my thoughts and the reasons behind them.

Stay tuned.

Wednesday, February 18, 2009

My website works on my machine, but it won't work on GoDaddy. How come?

Okay, as I said in my last post, I see a lot of posts in forums and newsgroups dealing with web development that are somewhere along the line of the title.  And it may be GoDaddy, or it may be some other shared hosting company.

I started writing this post about a week ago, and trying to recount my experiences chronologically became too long and rambling, so let me just list some of the problems that I have encountered.  I may expand on some of them in future posts.

1. You don't have control of your execution environment on a shared hosting service like you do when you're running on your own machine. You don't have control over what software has or hasn't been installed, or what the machine configuration settings are, etc. The first problem I encountered was that I had installed the MySql Connector that interfaces the .NET framework to a MySql database.  GoDaddy hadn't, or at least didn't have the same version that I had and that my program was expecting. (And they couldn't or wouldn't tell me what version, if any they did have.)  The work around is to make sure your program/website is completely self-contained, so that you're not relying on anything on their environment (in my case, by copying the MySqlData.dll into the "bin" directory of the website I was publishing to GoDaddy).

2. You're running in what is known as a "medium trust" environment in a shared hosting server.  Chances are, unless  you have deliberately configured it, your development and  test environment is a "high trust" environment.  What this basically means is that there are a whole  lot of perfectly legitimate things that your program might want to do that are simply not allowed in the medium trust environment.  This is worth a whole post of its own, but just let me say that, if you're going to be hosting your site on a shared hosting server, set up your development and test environment  for medium trust (I'll cover how in another post.  For now, if you need to know how, google it.)  You will save yourself a whole lot of headaches.

3. The database servers are probably different in some respects from what you're running on in development.  This will be particularly true in the case that you're using MySql (which I was), rather than Microsoft SQL Server (MSSQL).  There are two noticable differences, even though I was running MySql in my development environment as well. 

One is that the MySql server that was in my development environment was running on a Windows machine.  There's is running on a  Linux server.  Yes, the web server is hosted on a  Windows machine, but the database that it connects to is running on a  separate machine which is Linux.   The  key difference is that MySql on Windows is not case sensitive, while on Linux it is.  So a command like "SELECT productID FROM Products WHERE Sku=@Sku"  will work fine on a Windows base MySql Server, even if the columnname is actually productid and the table name is products.  But it will fail if that same database is hosted  on a  Linux server.

The second area of concern is that the security is much tighter on GoDaddy's database servers. Specifically, you cannot access anything outside of the database you're connected to, even if you have permissions for it (I'm  not sure how you would specify permissions for it.)  As a result, you are not even permitted to specify the database property of a table.  If you're not  aware of it, this can be a problem, because the MySql Connector that  interfaces with Visual Studio, by default, generates insert, update and delete commands that reference the tables as <databasename>.<tablename>  (E.g., INSERT INTO MyDB.Customer (CustomerName, ...) ) Even though the databasename is, in fact, the database that you are connected to and working with, simply specifying the database name will  kick the statement out on a permissions violation.  (The first time I saw this error, it said something like my Insert statement failed because I didn't have proper permissions, and I was on the phone complaining irately to GoDaddy Support that they had set up my database without giving me write access into my own tables!  It took  me a while to understand exactly how it worked.)

Another area where this comes into play is that, when you're dumping and restoring a database, you may have to edit the SQL that's generated to remove certain parameters.  When you define a View, the MySqldump will dump the CREATE VIEW statement with a "DEFINER" attribute.  Even  though the DEFINER is you, that will cause the statement to fail if you try tor use it to  restore the database on GoDaddy's servers.

Also, GoDaddy, allegedly for "security reasons" will not permit you to define your own stored procedures in your database (and don't tell you that until you try it and it fails with some obscure error!).  I'm not that good with databases, and so far, I've only had one instance where I was trying to use a stored procedure.  Fortunately, I was able to program around that one fairly easily.


So,  those are the three main areas.  There's probably some small incidents here and there that fall outside those bounds.  But that covers most of it.  And there are ways to work around all  of them. It's just a question of  how much work   you have to go through to do it.

I will try to expand on the "medium trust" issue in  another post.


Saturday, February 7, 2009

Hosting a Website on GoDaddy

I'm going to make this short right now, and post more in future days, hopefully.

One of the reasons I started this blog was to share what I had learned about hosting a website that I've developed on a shared hosting service, specifically, GoDaddy.com. 

In reading various ASP.NET forums, I am constantly seeing posts that say something like "I developed this website, and it works great on my development server, but it won't come up at all (or misbehaves in some particular way) when I port it to my hosting service."  Which was exactly my experience when I brought up my first site nearly a year ago.  And I solved a lot of problems, one at a time, and learned a lot, before I got it running. (BTW, it's broke right now, and I'm working on finding time to get it fixed.  Soon.)

But before I do post any of those lessons, I wanted to share a post made earlier this week by Joe Stagner of Microsoft. It's a 45-minute video on
Creating, Updating, and Publishing Web applications with Visual Web Developed Shared Hosting.

In it, he goes through the mechanics of loading your site to your hosting service, establishing your database, administering your site etc.  The particulars vary depending on your hosting company (and, unfortunately, none of them are remotely close for GoDaddy) but the basic idea is there.

I was disappointed that he did not go into some of the development issues to keep in mind - things you are allowed to do on your own machine that are guaranteed to break spectacularly when you put your application in a shared hosting environment.  But maybe he will in subsequent installments.  He did say this was the first of a series.

And, if not, all the more reason for me to write my posts...

Wednesday, February 4, 2009

Facebook

I have a confession!  Until recently, I was not on facebook!

It really was more that I just couldn't be bothered than that I was actively resisting.  But I kept getting more and more invitations from friends, and discovered that you really couldn't nose around and see anything about what your friends were doing unless you had an account there.  (Fair enough, I suppose.)

So, a few weeks ago, I relented and created an account.  And since then, I have been amazed at the number of people that I really do know that are there.   Some that I haven't seen in 40 years!  But I'm even more amazed at the number of times it (facebook) will suggest that I might know someone, and way more often than not,  they're right.  And I scratch my head and say, how on earth does it know that?

Be that  as it may, it appears that facebook is becoming (or has become) something of a phenomenon.  My friend George Hillman posted an entry on his blog the other day which caught my eye: Why aren't you on Facebook? In it, columnist Farhad Manjoo says that facebook has followed a similar evolution to that  of the cellphone - from an elitist gadget to something that is simply expected.  Facebook recently announced reaching a milestone of 150 million user accounts.

Anyway, I'm enjoying catching up with a lot of people that I wouldn't have otherwise.  There are certainly some objectionable possibilities, Mark Davis points out, you have complete control over what you do  with it and what you make of it.

Thursday, January 29, 2009

This shouldn’t be that hard!

For any of my vast number of readers (hah, hah) who have been following this blog, this post is more what I intended when I decided to start blogging, but so far, haven't gotten around to – a recounting of dealing with a technical issue.

So if you're not into software development, this will doubtless leave you cold, and you're forgiven if you want to go read something more interesting.

For the past 3 days I have been struggling to do something in Microsoft ASP.NET that should be duck soup. But it ain't.

I have a 24x7 array of data that I want to present and edit in a GridView.

Now, a GridView being a presentation control composed of a number of rows and a number of columns, one would think at first glance that he could simply set the DataSource to the array, and, voilá, it would appear. Not so.

In the end, the solution is not too, too terrible, but arriving at it is. This is owing in large part to the state of documentation of today's software products.

They come with megabytes and megabytes of hyper-linked references and how-to walkthroughs, which is great if the task you want to accomplish is exactly one of the walkthrough topics. But if not, you're left to try different combinations of words in various online and offline search engines and hope you hit a combination that lands on an article that somebody has fortuitously written that describes your plight, or something relevant to it.

Now, the Visual Studio Help file entry for "GridView" tells you:

The GridView control can be bound to a data source control (such as SqlDataSource, ObjectDataSource, and so on), as well as any data source that implements the System.Collections..::.IEnumerable interface (such as System.Data..::.DataView, System.Collections..::.ArrayList, or System.Collections..::.Hashtable).

(An IEnumerable is basically anything whose members you can sequence through one at a time – including an array.)

But then it goes on and tells you that there are two different ways to bind to the datasource, depending on which type you're using – a data source control, or an IEnumerable. And there's the first hint of difficulty.

The GridView is really designed to work with data from a database, and when you use it that way, everything just goes, point, point, click, click, and it just works. But when you start trying to figure out how to use it with arrays, you're just kinda left in the dark. Searching help files for "GridView binding to array" yields a bunch of articles and hyperlinked references on binding GridViews … to DataSource controls. I never could find a walk through on how to use it with an array.

When you bind to a Database data source (from now on referred to, as Microsoft does, as a "Data Source Control"), the binding goes in the aspx declarative markup, so it's there automatically each time the page is loaded. When you bind to an array, you have to set it programmatically, which basically means that you end up starting all over each time the page is loaded, including when anyone clicks on a button or link on the page.

I'm gonna cut to the chase here and skip dragging you through all the stumbling around that I did … partly in the interest of time, partly so I don't make myself look excessively stupid.

Yes, GridViews can be bound to arrays, although, at least not that I could find, to 2-dimensional arrays, at least not in the way that I wanted to. The thing is that you have to do everything just right, and if you don't, you're rewarded with … nothing. It just simply doesn't work, and you have no clue why.

The first thing is that, while a GridView looks like it would display a 2-dimensional array nicely, it really displays a one-dimensional sequence of objects (in its rows). The columns that it displays have to be Properties of the objects. Not just elements, but properties. Thus, one of my early attempts, for a programming exercise, involved an array of product elements:


public
class
shortProduct

{


public
int id;


public
string sku;


public
string name;


public
decimal cost;


public
bool fractional;


public
decimal weight;

}


I tried to bind an array of those to a GridView (actually, that was a Windows Form project, so it was a DataGridView, but it's the same principal), and got nothing, because those elements (id, sku, etc.) are just elements and not properties. When I converted them all to properties, and bound it to the control, they came up pretty as you please.

But that's a problem when you have a 2-dimensional array of simple elements. What I ended up doing was re-mapping it to an array of 7 objects, each of which was an array of 24 booleans. And then I defined 24 separate properties corresponding to each one of the Booleans. Now I could display it in a datagrid. Clumsy, but it worked:

public class ValidTimeDay

{

private bool[] _validTimeArray;

public bool ValidHour0 { get {return _validTimeArray[0];} set { _validTimeArray[0] = value}}

public bool ValidHour1 { get {return _validTimeArray[1];} set { _validTimeArray[1] = value}}

etc. down to

public bool ValidHour23 { get {return _validTimeArray[23];} set { _validTimeArray[23] = value}}


}


Now I had an object I could display in the GridView. I then mapped each of the 7 rows into one such object, and made the 7 objects into an array, and I could bind to it.

The other area where the GridView makes it difficult to work with arrays is in the editing features. Again, when you're working with Data Source controls, enabling editing of the data is pretty much point, point, click, click. Because the array doesn't have any kind of programmatic insert/update/delete interface, the GridView basically throws up its hands and leaves it up to you. You can get an Edit button on your GridView with just a few clicks, but everything else is up to you. You have to write the program code for handling each event in the process. And one thing that cost me about half a day of stumbling around until some kind soul on a forum gave me an example, the first thing you have to do is tell it what it's editing – even though it just told you . In your "RowEditing" event handler, the first line should be something akin to "GridView1.EditIndex = e.NewEditIndex". If you don't do that, nothing else happens! You also have to write the code to go back into the child controls of the GridView and figure out exactly what changes were made and store them in the array- that doesn't happen automatically either.

Once you know how to do something, it's not all that hard. It just shouldn't be that dang hard to figure out.




Monday, January 19, 2009

My first cruise




I’m writing this in the car on the way back from my first cruise. It’s something I’ve wanted to do for a long time, and let me say, right up front, I’m glad I went and I had a good time.

But it didn’t really meet my expectations, and I doubt I will go again. The problem may have been with my expectations, or it may have been with the cruise.

For one thing, at least in my mind, when one says “Caribbean Cruise”, one pictures, well… a CARIBBEAN cruise. Caribbean as in, primarily, warm, and with white sand beaches and blue water.

We left Dallas at 6:30 in the morning with the temperatures in the 20s. And while the cruise was certainly warmer than we left in Dallas, it didn’t match up with my mental picture of WARM. But I should have realized, even though we’re going to the Caribbean, we’re starting the voyage from Galveston, a scant 300 miles south of Dallas. Plus the same cold front that had sent temperatures plummeting in Dallas had pushed its way on south. While the temperature as we boarded the ship was in the 50s, there was a stiff north wind that kept me in sweatshirts and jackets nearly the whole trip.

So I guess the lesson to learn from that is, don’t plan a cruise out of Galveston in the middle of January if you’re expecting warm weather!

That same wind kept the seas rough. The ship was rolling from side to side, to the point where I had the sensation that I was going to roll right out of the bed. While I’m usually pretty good about motion sickness, by 3:00 PM of our first full day at sea, I was huddled in bed to keep from hurtling my lunch. Nancy, my girlfriend, went to the infirmary and brought back some motion sickness pills, which alleviated the sensation, but also virtually knocked me out till 8:00 the next morning.

The consolation, though, is that several cruise veterans said that was the roughest they had seen the seas on any of their cruises. So if I were to go again, that experience probably wouldn’t be repeated.

Overall, the cruise was very relaxing and enjoyable. I got to see a couple of beautiful sunrises (see photo) and sunsets over the water. The food was plentiful, and was certainly good, though I wouldn’t consider it superb. About on a par with what you would expect from your typical casual dining restaurant. However, the claim I have often heard that you can find something to eat at any hour of the day or night turned out to be not quite true, unless you count soft-serve ice cream. We went in search of some at 4:00 one morning, and the ice cream machine was about the only thing we found stirring.

While the weather in Cozumel was somewhat warmer (mid 70s), the same wind still dogged us, and it was cloudy, so I wasn’t really inclined to hit the beach with the few hours we had in port.

While there were certainly enjoyable activities on the ship (dancing, clubs, shows, parties, etc.), I guess I would much prefer, if I’m going to a Caribbean destination, to get there and spend the time on the beach or in the water, rather than spend a day and a half at sea (even if it’s enjoyable) each way to get a few hours at the destination.

But, at least I got to go, and that’s something I can cross off my list of things I’ve always wanted to do!