Making InfoPath 2010 Preview/Debug work again

Quick blog.  How I fixed InfoPath 2010 Debug/Preview error, after installing Office 2013.

InfoPath cannot open the selected form because of an error in the form's code.
InfoPath will fail to load this form because Microsoft .NET Framework 3.5 is not installed or is installed incorrectly

Install .NET Framework 3.5

First, if you are on Windows 8, you do need to install the .NET Framework 3.5 feature.  Do this via Add Windows Feature control panel.

 

Reverse the .NET Assembly Binding Redirect Policies

Fix these two policies that was redirecting v14 references to v15.

  • C:\Windows\assembly\GAC_MSIL\Policy.14.0.Microsoft.Office.InfoPath.Client.Internal.Host\15.0.0.0__71e9bce111e9429c\ Policy.14.0.Microsoft.Office.InfoPath.Client.Internal.Host.config
  • C:\Windows\assembly\GAC_MSIL\Policy.14.0.Microsoft.Office.InfoPath\15.0.0.0__71e9bce111e9429c\ Policy.14.0.Microsoft.Office.InfoPath.config

If you just change it to bind to the original version 14:

  • <bindingRedirect oldVersion="14.0.0.0" newVersion="14.0.0.0"></bindingRedirect>

 

Missing IPDMCTRL

If you see complains about ipdmctrl, copy it from:

  • C:\Program Files (x86)\Microsoft Visual Studio 11.0\Visual Studio Tools for Office\PIA\Common\IPDMCTRL.dll to C:\Program Files\Microsoft Office\Office14\

You can find IPDMCTRL in any Visual Studio Tools for Office installation.  Your directory could be different.

 

Use the Fusion Log Viewer tool

I figured this out using the fuslogvw tool - which logs .NET assembly loading events, and so I could figure out what it was trying to load when debugging, and failing.

image

 

Pics or it didn't happen

image

 

Here is both VS2012 debugging an InfoPath 2013 form, at the same time as VSTO debugging a separate InfoPath 2010 form.

SharePoint Saturday Perth - Building SharePoint solutions with TypeScript: how and why.

 

I'll be presenting a new topic for SharePoint Saturday Perth this year, on SharePoint and TypeScript.

While I had begin planning to work with TypeScript since the beginning of the year, I really owe it to Charlie Holland's blog post that really got me started.

Anyway, if you see the good parts in my demo, that'd be to his credit.  And if you see the lousy parts?  I'll claim those.

 

Building SharePoint Solutions with TypeScript

TypeScript is a new language designed as a superset of JavaScript. Released by Microsoft and designed by the father of C# Anders Hejlsberg. It is designed to ease building large scale applications using JavaScript, and addresses JavaScript shortfalls such as lacking a module system as well as type and compile-time type checking for better error detection and tooling.

SharePoint itself has become increasingly open over the recent versions with numerous new APIs available to client-side scripting, thus allowing more and more complex JavaScript applications. The time seems right that TypeScript will be a great addition to help us envision and attempt even more complex SharePoint solutions.

In this session, we want to tackle the two problems at hand: how do we set up our environment and get started with writing TypeScript with our solutions. And perhaps more importantly, what benefits do we get for choosing to go down this route with TypeScript.

 

A sneak preview

image

 

We'll build this Sandbox Webpart with TypeScript.  I'll see (some) of you this Saturday at Perth.

Ticket for SPSPER are very low, you'll need to register right away.

:-)

TypeScript and SharePoint - definition files

 

One of TypeScript's strengths is that you can use the ability to define Interfaces to produce Type Definition files for JavaScript.  These interface definitions provides an IDE (like Visual Studio) with a lot more type information at compile time regarding how to use a certain JavaScript object.

A large repository of definition files are at: https://github.com/borisyankov/DefinitelyTyped

Why is this related to SharePoint?  Well, javascript files provided in SharePoint are actually quite rich in meta data and could potentially be used to reverse engineer the TypeScript Definition Files. 

Without further delay...

  • Here's my TypeScript program
  • which will generate a JavaScript program
  • which will parse and read SP's JavaScript objects
  • which will produce TypeScript definition results

 

TypeScript code

 

module tools {

