Category Archives: .net

8 Laws of Software Installation

2014-04-17_1958[1]

Clone this wiki locally

https://github.com/OneGet/oneget.wiki.git

 

Establishing an ecosystem that works together.

I started thinking about how all of this fits together and how we (as an ecosystem) need to be able to work together–and more importantly–still allow different systems to work how they please.

Many years ago, [url:Kim Cameron|http://www.identityblog.com/] came up with a list of [url:”7 Laws of Identity”|http://www.identityblog.com/?p=352/]. They outline some core fundamental principles that any Identity system should follow to ensure that everyone’s (users, identity providers, and relying parties) security is maximized.

It occurred to me, that concepts from the Laws could be recycled in a way that reflects how we can define the general parameters for an installation ecosystem:

1. USER CONTROL AND CONSENT

Users must always be able to make the ultimate decisions about their system, and installers must never do unauthorized actions without the user’s consent. Essentially, we really want to ensure that changes that the user doesn’t want aren’t being applied to their systems. This means that the that installers should always provide a clear and accurate description of the product being installed, and ensure that the user is in control of their systems. User interfaces or tools that obscure or break this trust with the user should be avoided. Ideally, user interfaces should strive for some amount of minimalism, not be serving up a collection of pedantic screens which users tediously press ‘next’ thru. Less UI means that users are far more likely to pay attention to what’s said.

  • Personal Opinion: I guess at the same time, I should point out a particular gripe of mine, especially with open source software installation on Windows. The proliferation of EULAs and Licenses masquerading as EULAs in the installation process should stop. Many OSS licenses don’t actually have any requirement upon the end-user to agree to the terms of them before installation, so please stop asking for people to ‘agree’ just to make it look like you have a ‘professional’ installer.

  • If you actually have a requirement to record an acceptance of license, perhaps you should be doing that upon first use (or whatever activity actually requires the acceptance of the license)

2. MINIMAL IMPACT FOR A CONSTRAINED USE

Changes to a system should aim to offer the least amount of disruption to the system. Installing unnecessary or unwanted components adds to bloat, and will increase the potential attack surface for malware.

  • Personal Opinion: There is a category of software out there that has opted to provide their software free, but heavily–and often with great vigilance–attempts to install toolbars, add-ins, or other pieces of trash software that serve only to funnel advertising to the user. Others nag the user to change their default search settings, or their browser home page for similar purposes. These behaviors are abusive to customers, and should be avoided at all costs.

3. PLURALISM OF OPERATORS AND TECHNOLOGIES

The ecosystem should easily support many different technologies, there is no one-size-fits-all answer. Software comes in all shapes and sizes. Any well-behaved individual packaging or installation technology should be welcome to participate. Choosing one technology over another should be left to the publisher. Pushing this to the logical ends means that any attempt to unify these should permit and encourage use of any part of the ecosystem.

4. TRANSPARENCY, ACCOUNTABILITY, AND REVERSABILITY

Installation technologies should never obfuscate what is being done, should never place the system in a state that can’t be undone. Again, keeping in mind that the target system belongs to the user, not the publisher, end users should be able to expect that un-installation should remove without issue or require any additional work to clean up.

  • Personal Opinion: On a slightly tangential note, I’d like to talk about rebooting the system. Windows Installers seem to be overly-eager to reboot the OS, either on installation or uninstallation. Now look–there is a very small class of software that can actually justify having to reboot the system. 99%+ of software should be able to deal with file conflicts, proper setup, manage their running processes or services, manipulating locked files, remove their temporary files, and all of those other things that you think you need to reboot the system in order to finish the work. If you need help on doing this, ask. You’ll be doing everyone a great service.

5. FLEXIBILITY OF INSTALLATION SCOPE

Ideally, a given package should be able to install into different installation scopes (OS/Global scope, Restricted/User scope, and Local/Sandboxed scope) and support installation into online and offline (VM Images) systems. Packaging systems should consider how they can help products to be fully installed in these scopes.

6. INSTALLATION IS NOT CONFIGURATION

Software installation on Windows has since time began, been conflating configuration with installation. This approach introduces several painful problems into the software installation process:

** This increases the amount of UI during installation, which only leads to additional confusion for the end user. ** Users may not know the answers to configuration questions, and are now blocked until they can find answers. ** Configuration during installation is nearly always significantly different than the process to configure (or ‘re-configure’) the product after installation. Again, confusing to the user. ** Migrating a working configuration to another system is harder when you have to answer during installation. Configuration should be easily portable between installations. ** Increases friction for end-users who are trying to automate the installation of software for large numbers of systems.

Really, don’t be that guy.

7. RESPECT THE RESOURCES OF THE TARGET SYSTEM

Software publishers need to respect the system to which their software is being installed. You don’t own that system, the end user does. Common scenarios that can be disrespectful

** Launching straight from the installer — Installation should not be considered good opportunity to launch your application. Similar to configuration issues, this is frustrating to end-users who are looking to automate the installations, and can introduce confusion for users who may not have expected that.

** Automatically starting software at system start — The proliferation of software that insists on starting up with the OS automatically is getting out of control. Software that wishes to launch at start-up should get explicit opt-in consent from the user (after the user has launched the application), not require the user to hunt down the option from a sea of configuration settings to disable it. Oh, and not providing a method to trivially disable auto-start is very bad.

** Checking for software updates — There are two acceptable methods for automatically checking for software updates. Preferred: checking from within the application itself (ie, at startup) and elegantly handling update and restart. Acceptable: Launching an update checker via a scheduled task, checking and then exiting. Wrong: Auto-starting a background or tray-application to constantly check for updates.

  • Personal Opinion: This last one is particularly frustrating. Since Windows doesn’t currently have a built-in 3rd party update service (like Windows Update) that will on a schedule check for updates, download and install them, many companies have resorted to running bloated, wasteful apps in the background, waiting for updates. This is terribly disrespectful to the end user’s system, and offers absolutely nothing of value to the user that a scheduled task wouldn’t accomplish with less effort.

8. CONSISTENT EXPERIENCE ACROSS CONTEXTS

Finally, regardless of underlying technology, there should be a common set of commands, tools and processes that allows users to install whatever software in the way that they’d like. Currently, we see that individual installation technologies are all headed in different directions, which makes automating the installation of some pieces of software a nightmare. We as a community need to have the ability to bring all of these pieces of software together without having to manually script each individual combination.

Advertisements

How To : Use the REST API and AngularJS to Create a Web Part to retrieve List Items

Introduction

This article explains how to get the data from a SharePoint List using Angular JavaScript and the REST API. I used the REST API to talk to SharePoint and get the data from the list.

In this script we just see that we have first created an Angular Controller with the name “spCustomerController”. We have also injected $scope and $http service.

The $http service will fetch the list data from the specific columns of the SharePoint list. $scope is a glue between a Controller and a View. It acts as execution context for Expressions. Angular expressions are code snippets that are usually placed in bindings such as {{ expression }}.

Angular Controller.jpg

Use the following procedure to create a sample.

  1. <h1>WelCome To Angular JS Sharepoint 2013 REST API !!</h1>  
  2.   
  3. <div ng-app=“SharePointAngApp” class=“row”>  
  4.     <div ng-controller=“spCustomerController” class=“span10”>  
  5.         <table class=“table table-condensed table-hover”>  
  6.             <tr>  
  7.                 <th>Title</th>  
  8.                 <th>Employee</th>  
  9.                 <th>Company</th>  
  10.                  
  11.             </tr>  
  12.             <tr ng-repeat=“customer in customers”>  
  13.                 <td>{{customer.Title}}</td>  
  14.                 <td>{{customer.Employee}}</td>  
  15.                 <td>{{customer.Company}}</td>  
  16.                 </tr>  
  17.         </table>  
  18.     </div>  
  19. </div>  

 

Step 1: Navigate to your SharePoint 2013 site.

Step 2: From this page select the Site Actions | Edit Page.

Edit the page, go to the “Insert” tab in the Ribbon and click the “Web Part” option. In the “Web Parts” picker area, go to the “Media and Content” category, select the “Script Editor” Web Part and press the “Add button”.

Step 3: Once the Web Part is inserted into the page, you will see an “EDIT SNIPPET” link; click it. You can insert the HTML and/or JavaScript as in the following

  1. <style>  
  2. table, td, th {  
  3.     border: 1px solid green;  
  4. }  
  5.   
  6. th {  
  7.     background-color: green;  
  8.     color: white;  
  9. }  
  10. </style>  
  11. <script src=https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js&#8221;></script>  
  12. <script src=http://code.jquery.com/ui/1.10.3/jquery-ui.min.js&#8221;></script>  
  13.   
  14. <script>  
  15.       
  16.   
  17.     var myAngApp = angular.module(‘SharePointAngApp’, []);  
  18.     myAngApp.controller(‘spCustomerController’, function ($scope, $http) {  
  19.         $http({  
  20.             method: ‘GET’,  
  21.             url: _spPageContextInfo.webAbsoluteUrl + “/_api/web/lists/getByTitle(‘InfoList’)/items?$select=Title,Employee,Company”,  
  22.             headers: { “Accept”: “application/json;odata=verbose” }  
  23.         }).success(function (data, status, headers, config) {  
  24.             $scope.customers = data.d.results;  
  25.         }).error(function (data, status, headers, config) {  
  26.          
  27.         });  
  28.     });  
  29.       
  30. </script>  
  31.   
  32. <h1> Angular JS SharePoint 2013 REST API !!</h1>  
  33.   
  34. <div ng-app=“SharePointAngApp” class=“row”>  
  35.     <div ng-controller=“spCustomerController” class=“span10”>  
  36.         <table class=“table table-condensed table-hover”>  
  37.             <tr>  
  38.                 <th>Title</th>  
  39.                 <th>Employee</th>  
  40.                 <th>Company</th>  
  41.                  
  42.             </tr>  
  43.             <tr ng-repeat=“customer in customers”>  
  44.                 <td>{{customer.Title}}</td>  
  45.                 <td>{{customer.Employee}}</td>  
  46.                 <td>{{customer.Company}}</td>  
  47.                 </tr>  
  48.         </table>  
  49.     </div>  
  50. </div>  

 

Finally the result show look as below:

 

Finally result show.jpg

How To : Use JavaScript: Error Handling to Build More Efficient Windows Store Apps

winjs_life_02[1]

Believe it or not, sometimes app developers write code that doesn’t work. Or the code works but is terribly inefficient and hogs memory. Worse yet, inefficient code results in a poor UX, driving users crazy and compelling them to uninstall the app and leave bad reviews.

I’m going to explore common performance and efficiency problems you might encounter while building Windows Store apps with JavaScript. In this article, I take a look at best practices for error handling using the Windows Library for JavaScript (WinJS). In a future article, I’ll discuss techniques for doing work without blocking the UI thread, specifically using Web Workers or the new WinJS.Utilities.Scheduler API in WinJS 2.0, as found in Windows 8.1. I’ll also present the new predictable-object lifecycle model in WinJS 2.0, focusing particularly on when and how to dispose of controls.

For each subject area, I focus on three things:

  • Errors or inefficiencies that might arise in a Windows Store app built using JavaScript.
  • Diagnostic tools for finding those errors and inefficiencies.
  • WinJS APIs, features and best practices that can ameliorate specific problems.

I provide some purposefully buggy code but, rest assured, I indicate in the code that something is or isn’t supposed to work.

I use Visual Studio 2013, Windows 8.1 and WinJS 2.0 for these demonstrations. Many of the diagnostic tools I use are provided in Visual Studio 2013. If you haven’t downloaded the most-recent versions of the tools, you can get them from the Windows Dev Center (bit.ly/K8nkk1). New diagnostic tools are released through Visual Studio updates, so be sure to check for updates periodically.

I assume significant familiarity with building Windows Store apps using JavaScript. If you’re relatively new to the platform, I suggest beginning with the basic “Hello World” example (bit.ly/vVbVHC) or, for more of a challenge, the Hilo sample for JavaScript (bit.ly/SgI0AA).

Setting up the Example

First, I create a new project in Visual Studio 2013 using the Navigation App template, which provides a good starting point for a basic multipage app. I also add a NavBar control (bit.ly/14vfvih) to the default.html page at the root of the solution, replacing the AppBar code the template provided. Because I want to demonstrate multiple concepts, diagnostic tools and programming techniques, I’ll add a new page to the app for each demonstration. This makes it much easier for me to navigate between all the test cases.

The complete HTML markup for the NavBar is shown in Figure 1. Copy and paste this code into your solution if you’re following along with the example.

Figure 1 The NavBar Control

<!-- The global navigation bar for the app. -->
<div id="navBar" data-win-control="WinJS.UI.NavBar">
  <div id="navContainer" 
       data-win-control="WinJS.UI.NavBarContainer">
    <div id="homeNav" 
      data-win-control="WinJS.UI.NavBarCommand"
      data-win-options="{
        location: '/pages/home/home.html',
        icon: 'home',
        label: 'Home page'
    }">
    </div>
    <div id="handlingErrors"
      data-win-control="WinJS.UI.NavBarCommand"
      data-win-options="{
        location: '/pages/handlingErrors/handlingErrors.html',
        icon: 'help',
        label: 'Handling errors'
    }">
    </div>
    <div id="chainedAsync"
      data-win-control="WinJS.UI.NavBarCommand"
      data-win-options="{
        location: '/pages/chainedAsync/chainedAsync.html',
        icon: 'link',
        label: 'Chained asynchronous calls'
    }">
    </div>
  </div>
