The more I develop for Windows Phone 7…

… I’m not sure how to finish that sentence.

I signed up to be a Windows Phone 7 developer for free via Dreamspark, which lets you submit 5 apps for free. Considering Microsoft decided to be even greedier than Apple (which is hard to do…) and charges $100/year PLUS a $25 submission fee PER APP (including free apps), I figured this was quite a deal.

While it probably is, I’ve already run into a couple really annoying snags. The latest of which has me downright mad.

First off, I consider it a fundamental right that when you buy something, you should be able to modify it. If that something happens to be a computer, you should be able to write your own programs for it. When Microsoft first announced that Windows Phone 7 would be locked down in a manner akin to Apple… (you have to pay to put YOUR code on YOUR device) well lets just say I was disappointed. Tremendously. Nevertheless, I have been wanting to try my hand at mobile developement, and I despise Objective-C. WP7 uses .NET. I know .NET.

So after I signed up for the Dreamspark account, I learned that you cannot actually deploy an app to the phone until after your identity has been verified. If you have a Paid account, this happens as soon as you sign up. For students, it doesn’t happen until you submit your first app.

So I wrote a silly junk app and sumbitted it. (I later realized that if it passed inspection, I would have wasted one of my 5 free submissions…)
Identity verified, Phone unlocked. FINALLY, I could write my own phone apps.

So I have a couple ideas I’m banging away at – some of them are really just for my own benefit, some are headed to the marketplace.
Just today I realized that the prominent free Tip Calculator sucked, and that I could write a better one. I get it developed to the point of testing, and attempt to deploy it to the phone.
And I quote,

“Unable to install application. The maximum number of developer applications on this phone has been reached. Please uninstall a developer application and try again.”

WHAT??!!?

Why in the name of God’s green earth would they limit the number of MY OWN apps I can deploy to MY OWN phone? What possible rationale could they have?
Does this mean that I would have to buy my own app in order to use it without restriction?

Apparently if I had a paid account, I could have 10 developer apps instead of 3, but it doesn’t matter – in fact it’s even worse.

Requiring me to have a developer account to deploy my apps on my phone is stupid.
Requiring me to verify my identity to deploy my apps on my phone is stupid.
Limiting the number of my apps I can deploy on my phone is downright asinine.

Since I am having such a good time ranting, here are more greivances:

  • MVVM (Model View View-Model) Designed to create a logical separation of Design and Code. Great in theory. In practice, it makes the code much harder to read and write by a casual coder; it comes with significant overhead (most guides are recommending against using it if performance is a concern), and the name is ridiculous.
  • You have XNA or Silverlight. XNA requires redesigning the wheel if you want UI elements. Silverlight is a framework in a framework (i.e., slow)
  • Making your app resemble the functionality of the built-in apps requires reinventing the wheel. Page transitions, for example, should be built-in. Instead you have to create XAML animations to do it yourself.
    (And did I mention that the more XAML your app has, the longer it takes to load?)
  • Something as simple as the built in “I’m working” animation has a bug that causes major performance issues.
  • You cannot access the compass. Seriously? iPhones and Android phones have had compasses for how long?
  • You cannot access video from the camera. This seriously limits the usefulness of barcode scanner software…
  • You cannot do anything involving the web synchronously (inherited from silverlight). I know, I know, blocking the UI thread is a bad idea, but the sheer quantity of code required to simply pull down a web page is staggering compared to the synchronous equivalent. To do an HTTP post? Why on earth do I need a callback for a stream containing “u=jason”…

Word on the street is that Microsoft is planning to open things up a little. I really hope so. I just dusted off my Mac Mini and installed Xcode — if I’m going to have my hands tied, it might as well be on the more popular platform…

Adding task panes in a Office Add-in when using IDTExtensibility2

If you are creating an Office Add-in using VSTO, it is easy to create task panes. But what if you do not want to involve the VSTO Runtime?

Using VSTO makes creating Add-ins very simple, but that simplicity comes at a cost. ClickOnce is a major pain to deploy to users, VSTO Add-ins have a tendency to mysteriously disable themselves, and they load slow.

I have recently switched to using the Visual Studio Add-in wizard, which created Add-ins using the IDTExtensibility2 interface. It requires you to do a bit more legwork, but the generated solution comes with a pre-configured MSI installer project, just asking to be deployed via Group Policy.