    export function findReturnType(o: any): string {

        // return;
        if (/return\s*;/gi.test(o)) return ": void";

        // no return
        if (!/return/gi.test(o)) return ": void";

        // return 1.1; return 1;
        if (/return\s*\d+(\.\d+)?;/gi.test(o)) return ": number";

        // return "xx";
        if (/return\s*"[^"]*?"\s*;/gi.test(o)) return ": string";

        // return 'xx';
        if (/return\s*'[^']*?'\s*;/gi.test(o)) return ": string";

        // return something;
        if (/return\s*[^;]+?;/gi.test(o)) return ": any";

        // don't know
        return ": any";
    }

    export function toClass(o: any): string {
        var isClass = o["__class"] == true;
        var typeName = o["__typeName"];

        var results = "interface " + typeName + "{\n";

        for (var member in o) {

            if (member.match(/\$|__/)) continue;

            var m = o[member];
            if (typeof (m) == "function") {
                var match = /function\s*(\(.*?\))/gi.exec(m);
                if (match) {
                    results += "function " + member + match[1] + findReturnType(m) + ";\n";
                }
            }
            else {
                results += "" + member + " : " + typeof (m) + ";\n";
            }
        }

        results += "}\n";

        return results;

    }

    export function toEnum(o: any): string {

        var typeName = o["__typeName"];
        var results = "interface " + typeName + "{\n";

        for (var member in o) {

            if (member.match(/\$|__/)) continue;

            var m = o[member];
            if (typeof (m) == "function") {
                continue;
            }
            else {
                results += "" + member + " : " + typeof (m) + ";\n";
            }
        }

        results += "}\n";
        return results;
    }

    export function toTypeScript(o: any): string {
        var isClass = o["__class"] == true;
        var isNamespace = o["__namespace"] == true;
        var isEnum = o["__enum"] == true;

        if (isClass) {
            return toClass(o);
        }
        if (isEnum) {
            return toEnum(o);
        }
        return "";
    }
}

 

What does this do?

 

When you run this code in the SharePoint browser console, you'd get this:

image

Which is nearly a usable TypeScript definition file. 

There are still a bunch of clean up to do, since this is a really basic list:

  • You will need to clean up the interface name. 
  • If you want, improve the arguments list, a number of the arguments are actually optional.
  • Remove zIndexStep and zIndexStart - which are properties in SP.UI.ModalDialog but aren't for public use.
  • Remove bind function - that's from jQuery

 

Here's another example, with enum's defined in SP.UI

image

 

Summary

In this quick blog article, I talked about using a TypeScript program to read the javascript object, and infer TypeScript definitions.  Since TypeScript contains far more information that isn't available in JavaScript, there will still be need to manually tweak the output.

Eventually, I hope we'll arrive at a place where we have fully documented TypeScript definitions for SharePoint available. 

Charlie Holland has started such a work, and it is available on https://github.com/chaholl/TypeScriptDefinitions/

http://www.chaholl.com/archive/2013/02/18/a-collection-of-typescript-definition-files-for-sharepoint-2013-et-al.aspx

Example uses of SPServices, JavaScript and SharePoint

 

I wanted to write about spservices.codeplex.com from Marc D Anderson - we've found ourselves using this really special library time and again across different projects to talk back to SharePoint quickly.

 

Starting Workflows

Here's a page from one of our Process Wiki articles.

image

 

  • We have a special "Contributor-only" webpart on the right. 
  • It shows the various workflow status' on the current page, as traffic light bubbles. 
  • The "Certify Process Page" calls a javascript function that calls StartWorkflow via SPServices.
  • The workflow is a Nintex workflow and triggers a significant multi-stage approval process.  But you can use StartWorkflow to start SharePoint workflows as well.

 

Getting List data, lots of list data

Here's our task list, represented as a taskboard.

image

  • This one is completely done with SPServices to get the list items
  • Convert the objects to JSON using SPServices.SPXmlToJson
  • Then binding the objects to UI via KnockoutJS
  • There's JQuery UI's drag and drop in play, so we can change the Task's status by dragging the task across a different column.
  • Update task using SPServices' UpdateItem call.
  • And some nice CSS. 
  • This particular page also runs via SharePoint 2010's OData listdata.svc, but is completely viable with SPServices on SP2007 as well.

 