</div>

For more information about building a navigation bar, check out some of the Modern Apps columns by Rachel Appel, such as the one at msdn.microsoft.com/magazine/dn342878.

You can run this project with just the navigation bar, except that clicking any of the navigation buttons will raise an exception in navigator.js. Later in this article, I’ll discuss how to handle errors that come up in navigator.js. For now, remember the app always starts on the home­page and you need to right-click the app to bring up the navigation bar.

Handling Errors

Obviously, the best way to avoid errors is to release apps that don’t raise errors. In a perfect world, every developer would write perfect code that never crashes and never raises an exception. That perfect world doesn’t exist.

As much as users prefer apps that are completely error-free, they are exceptionally good at finding new and creative ways to break apps—ways you never dreamed of. As a result, you need to incorporate robust error handling into your apps.

Errors in Windows Store apps built with JavaScript and HTML act just like errors in normal Web pages. When an error happens in a Document Object Model (DOM) object that allows for error handling (for example, the <script>, <style> or <img> elements), the onerror event for that element is raised. For errors in the JavaScript call stack, the error travels up the chain of calls until caught (in a try/catch block, for instance) or until it reaches the window object, raising the window.onerror event.

WinJS provides several layers of error-handling opportunities for your code in addition to what’s already provided to normal Web pages by the Microsoft Web Platform. At a fundamental level, any error not trapped in a try/catch block or the onError handler applied to a WinJS.Promise object (in a call to the then or done methods, for example) raises the WinJS.Application.onerror event. I’ll examine that shortly.