My latest project needs to prompt a user to perform an action when Word documents of a certain type are opened. Sure, I could use a pop-up form, but that is so very un-office-like. Taskpanes are a much more integrated solution, but for some reason the documentation and examples on the internet are pretty bad. And confusing. And WAY over complicated.
While working on this, I almost gave up (deleted and then started over once), but persistence and experimentation paid off – I got it to work, and it was much easier than I expected.

The following assumes you have some experience creating Add-ins using IDTExtensibility2.

Create your add-in project (be sure to change the debug properties to run your desired application – it defaults to Visual Studio) , add a reference to System.Windows.Forms, and add the following using statements:

using System.Windows.Forms;
using Microsoft.Office.Core;

First you need to create a user control for your task pane. Microsoft’s example says you have to create a Form and a user control in a separate project, well this is simply not true.

Add a user control to your project. I left the default name of “UserControl1”. Just for fun, we’ll add a button and a label to the user control as well.

Find the modifiers property on the button and change it to public.

We are doing this so we can access the button’s events from the Add-in, and because I am lazy. (The correct way would be to add a public event to your UserControl1 class, and call it from your private button1 event handler)

Next, modify your Connect class to also implement the ICustomTaskPaneConsumer interface.

    public class Connect : Object, Extensibility.IDTExtensibility2, ICustomTaskPaneConsumer
    {
    //
    //

Lets also add a couple more class variables, just to keep life simple (and prevent things from going out of scope unexpectedly)

        private object applicationObject;
        private object addInInstance;
        // New vars for Custom task pane
        private ICTPFactory myCtpFactory;
        private CustomTaskPane myPane;
        private UserControl1 myControl;

Finally, you implement the CTPFactoryAvailable method – this provides you with the ICTPFactory instance that you will use to actually create the task pane. I have also included the example code to create and display our task pane.

        public void CTPFactoryAvailable(ICTPFactory CTPFactoryInst)
        {
            // Store the CTP Factory for future use. You need this to display
            // Custom Task Panes
            myCtpFactory = CTPFactoryInst;

            // Create the task pane using UserControl1 as the contents
            // The third parameter, when supplied, is Window object.
            myPane = myCtpFactory.CreateCTP("MyAddin1.UserControl1", "My Task Pane", Type.Missing);

            //Set the dock position and show the task pane
            myPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
            myPane.Visible = true;

            // CustomTaskPane.ContentControl is a reference to the control object
            myControl = (UserControl1)myPane.ContentControl;

            // assuming UserControl1.button1 is public, add a handler to the click event.
            myControl.button1.Click += new EventHandler(button1_Click);
        }

And lastly, add an event handler for the click event

        void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello World!");
        }

Now run your project, and the task pane should be there to greet you. Clicking the button will then display the hello world messagebox.

In my project, I kept my application logic in a separate class from the Connect class. All you need is a reference to the instance of ICTPFactory supplied by CTPFactoryAvailable to create and hide task panes.

For reference, here is the entire Connect.cs file.

namespace MyAddin1
{
    using System;
    using Extensibility;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using Microsoft.Office.Core;
    /// <summary>
    ///   The object for implementing an Add-in.
    /// </summary>
    /// <seealso class='IDTExtensibility2' />
    [GuidAttribute("62EFAKE8-FAKE-47EF-82FC-85C5FAKE977E"), ProgId("MyAddin1.Connect")]
    public class Connect : Object, Extensibility.IDTExtensibility2, ICustomTaskPaneConsumer
    {

        public Connect()
        {
        }

        public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
        {
            applicationObject = application;
            addInInstance = addInInst;
        }

        public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
        {
        }

        public void OnAddInsUpdate(ref System.Array custom)
        {
        }

        public void OnStartupComplete(ref System.Array custom)
        {
        }

        public void OnBeginShutdown(ref System.Array custom)
        {
        }

        public void CTPFactoryAvailable(ICTPFactory CTPFactoryInst)
        {
            // Store the CTP Factory for future use. You need this to display
            // Custom Task Panes
            myCtpFactory = CTPFactoryInst;

            // Create the task pane using UserControl1 as the contents
            // The third parameter, when supplied, is Window object.
            myPane = myCtpFactory.CreateCTP("MyAddin1.UserControl1", "My Task Pane", Type.Missing);

            //Set the dock position and show the task pane
            myPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
            myPane.Visible = true;

            // CustomTaskPane.ContentControl is a reference to the control object
            myControl = (UserControl1)myPane.ContentControl;

            // assuming UserControl1.button1 is public, add a handler to the click event.
            myControl.button1.Click += new EventHandler(button1_Click);
        }