Getting User Profiles via Search

Here's our People page.

image

 

  • First, get SharePoint to index your people.
  • Use SPServices to call SharePoint search to return a bunch of people, including their picture (one would say, especially their picture).
  • Here I use Knockout to render the pictures.  When clicked, each one opens that user's My Site page.
  • There's a filter box on the top right, as well as "fake" refinements on the left hand side that allows us to re-query SharePoint search for filtered people.
  • One possible idea here would be to use SPServices' User Profile Service support and talk directly to the User Profile service, if you want to skip the search service.

 

Summary

A quick post of 3 recent javascript customizations that heavily used SPServices.  Hope that give you guys a lot of ideas.  Let me know what you guys think.

InfoPath - Form stuck on Installing, Upgrading or Deleting

When you publish an InfoPath Form through Central Administration, a few things happen:

  1. Central Administration creates a WSP package for this form.
  2. Central Administration creates timer jobs to deploy the package to each of the web applications that uses this form (defined by Activate to Site Collection, in Central Administration)
  3. Administration Service on each server then runs the timer job to deploy the form.
  4. The deployment job actually does a bunch of things:
    1. Creates a list of upgrade templates in \14\TEMPLATE\FEATURES\FT-01-72d7f7bc-0c6e-ba52-fa91-bb24c0014ed6
      Note, for some sites, this list is incredibly long, and can take a long time. I can't think of any good reason why we need all the versions, but may be this can potentially affect form upgrades.
    2. Creates a content type for the form
    3. Copy the form template to %site collection%/Form Templates/template.xsn
    4. (do other stuff)

Review this article from Microsoft: http://blogs.msdn.com/b/infopath/archive/2006/10/23/behind-the-scenes-of-administrator-approved-form-templates.aspx 

So when a form is stuck on "Installing" or "Upgrading"

 

  1. Check timer jobs. If there are jobs that can't start - they will wait
    1. Check all administration service are running on both servers
    2. Check timer service is running (timer service calls administration service to deploy)
  2. If your administration service is OFF, then you can try using the command line to execute those timer jobs
    1. stsadm -o execadmsvcjobs
    2. The benefit is if there's exceptions thrown here you'd see it in the console
    3. Do this on all SharePoint servers. If the administration service is running, then this stsadm command won't do anything.
  3. If your job is missing, you can check in Solution Management /_admin/Solutions.aspx
    1. Go to Solution Management under Central Administration /_admin/Solutions.aspx
    2. Find the farm solutions that for the form. The name would be form-formname.wsp.
    3. If the solution isn't deployed, you can select deploy - global
    4. If your admin service isn't running, you'll get a warning saying that jobs are scheduled but no admin service means they won't run.
    5. Use stsadm -o execadmsvcjobs
  4. If nothing else works, or if we want to do a complete removal.
    1. In form templates, select the form template, and hit Remove.

Form is stuck on "Deleting"

  1. Go to Solution Management under Central Administration /_admin/Solutions.aspx
  2. Find the farm solutions that for the form. The name would be form-formname.wsp.
  3. If the status is Deployed, then retraction hasn't started.
  4. Click the package and select Retract Solution.
  5. If your admin service isn't running, you'll get a warning saying that job is scheduled but no admin service means they won't run.
  6. In command line, stsadm -o execadmsvcjobs, on both servers.
    C:\ > stsadm -o execadmsvcjobs
    Executing job-application-server-admin-service.
    Executing job-password-management.
    Executing solution-deployment-form-tradepackageform.wsp-0.
    Operation completed successfully.
  7. You'll see this back on solutions.
  8. Name:    form-packageform.wsp
    Type:    Core Solution
    Contains Web Application Resource:    No
    Contains Global Assembly:    No
    Contains Code Access Security Policy:    No
    Deployment Server Type:    Front-end Web server
    Deployment Status:    Deployed
    Deployed To:    Globally deployed.
    Last Operation Result:    The solution was successfully retracted.
    Last Operation Details:   
    SRV02 : The solution was successfully retracted.
    SRV03 : The solution was successfully retracted.
    Last Operation Time:    1/8/2013 11:01 AM

  9. You can then remove the solution package.
  10. If you go back to Form Template management, the form will be removed from the list, and you can re-upload as usual.