In practice, you can listen for errors at other levels in addition to Application.onerror. With WinJS and the templates provided by Visual Studio, you can also handle errors at the page-control level and at the navigation level. When an error is raised while the app is navigating to and loading a page, the error triggers the navigation-level error handling, then the page-level error handling, and finally the application-level error handling. You can cancel the error at the navigation level, but any event handlers applied to the page error handler will still be raised.

In this article, I’ll take a look at each layer of error handling, starting with the most important: the Application.onerror event.

Application-Level Error Handling

WinJS provides the WinJS.Application.onerror event (bit.ly/1cOctjC), your app’s most basic line of defense against errors. It picks up all errors caught by window.onerror.” It also catches promises that error out and any errors that occur in the process of managing app model events. Although you can apply an event handler to the window.onerror event in your app, you’re better off just using Application.onerror for a single queue of events to monitor.

Once the Application.onerror handler catches an error, you need to decide how to address it. There are several options:

  • For critical blocking errors, alert the user with a message dialog. A critical error is one that affects continued operation of the app and might require user input to proceed.
  • For informational and non-blocking errors (such as a failure to sync or obtain online data), alert the user with a flyout or an inline message.
  • For errors that don’t affect the UX, silently swallow the error.
  • In most cases, write the error to a tracelog (especially one that’s hooked up to an analytics engine) so you can acquire customer telemetry. For available analytics SDKs, visit the Windows services directory at services.windowsstore.com and click on Analytics (under “By service type”) in the list on the left.

For this example, I’ll stick with message dialogs. I open up default.js (/js/default.js) and add the code shown in Figure 2 inside the main anonymous function, below the handler for the app.oncheckpoint event.