        void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello World!");
        }


        private object applicationObject;
        private object addInInstance;
        // New vars for Custom task pane
        private ICTPFactory myCtpFactory;
        private CustomTaskPane myPane;
        private UserControl1 myControl;

    }
}

Getting around activation when virtualizing windows

I have been duplicating servers at work in preparation for testing upgrades. The virtualized environment lives in a completely isolated network, and it will only exist long enough to test some major upgrades.

Most of the servers p2v’d without asking for activation, but on the last server I was not so lucky.

When server 2008 demands activation, you either have to activate or it logs you out. Thankfully, I stumbled across this article:

http://www.petri.co.il/bypass-windows-server-2008-activation.htm

Essentially, you tell it to try activating (which fails, because there is no internet), then you select other options, and click on the “What is Activation” help link at the bottom. When the help window pops up, you search for “cmd”, and select the help article for Opening a command prompt. This will let you open a command prompt, where you can then type “explorer” and you will get your start menu and desktop, etc.

At this point, you could configure the network, and complete activation if you were so inclined. I was not.

Server 2008 (and Vista and Windows 7 and Server 2008 R2) normally provides a 60-day “grace period” for activation. This grace period can be extended by “rearming” windows activation up to three times. Most literature on the internet states that this allows you a 240-day trial period. What they don’t mention is that you can also rearm a machine that has “lost” its activation well beyond 240 days after installation.

Follow the directions here:

http://support.microsoft.com/kb/948472

That is,
Open an elevated command prompt, and run “slmgr.vbs -rearm”. After a bit you should get a pop up telling you that it succeeded.
Note: because this must be run from an elevated command prompt, you still need to start explorer first.

Hope this helps save you some time!

Error loading operating system after vmware converter

Today I performed a p2v conversion of a Windows XP workstation into VMWare ESXi using the free VMware Converter. This tool is really wonderful, but sometimes it likes to leave windows in an inconsistent state – especially if you resize the partition.
This case is complicated by the fact that the source computer has the Dell recovery partition, which I decided to bring along as well. After conversion, I shut down the source PC, and power on the VM, only to get Error loading operating system.

The internets failed me. Plenty of people have had the problem, but most of the solutions involved Linux or Vista+ (or reformatting. Obviously not an option). Additionally, I have encountered this problem when performing a p2v on a Server 2008 box…

I tried using the windows XP cd recovery console with fixboot and fixmbr. It didn’t work. I fooled around with the UBCD. Again, didn’t work (and wasted a lot of time) Finally, I fell back on previous experience, and found my solution: use the server 2008 CD to fix windows XP! (This would probably work with the Vista or windows 7 images as well)

So here are the steps to fix the “Error loading operating system” issue (with Windows XP ONLY) caused by vmware converter:

  1. Boot with a Server 2008 disk (Vista, Win 7 might work as well)
  2. At the language screen click next
  3. At the “Install windows” screen, click “Repair your computer” to the lower left
  4. The next screen “System Recovery Options” will have an empty list, but that is ok! Click Next
  5. Click “Command Prompt”
  6. At the command prompt, type the following:
    bootsect /nt52 ALL /force /mbr
    note: in my case, using “ALL” instead of “c:” or “SYS” was what finally solved it
  7. exit out and reboot – with any luck, windows XP will now boot!

If you still have a problem, my only other suggestion would be to use diskpart to ensure that the correct partition is active. If that diesn’t solve it, maybe the other Google results will

Good luck, and please leave a comment if this helped!

Not sure what to make of this

I’m installing the Sharepoint Foundation 2010 prerequisites, and happened to notice this little gem:

Already downloaded more than the size of the file

This does not bode well..

Welcome back!

Shulerent.com is relaunched as Jason Shuler’s Tech Blog using WordPress (instead of Nucleus).

I have decided to venture outside the realm of obscurity, and join the community. Nucleus really wasn’t up to the challenge, and Shuler Enterprises is no real company… so a change of venue and name was in order. I will still need to go back through and perform some cleanup, since all previous posts were imported.

Stay tuned for more frequent updates and I attempt to integrate my online presence

-Jason