Figure 2 Adding a Message Dialog

app.onerror = function (err) {
  var message = err.detail.errorMessage ||
    (err.detail.exception && err.detail.exception.message) ||
    "Indeterminate error";
  if (Windows.UI.Popups.MessageDialog) {
    var messageDialog =
      new Windows.UI.Popups.MessageDialog(
        message,
        "Something bad happened ...");
    messageDialog.showAsync();
    return true;
  }
}

In this example, the error event handler shows a message telling the user an error has occurred and what the error is. The event handler returns true to keep the message dialog open until the user dismisses it. (Returning true also informs the WWAHost.exe process that the error has been handled and it can continue.)

hero-for-hire_basic-layout_600Senior C# & SharePoint Developer with 10 year’s development experience

BSC degree in Computer Science and Information Systems

5 years experience in delivering SharePoint based solutions using OOB functionality and Custom Development

Extensive experience in
• Microsoft SharePoint platform, App Model (2010 & 2013)
• C# 2.0 – 4.5
• Advanced Workflow (Visual Studio, K2, Nintex)
• Development of Custom Web Parts
• Master Page Dev & Branding
• Integration of Back-end systems, including 3 SAP Projects, MS CRM, K2 BlackPearl,
Custom LOB Systems
• SQL Server (design,development, stored procedures, triggers)
• BCS, BDC – Implementing WCF, REST Services, Web Services
• SharePoint Excel Services, PowerPivot, Word Automation Services
• Custom Reports (MS SQL Reporting, Crystal Reports)
• Objected Oriented Programming and Patterns
• TFS 2010-2013
• Agile & SCRUM methodologies (ALM / SDLC)
• Microsoft Azure as database and hosting hybrid solutions
• Office 365 and SharePoint App Development

 

Now I’ll create some errors for this code to handle. I’ll create a custom error, throw the error and then catch it in the event handler. For this first example, I add a new folder named handling­Errors to the pages folder. In the folder, I add a new Page Control by right-clicking the project in Solution Explorer and selecting Add | New Item. When I add the handlingErrors Page Control to my project, Visual Studio provides three files in the handlingErrors folder (/pages/handlingErrors): handlingErrors.html, handling­Errors.js and handlingErrors.css.

I open up handlingErrors.html and add this simple markup inside the <section> tag of the body:

<!-- When clicked, this button raises a custom error. -->
<button id="throwError">Throw an error!</button>

Next, I open handlingErrors.js and add an event handler to the button in the ready method of the PageControl object, as shown in Figure 3. I’ve provided the entire PageControl definition in handlingErrors.js for context.

Figure 3 Definition of the handlingErrors PageControl

// For an introduction to the Page Control template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232511
(function () {
  "use strict";
  WinJS.UI.Pages.define("/pages/handlingErrors/handlingErrors.html", {
    ready: function (element, options) {
      // ERROR: This code raises a custom error.
      throwError.addEventListener("click", function () {
        var newError = new WinJS.ErrorFromName("Custom error", 
          "I'm an error!");
        throw newError;
      });
    },
    unload: function () {
      // Respond to navigations away from this page.
      },
    updateLayout: function (element) {
      // Respond to changes in layout.
    }
  });
})();

Now I press F5 to run the sample, navigate to the handling­Errors page and click the “Throw an error!” button. (If you’re following along, you’ll see a dialog box from Visual Studio informing you an error has been raised. Click Continue to keep the sample running.) A message dialog then pops up with the error, as shown in Figure 4.

The Custom Error Displayed in a Message Dialog
Figure 4 The Custom Error Displayed in a Message Dialog

Custom Errors

The Application.onerror event has some expectations about the errors it handles. The best way to create a custom error is to use the WinJS.ErrorFromName object (bit.ly/1gDESJC). The object created exposes a standard interface for error handlers to parse.

To create your own custom error without using the ErrorFromName object, you need to implement a toString method that returns the message of the error.

Otherwise, when your custom error is raised, both the Visual Studio debugger and the message dialog show “[Object object].” They each call the toString method for the object, but because no such method is defined in the immediate object, it goes through the chain of prototype inheritance for a definition of toString. When it reaches the Object primitive type that does have a toString method, it calls that method (which just displays information about the object).

Page-Level Error Handling

The PageControl object in WinJS provides another layer of error handling for an app. WinJS will call the IPageControlMembers.error method when an error occurs while loading the page. After the page has loaded, however, the IPageControlMembers.error method errors are picked up by the Application.onerror event handler, ignoring the page’s error method.

I’ll add an error method to the PageControl that represents the handleErrors page. The error method writes to the JavaScript console in Visual Studio using WinJS.log. The logging functionality needs to be started up first, so I need to call WinJS.Utilities.startLog before I attempt to use that method. Also note that I check for the existence of the WinJS.log member before I actually call it.

The complete code for handleErrors.js (/pages/handleErrors/handleErrors.js) is shown in Figure 5.

Figure 5 The Complete handleErrors.js

(function () {
  "use strict";
  WinJS.UI.Pages.define("/pages/handlingErrors/handlingErrors.html", {
    ready: function (element, options) {
      // ERROR: This code raises a custom error.      
      throwError.addEventListener("click", function () {
        var newError = {
          message: "I'm an error!",
          toString: function () {
            return this.message;
          }
        };
        throw newError;
      })
    },
    error: function (err) {
      WinJS.Utilities.startLog({ type: "pageError", tags: "Page" });
      WinJS.log && WinJS.log(err.message, "Page", "pageError");
    },
    unload: function () {
      // TODO: Respond to navigations away from this page.
    },
    updateLayout: function (element) {
      // TODO: Respond to changes in layout.
    }
  });
})();

WinJS.log

The call to WinJS.Utilities.startLog shown in Figure 5 starts the WinJS.log helper function, which writes output to the JavaScript console by default. While this helps greatly during design time for debugging, it doesn’t allow you to capture error data after users have installed the app.

For apps that are ready to be published and deployed, you should consider creating your own implementation of WinJS.log that calls into an analytics engine. This allows you to collect telemetry data about your app’s performance so you can fix unforeseen bugs in future versions of your app. Just make sure customers are aware of the data collection and that you clearly list what data gets collected by the analytics engine in your app’s privacy statement.

Note that when you overwrite WinJS.log in this way, the WinJS.log function will catch all output that would otherwise go to the JavaScript console, including things like status updates from the Scheduler. This is why you need to pass a meaningful name and type value into the call to WinJS.Utilities.startLog so you can filter out any errors you don’t want.

Now I’ll try running the sample and clicking “Throw an error!” again. This results in the exact same behavior as before: Visual Studio picks up the error and then the Application.onerror event fires. The JavaScript console doesn’t show any messages related to the error because the error was raised after the page loaded. Thus, the error was picked up only by the Application.onerror event handler.

So why use the PageControl error handling? Well, it’s particularly helpful for catching and diagnosing errors in WinJS controls that are created declaratively in the HTML. For example, I’ll add the following HTML markup inside the <section> tags of handleErrors.html (/pages/handleErrors/handleErrors.html), below the button:

<!-- ERROR: AppBarCommands must be button elements by default
  unless specified otherwise by the 'type' property. -->
<div data-win-control="WinJS.UI.AppBarCommand"></div>

Now I press F5 to run the sample and navigate to the handleErrors page. Again, the message dialog appears until dismissed. However, the following message appears in the JavaScript console (you’ll need to switch back to the desktop to check this):

pageError: Page: Invalid argument: For a button, toggle, or flyout   command, the element must be null or a button element

Note that the app-level error handling appeared even though I handled the error in the PageControl (which logged the error). So how can I trap an error on a page without having it bubble up to the application?

The best way to trap a page-level error is to add error handling to the navigation code. I’ll demonstrate that next.

Navigation-Level Error Handling

When I ran the previous test where the app.on­error event handler handled the page-level error, the app seemed to stay on the homepage. Yet, for some reason, a Back button control appeared. When I clicked the Back button, it took me to a (disabled) handlingErrors.html page.

This is because the navigation code in navigator.js (/js/navigator.js), which is provided in the Navigation App project template, still attempts to navigate to the page even though the page has fizzled. Furthermore, it navigates back to the homepage and adds the error-prone page to the navigation history. That’s why I see the Back button on the homepage after I’ve attempted to navigate to handlingErrors.html.

To cancel the error in navigator.js, I replace the PageControl­Navigator._navigating function with the code in Figure 6. You see that the navigating function contains a call to WinJS.UI.Pages.render, which returns a Promise object. The render method attempts to create a new PageControl from the URI passed to it and insert it into a host element. Because the resulting PageControl contains an error, the returned promise errors out. To trap the error raised during navigation, I add an error handler to the onError parameter of the then method exposed by that Promise object. This effectively traps the error, preventing it from raising the Application.onerror event.

Figure 6 The PageControlNavigator._navigating Function in navigator.js

// Other PageControlNavigator code ...
// Responds to navigation by adding new pages to the DOM.
_navigating: function (args) {
  var newElement = this._createPageElement();
  this._element.appendChild(newElement);
  this._lastNavigationPromise.cancel();
  var that = this;
  this._lastNavigationPromise = WinJS.Promise.as().then(function () {
    return WinJS.UI.Pages.render(args.detail.location, newElement,
       args.detail.state);
  }).then(function parentElement(control) {
    var oldElement = that.pageElement;
    // Cleanup and remove previous element
    if (oldElement.winControl) {
      if (oldElement.winControl.unload) {
        oldElement.winControl.unload();
      }
      oldElement.winControl.dispose();
    }
    oldElement.parentNode.removeChild(oldElement);
    oldElement.innerText = "";
  },
  // Display any errors raised by a page control,
  // clear the backstack, and cancel the error.
  function (err) {
    var messageDialog =
      new Windows.UI.Popups.MessageDialog(
        err.message,
        "Sorry, can't navigate to that page.");
    messageDialog.showAsync()
    nav.history.backStack.pop();
    return true;
  });
  args.detail.setPromise(this._lastNavigationPromise);
},
// Other PageControlNavigator code ...

Promises in WinJS

Creating promises and chaining promises—and the best practices for doing so—have been covered in many other places, so I’ll skip that discussion in this article. If you need more information, check out the blog post by Kraig Brockschmidt at bit.ly/1cgMAnu or Appendix A in his free e-book, “Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition” (bit.ly/1dZwW1k).

Note that it’s entirely proper to modify navigator.js. Although it’s provided by the Visual Studio project template, it’s part of your app’s code and can be modified however you need.

In the _navigating function, I’ve added an error handler to the final promise.then call. The error handler shows a message dialog—as with the application-level error handling—and then cancels the error by returning true. It also removes the page from the navigation history.

When I run the sample again and navigate to handlingErrors.html, I see the message dialog that informs me the navigation attempt has failed. The message dialog from the application-level error handling doesn’t appear.

Tracking Down Errors in Asynchronous Chains

When building apps in JavaScript, I frequently need to follow one asynchronous task with another, which I address by creating promise chains. Chained promises will continue moving along through the tasks, even if one of the promises in the chain returns an error. A best practice is to always end a chain of promises with a call to the done method. The done function throws any errors that would’ve been caught in the error handler for any previous then statements. This means I don’t need to define error functions for each promise in a chain.

Even so, tracking errors down can be difficult in very long chains once they’re trapped in the call to promise.done. Chained promises can include multiple tasks, and any one of them could fail. I could set a breakpoint in every task to see where the error pops up, but that would be terribly time-consuming.

Here’s where Visual Studio 2013 comes to the rescue. The Tasks window (introduced in Visual Studio 2010) has been upgraded to handle asynchronous JavaScript debugging as well. In the Tasks window you can view all active and completed tasks at any given point in your app code.

For this next example, I’ll add a new page to the solution to demonstrate this awesome tool. In the solution, I create a new folder called chainedAsync in the pages folder and then add a new Page Control named chainAsync.html (which creates /pages/­chainedAsync/chainedAsync.html and associated .js and .css files).

In chainedAsync.html, I insert the following markup within the <section> tags:

<!-- ERROR:Clicking this button starts a chain reaction with an error. -->
<p><button id="startChain">Start the error chain</button></p>
<p id="output"></p>

In chainedAsync.js, I add the event handler shown in Figure 7for the click event of the startChain button to the ready method for the page.

Figure 7 The Contents of the PageControl.ready Function in chainedAsync.js

startChain.addEventListener("click", function () {
  goodPromise().
    then(function () {
        return goodPromise();
    }).
    then(function () {
        return badPromise();
    }).
    then(function () {
        return goodPromise();
    }).
    done(function () {
        // This *shouldn't* get called
    },
      function (err) {
          document.getElementById('output').innerText = err.toString();
    });
});

Last, I define the functions goodPromise and badPromise, shown in Figure 8, within chainAsync.js so they’re available inside the PageControl’s methods.

Figure 8 The Definitions of the goodPromise and badPromise Functions in chainAsync.js

function goodPromise() {
  return new WinJS.Promise(function (comp, err, prog) {
    try {
      comp();
    } catch (ex) {
      err(ex)
    }
  });
}
// ERROR: This returns an errored-out promise.
function badPromise() {
  return WinJS.Promise.wrapError("I broke my promise :(");
}

I run the sample again, navigate to the “Chained asynchronous” page, and then click “Start the error chain.” After a short wait, the message “I broke my promise :(” appears below the button.

Now I need to track down where that error occurred and figure out how to fix it. (Obviously, in a contrived situation like this, I know exactly where the error occurred. For learning purposes, I’ll forget that badPromise injected the error into my chained promises.)

To figure out where the chained promises go awry, I’m going to place a breakpoint on the error handler defined in the call to done in the click handler for the startChain button, as shown in Figure 9.

The Position of the Breakpoint in chainedAsync.html
Figure 9 The Position of the Breakpoint in chainedAsync.html

I run the same test again, and when I return to Visual Studio, the program execution has stopped on the breakpoint. Next, I open the Tasks window (Debug | Windows | Tasks) to see what tasks are currently active. The results are shown in Figure 10.

The Tasks Window in Visual Studio 2013 Showing the Error
Figure 10 The Tasks Window in Visual Studio 2013 Showing the Error

At first, nothing in this window really stands out as having caused the error. The window lists five tasks, all of which are marked as active. As I take a closer look, however, I see that one of the active tasks is the Scheduler queuing up promise errors—and that looks promising (please excuse the bad pun).

(If you’re wondering about the Scheduler, I encourage you to read the next article in this series, where I’ll discuss the new Scheduler API in WinJS.)

When I hover my mouse over that row (ID 120 in Figure 10) in the Tasks window, I get a targeted view of the call stack for that task. I see several error handlers and, lo and behold, badPromise is near the beginning of that call stack. When I double-click that row, Visual Studio takes me right to the line of code in badPromise that raised the error. In a real-world scenario, I’d now diagnose why badPromise was raising an error.

WinJS provides several levels of error handling in an app, above and beyond the reliable try-catch-finally block. A well-performing app should use an appropriate degree of error handling to provide a smooth experience for users. In this article, I demonstrated how to incorporate app-level, page-level and navigation-level error handling into an app. I also demonstrated how to use some of the new tools in Visual Studio 2013 to track down errors in chained promises.

How to: Modify a Project System So That Projects Load in Multiple Versions of Visual Studio

avatar[2]

In Visual Studio 2013, you can prevent a project that was created in your custom project system from loading in an earlier version of Visual Studio.

You can also enable that project to identify itself to a later version in case the project requires repair, conversion, or deprecation.

You can mark a project as incompatible with earlier versions of Visual Studio. For example, suppose you create in Visual Studio 2013 a project that uses a .NET Framework 4.5 feature.
Because this project can’t be built in Visual Studio 2010 with SP1, you can mark it as incompatible with Visual Studio 2010 with SP1 to prevent that version from trying to load it.

 

The component that adds the incompatible feature is responsible for marking the project as incompatible. The component must have access to the IVsHierarchy interface that represents the projects of interest.

Marking a Project as Incompatible


You can mark a project as incompatible with earlier versions of Visual Studio. For example, suppose you create in Visual Studio 2013 a project that uses a .NET Framework 4.5 feature. Because this project can’t be built in Visual Studio 2010 with SP1, you can mark it as incompatible with Visual Studio 2010 with SP1 to prevent that version from trying to load it.

 

The component that adds the incompatible feature is responsible for marking the project as incompatible. The component must have access to the IVsHierarchy interface that represents the projects of interest.

To mark a project as incompatible

  1. In the component, get an IVsAppCompat interface from the global service SVsSolution.

    For more information, see SVsSolution.

  2. In the component, call IVsAppCompat.AskForUserConsentToBreakAssetCompat, and pass it an array of IVsHierarchy interfaces that represent the projects of interest.

    This method has the following signature:

    HRESULT AskForUserConsentToBreakAssetCompat([in] SAFEARRAY(IVsHierarchy*) sarrProjectHierarchies) 
    

    If you implement this code, a project compatibility dialog box will appear. The dialog box will asks the user for permission to mark all specified projects as incompatible. If the user agrees, AskForUserConsentToBreakAssetCompat returns S_OK; otherwise, AskForUserConsentToBreakAssetCompat returns OLE_E_PROMPTSAVECANCELLED.

    Caution noteaution
    In most common scenarios, the IVsHierarchy array will contain only one item.

     

  3. If AskForUserConsentToBreakAssetCompat returns S_OK, the component makes or accepts the changes that break compatibility.
  4. In your component, call the IVsAppCompat.BreakAssetCompatibility method for each project that you want to mark as incompatible. The component can set the value of the parameter lpszMinimumVersion to a specific minimum version instead of having Visual Studio look up the current version string in the registry.

    This approach minimizes the risk of the component inadvertently setting a higher value in the future, based on what is in the registry at that time. If that higher value were set, Visual Studio 2013 couldn’t open such a project.

    This method has the following signature:

    HRESULT BreakAssetCompatibility([in] IVsHierarchy * pProjHier), [in] LPCOLESTR lpszMinimumVersion); 
    

    If the component sets lpszMinimumVersion to NULL, the BreakAssetCompatibility method calls the IVsAppCompat.GetCurrentDesignTimeCompatVersion method to obtain a string that represents the current version of Visual Studio.

     

     

     

  5. This method has the following signature:
    RESULT GetCurrentDesignTimeCompatVersion([out] BSTR * pbstrCurrentDesignTimeCompatVersion)
    

     

     

  6. The BreakAssetCompatibility method then calls the IVsHierarchy.SetProperty method to set the root VSHPROPID_MinimumDesignTimeCompatVersion property to the value of the version string that you obtained in the previous step.

 

 Important
You must implement the VSHPROPID_MinimumDesignTimeCompatVersion property to mark a project as compatible or incompatible. For example, if the project system uses an MSBuild project file, add to the project file a <MinimumVisualStudioVersion> build property that has a value equal to the corresponding VSHPROPID_MinimumDesignTimeCompatVersion property value.
A project that is incompatible with the current version of Visual Studio must be kept from loading. Furthermore, a project that is incompatible can’t be upgraded or repaired. Therefore, a project must be checked for compatibility twice: first, when it is being considered for upgrade or repair, and second, before it is loaded.

To enable the detection of project incompatibility, you must implement the UpgradeProject_CheckOnly and CreateProject methods. If a project is incompatible, UpgradeProject_CheckOnly must return the success code VS_S_INCOMPATIBLEPROJECT, and CreateProject must return the error code VS_E_INCOMPATIBLEPROJECT. For flavored projects, you must implement IVsProjectFlavorUpgradeViaFactory2.UpgradeProjectFlavor_CheckOnly instead of IVsProjectUpgradeViaFactory4.UpgradeProject_CheckOnly.

A project system is referred to as flavored if it has a web, Office (VSTO), Silverlight, or other project type built on top of it. Older project systems that already implement IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly and flavored project systems that already implement IVsProjectFlavorUpgradeViaFactory.UpgradeProjectFlavor_CheckOnly continue to be supported. The older version of IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly has the following implementation signature:

Copy
IVsProjectUpgradeViaFactory::UpgradeProject_CheckOnly(

/* [in] */ BSTR bstrFileName,
/* [in] */ IVsUpgradeLogger *pLogger,
/* [out] */ BOOL *pUpgradeRequired,
/* [out] */ GUID *pguidNewProjectFactory,
/* [out] */ VSPUVF_FLAGS *pUpgradeProjectCapabilityFlags
)

If this method sets pUpgradeRequired to TRUE and returns S_OK, the result is treated as “Upgrade” and as though the method set an upgrade flag to the value VSPUVF_PROJECT_ONEWAYUPGRADE, which is described later in this topic. The following return values are supported by using this older method but only when pUpgradeRequired is set to TRUE:

  1. VS_S_PROJECT_SAFEREPAIRREQUIRED. This return value translates the pUpgradeRequired value to TRUE as equivalent to VSPUVF_PROJECT_SAFEREPAIR, which is described later in this topic.
  2. VS_S_PROJECT_UNSAFEREPAIRREQUIRED. This return value translates the pUpgradeRequired value to TRUE as equivalent to VSPUVF_PROJECT_UNSAFEREPAIR, which is described later in this topic
  3. VS_S_PROJECT_ONEWAYUPGRADEREQUIRED. This return value translates the pUpgradeRequired value to TRUE as equivalent to VSPUVF_PROJECT_ONEWAYUPGRADE, which is described later in this topic.

The new implementations in IVsProjectUpgradeViaFactory4 and IVsProjectFlavorUpgradeViaFactory2 enable specifying the migration type more precisely.

NoteNote
You can cache the result of the compatibility check by the UpgradeProject_CheckOnly method so that it can also be used by the subsequent call to CreateProject.

For example, if the UpgradeProject_CheckOnly and CreateProject methods that are written for a Visual Studio 2010 with SP1 project system examine a project file and find that the <MinimumVisualStudioVersion> build property is “11.0”, Visual Studio 2010 with SP1 won’t load the project. In addition, Solution Navigator would indicate that the project is “incompatible” and won’t load it.

By using Visual Studio 2013, you can modify most projects that were created in Visual Studio 2010 with SP1 to work in both that version and Visual Studio 2013.

Before a project is loaded, Visual Studio calls the UpgradeProject_CheckOnly method to determine whether the project can be upgraded. If the project can be upgraded, the UpgradeProject_CheckOnly method sets a flag that causes a later call to the UpgradeProject method to upgrade the project. Because incompatible projects can’t be upgraded, UpgradeProject_CheckOnly must first check for project compatibility, as described in the earlier section.

You, as the author of a project system, implement UpgradeProject_CheckOnly (from the IVsProjectUpgradeViaFactory4 interface) to provide users of your project system with an upgrade check.

Visual-Studio-2010-Add-New-Project[1] visual-studio-11-output-directory[1]

When users open a project, this method is called to determine whether a project must be repaired before it is loaded. The possible upgrade requirements are enumerated in VSPUVF_REPAIRFLAGS, and they include the following possibilities:

  1. SPUVF_PROJECT_NOREPAIR: Requires no repair.
  2. VSPUVF_PROJECT_SAFEREPAIR: Makes the project compatible with Visual Studio 2010 with SP1 without the issues that you might have encounter with the previous versions of the product.
  3. VSPUVF_PROJECT_UNSAFEREPAIR: Makes the project compatible with Visual Studio 2010 with SP1 but with some risk of the issues that you might have encountered with previous versions of the product. For example, the project won’t be compatible if it depended on different SDK versions between Visual Studio 2013 and Visual Studio 2010 with SP1.
  4. VSPUVF_PROJECT_ONEWAYUPGRADE: Makes the project incompatible with Visual Studio 2010 with SP1.
  5. VSPUVF_PROJECT_INCOMPATIBLE: Indicates that Visual Studio 2013 doesn’t support this project.
  6. VSPUVF_PROJECT_DEPRECATED: Indicates that this project is no longer supported.
Note Note
To avoid confusion, don’t combine upgrade flags when you set them. For example, don’t create an ambiguous upgrade status such as VSPUVF_PROJECT_SAFEREPAIR | VSPUVF_PROJECT_DEPRECATED.

 

 

Project flavors may implement the function UpgradeProjectFlavor_CheckOnly from the IVsProjectFlavorUpgradeViaFactory2 interface.

To make this function work, the IVsProjectUpgradeViaFactory4.UpgradeProject_CheckOnly implementation mentioned earlier must call it.

 

This call is already implemented in the Visual Basic or C# base project system. The effect of this function enables project flavors to also determine the upgrade requirements of a project, in addition to what the base project system has determined. The compatibility dialog box shows the most severe of the two requirements.

When Visual Studio performs an upgrade check, it provides a logger instead of a NULL value as in previous versions of Visual Studio. The logger enables project systems and flavors to provide additional information that can help you understand the nature of the changes that are needed to make your older projects load properly.

For Managed implementations, the project upgrade interfaces are available in the Microsoft.VisualStudio.Shell.Interop.11.0.dll interop assembly.

The UpgradeProject method can determine whether the changes it makes would prevent the project from loading in an previous version of Visual Studio. If so, the method marks the project as incompatible.

To understand how a project is marked as incompatible, see Marking a Project as Incompatible earlier in this topic. We recommend that, after this dialog box appears, you mark the project as incompatible by calling the method IVsAppCompat.BreakAssetCompatibility directly, instead of first calling the IVsAppCompat.AskForUserConsentToBreakAssetCompat method because the dialog box doesn’t need to appear twice.

Here is an example to help summarize the compatibility user experience. If a project was created in Visual Studio 2010 with SP1, that project is opened in Visual Studio 2012, and Visual Studio 2012 determines that an upgrade is required, Visual Studio displays a dialog box to ask the user for permission to make the changes.

If the user agrees, the project is modified and then loaded. If the project was created by using Visual Studio 2005 or Visual Studio 2008, the solution file will also be upgraded. If the solution is then closed and reopened in Visual Studio 2010 with SP1, the one-way-upgraded project will be incompatible and not loaded (but will load in Visual Studio 2012).

 

If the project had only required a repair (instead of an upgrade), the repaired project will still open in Visual Studio 2010 with SP1, Visual Studio 2012, and Visual Studio 2013.

The call to IVsProjectUpgradeViaFactory::UpgradeProject contains an IVsUpgradeLogger logger, which project systems and flavors should use to provide detailed upgrade tracing for troubleshooting. If a warning or an error is logged, Visual Studio shows the upgrade report.When you write to the upgrade logger, consider the following guidelines:

  • Visual Studio will call Flush after all projects have finished upgrading. Don’t call it in your project system.
  • The LogMessage function has the following ErrorLevels:
    • 0 is for any information that you’d like to trace.
    • 1 is for a warning.
    • 2 is for an error
    • 3 is for the Report formatter. When your project is upgraded, log the word “Converted” once, and don’t localize the word.
  • If a project doesn’t require any repair or upgrade, Visual Studio will generate the log file only if the project system had logged a warning or an error during UpgradeProject_CheckOnly or UpgradeProjectFlavor_CheckOnly methods.

HTML5 SharePoint Pic Web Part Released and Available !!

This is a Sandbox web part control to display a matrix of image thumbnails.

For a build a Metro IDE or a Picture Gallery to show products, news, or a social team that integrates with pictures, etc. All this, from any SharePoint picture library.

Supports : SharePoint 2010 & 2013 On-Premise Web Part,  SharePoint Online Web Part

FEATURES OF THE WEB PART** ver. 1.0

     

**PREVIEW EXAMPLE OF THE CONTROL**





 
1