Monday, March 1, 2010

Click Once Deployment

Deployment term can mean an installation of software program on user’s machines. Microsoft Visual Studio 2008 provides several methods for deploying your application. A familiar technology we all know is Microsoft Installer program which offers more detailed and complex deployment scenarios with multiple configuration steps. We’ll see another alternative light weight mechanism called ClickOnce.

Click Once Deployment features:

  • A ClickOnce setup can’t perform custom actions (accessing file system,registry, custom installation folder, custom setup wizard) when compared to extensive MSI setups. On the other hand, biggest gaining point is “Automatic update feature.”
  • ClickOnce applications are installed for a single user. You cannot install an application for all users on a machine. ClickOnce applications are always installed in a system-managed user-specific folder. You cannot change the folder where the application is installed.
  • ClickOnce setup can’t install shared components in the global assembly cache (GAC). ClickOnce apps are self-contained and isolated from rest of systems and runs no risk of breaking other apps.
  • By default, ClickOnce applications are self-updating. They can check for an update whenever they’re launched. ClickOnce usually is considered to be the preferred technology for WPF deployment.
  • ClickOnce technology supports stand alone deployments and deployments to web or file share. Many aspects of its behavior are completely fixed to guarantee a consistent user experience.
  • Clickonce deployment allows a user to launch a setup program from a browser page.
  • As you publish newer versions of your application, ClickOnce adds new subdirectories for each new version. The ClickOnce engine, dfsvc.exe, handles updates and downloads.The publishing wizard is a quick way to create a ClickOnce deployment
  • The key difference is that the publish version is the criteria that are used to determine whether a new update is available. If a user launches version 1.0.0.0 of an application and version 1.0.0.1 is available, the ClickOnce infrastructure will show the update dialog box. The Updates button isn’t available if you’re creating an online-only application. An online-only application always runs from its published location on a website or network share.
  • ClickOnce is a light weight setup option compared to MSI-based setups. Due to which, Click Once deployment doesn’t allow for much configuration and suitable for apps that don’t have elaborate installation requirements and have minimum security reqs. ClickOnce can deploy apps (WPF,Win Forms, page apps) in Full-Trust as well as partial trust apps(XBAP’s). 
  • ClickOnce supports two flavors of apps. i.e Online/Offline modes. If you choose to create an online-only available application, the user needs to return to the published location to run the application.   An old version of the application can’t be used after you roll out an update in online-only apps. This part of the deployment model is similar to a web application.
  • The publish.htm file is present only if you’re deploying to a web server. If you choose to publish for a CD installation, you don’t have the option of creating an online-only application.
  • In ClickOnce deployment, the .manifest and .application files store information about required files, update settings, and other details. These files are digitally signed at the time of publication, so these files can’t be modified by hand. If you do make a change, ClickOnce will notice the discrepancy and refuse to install the application.

Using Visual Studio:

 

You can deploy an application using ClickOnce directly from Visual Studio IDE using Publish tab of the project properties dialog box.

 

image

 

You can publish your app using ClickOnce by setting different publish properties in this page and then clicking “Publish Now” button.

Publish Location:

Specify the publishing location in Publishing Folder Location combo box. This can be a file path, a network file path, IIS path, a FTP address or external http address. Remember, Whatever value you specify, this will finally the go to location to install the app.

image

Installation folder:

Specify alternate Installation Folder URL if you’re planning to publishing to temporary location (staging) before it’s available for users to download.

Install Mode and Settings:

You can have your app available online which means app is available only when user is online OR you can make it offline. If you choose Online mode, app will be run directly from the publish location ensuring that the user always runs the most recent version. NO client installations!!

You can select “The Application is Available Offline As Well” to make app available both online and off-line. Anyways, local copy of app is available on client computer running offline.

Publish Wizard:

Clicking Publish Wizard makes things easy for you. If you like wizard like interface to configure your ClickOnce deployment, You’re lucky. A wizard will guide your through similar steps what we’re discussing to publish your application.

Options:

 

image

Clicking options button on publish dialog box brings up the above window. Obviously, you can set Publisher Name, the Product Name, the Support URL, and the name for the Deployment Web Page that is generated when the app is published.

Updates:

image

Clicking update button on publish dialog box brings up the above window. This is where magic happens. You can this window to specify whether app can check for updates automatically and time to check for updates.

Check “The application should check for updates” to enable app to check for updates. Either before app starts/after app starts we can check for updates. We can get into more granularity by specifying frequency for update check in terms of days.

You can also specify a minimum required  version for the application, and you can also specify a different location for updates if your updates are hosted in a location other than the install location.

Signing the ClickOnce manifests(.manifest/.Application)

image

Clicking the signing tab opens up the above shown window. You can use this window to associate a certificate/test certificate

with your application. You can use certificates to sign your ClickOnce based apps. You can also create Test certificate right from this window for signing.

 

Finally, Visual studio creates few criticial files like Application Manifest during ClickOnce deployment that describes the files and dependencies, identity of assemblies and file associations. We cannot configure File associations via Visual Studio user interface. To create a file association, we must edit the manifest file manually.

I missing screen shot of final publish.htm file that pops out when published from visual studio.

 

Wednesday, February 24, 2010

WPF Documents

Windows Presentation Foundation (WPF) provides rich set of features that help work with print ready and authoring documents easily.

 

WPF supports two types of Document models which provide rich layout support for displaying large amounts of text combined with features like scrolling, pagination and zoom.

 

Types of Documents:

  • Fixed Documents are XPS (Open XML Paper Specification) based fixed type set documents which are print ready
  • Flow Documents are dynamic which can layout the content dynamically based on details such as size of window and resolution.

Fixed document Flow document

       

WPF provides different kinds of Document containers to display these documents.

  • DocumentViewer allows to show fixed documents (XPS documents) in a window. (readonly) –Shown above
  • FlowDocumentPageViewer, FlowDocumentReader and FlowDocumentScrollViewer containers are read only which displays flow documents. (XAML documents) – Shown Above

FlowDocumentScrollViewer:

FlowDocumentScrollViewer shows the entire document with a scroll bar to let you move through it if the document exceeds the size of the FlowDocumentScrollViewer. The FlowDocumentScrollViewer doesn’t support pagination or multicolumn displays.

  • Printing and Zooming is supported.
  • Toolbar is hidden by default. To make it visible, set IsToolbarVisible to true
  • To disallow text selection in flowDocumentScrollViewer, use FlowDocumentScrollViewer.IsSelectionEnabled to false.

image

 

FlowDocumentPageViewer:

FlowDocumentPageViewer splits a flow document into multiple pages. Each page is as large as the available space and the user can step from one page to the next. The Flow-DocumentPageViewer has more overhead than the FlowDocumentScrollViewer  due to pagination feature.

  • Printing and Zooming is supported.
  • Toolbar is enabled by default.

image

 

FlowDocumentReader:

FlowDocumentReader combines the features of the FlowDocumentScrollViewer and FlowDocumentPageViewer. It lets the user choose whether to read content in a scrollable or paginated display. It also includes searching functionality.

The FlowDocumentReader has the most overhead of any flow document container. 

 

It supports three modes to display document.

  1. ScrollBarMode
  2. TwoPageMode
  3. PageMode
  • Printing and Zooming is supported.
  • Toolbar is enabled by default.
  • Document search functionality is supported.

image

 

Preserving space in WPF documents:

 

You need to use the xml:space attribute with the value preserve, which is an XML convention that tells an XML parser to keep all the whitespace characters in the content

 

 

Fixed Document snippets:

 

Code Snippet
  1. using System.Windows;
  2. using System.Windows.Documents;
  3. using System.Windows.Markup;
  4. using System.Windows.Xps.Packaging;
  5. using System.Xml;

 

 

Creating a simple Fixed document Programmatically:

 

Code Snippet
  1. var fixedDocument = new FixedDocument();
  2.             PageContent pageContent = new PageContent();
  3.             fixedDocument.Pages.Add(pageContent);
  4.             FixedPage fixedPage = new FixedPage();
  5.             TextBlock textBlock = new TextBlock
  6.                                       {
  7.                                           Margin = new Thickness(10, 10, 0, 0),
  8.                                           Text = "TestPage",
  9.                                           FontSize = 20
  10.                                       };
  11.             fixedPage.Children.Add(textBlock);
  12.             ((IAddChild)pageContent).AddChild(fixedPage);
  13.             dvDocumentViewer.Document = fixedDocument;

 

 

Saving a simple Fixed document Programmatically:

Code Snippet
  1. var xpsDocument = new XpsDocument(@"C:\test.xps", FileAccess.ReadWrite, CompressionOption.NotCompressed);
  2.          XpsDocumentWriter xdw = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
  3.          xdw.Write(document);
  4.          xpsDocument.Close();

 

 

Programmatically opening a Fixed document(XPS doc):

 

Code Snippet
  1. XpsDocument document = new XpsDocument(@"C:\Test.xps", FileAccess.Read);
  2.           IDocumentPaginatorSource documentPaginatorSource = document.GetFixedDocumentSequence();
  3.           dvDocumentViewer.Document = documentPaginatorSource;

 

 

 

Flow Documents snippets:

 

 

Code Snippet
  1. using System;
  2. using System.IO;
  3. using System.Windows;
  4. using System.Windows.Documents;
  5. using System.Windows.Markup;
  6. using System.Windows.Media;
  7. using System.Windows.Shapes;
  8. using System.Xml;

 

Programmatically creating a Flow document(XAML):

 

Code Snippet
  1. var flowDocument = new FlowDocument();
  2.             //creating a new paragraph
  3.             var paragraph = new Paragraph();
  4.             paragraph.Inlines.Add("This is a simple para.");
  5.             paragraph.Inlines.Add("created in a flow document.");
  6.             paragraph.Inlines.Add("This is a para3");
  7.             paragraph.Inlines.Add("This is a para4");
  8.             paragraph.Inlines.Add("This is a para5");
  9.             paragraph.Inlines.Add("This is a para6");
  10.             paragraph.Inlines.Add("This is a para7");
  11.             //Adding para to blocks collection of flow document.
  12.             flowDocument.Blocks.Add(paragraph);
  13.             //Creating new floater object.
  14.             Floater floater = new Floater();
  15.             paragraph = new Paragraph();
  16.             Rectangle rect = new Rectangle();
  17.             rect.Width = 50;
  18.             rect.Height = 50;
  19.             rect.Fill = Brushes.Blue;
  20.             rect.StrokeThickness = 2;
  21.             rect.Stroke = Brushes.Black;
  22.             paragraph.Inlines.Add(rect);
  23.             floater.Blocks.Add(paragraph);
  24.             //Adding floater object to blocks collection of flow document.
  25.             flowDocument.Blocks.Add(new Paragraph(floater));
  26.             fdrViewer.Document = flowDocument;

 

 

Saving a simple Flow document Programmatically(XAML):

 

Code Snippet
  1. XmlTextWriter xmlWriter = null;
  2.             TextWriter writer = null;
  3.             Stream file = null;
  4.  
  5.             try
  6.             {
  7.                 file = File.Create(fileName);
  8.                 writer = new StreamWriter(file);
  9.                 xmlWriter = new XmlTextWriter(writer);
  10.                 //The main function of the XamlDesignerSerializationManager is to get and set the serialization mode for a given expression type.
  11.                 var xamlDesignerSerializationManager = new XamlDesignerSerializationManager(xmlWriter);
  12.                 XamlWriter.Save(documentPaginatorSource.DocumentPaginator.Source, xamlDesignerSerializationManager);
  13.             }

 

Programmatically opening a Flow document(XAML):

 

Code Snippet
  1. Stream file = null;
  2.          TextReader reader = null;
  3.          XmlTextReader xmlTextReader = null;
  4.          try
  5.          {
  6.              file = File.OpenRead(@"c:\test.xaml");
  7.              reader = new StreamReader(file);
  8.              xmlTextReader = new XmlTextReader(reader);
  9.  
  10.               FlowDocument flowDocument = XamlReader.Load(xmlTextReader) as FlowDocument;
  11.               fdv.Document = flowDocument;
  12.          }

Tuesday, January 19, 2010

WCF errors: No set method for property on Type 'xx'

I was surprised when i first saw this error. This usually happens when you try to publish DataContract on WCF service containing Read only properties. I don't know why exactly this error occurs? As many people are concerned, workaround for this problem looks very obvious.

Add Setter to the property in question.  But, this move will defeat your original purpose of Read only property.

Huh.., Ok, here's solution. just add Private keyword to your setter method. WCF allows this provision. So, client can never see the set method on your property acting much like a read only property.

WCF errors: WCF service has zero application (non-infrastructure) endpoints.This might be because no configuration file was found on your application, or because no service element matching the service name is found in the configuration file, or because no endpoints were defined in the service element.

This WCF error always pops on my computer when ever i'm creating brand new WCF service.  Bluntly, we can understand from error that we haven't configured the service properly. Of course, there can be multiple causes. Handy tool which can help during this crisis :-) is "WCF Service Configuration Editor". You can open WCF Service Configuration Editor (SvcConfigEditor.exe) by right clicking on configuration file in your WCF service library project or accessing it under Tools menu in the Visual Studio IDE.


On left pane in editor, you'll see various service elements already defined.  Click on your Service Endpoint node.  90% of time root cause of this error will be hanging around this Service Endpoint definition. 


Remember, all the WCF service  configuration definition is found under  element


Here's the checklist that should help resolve this error.

  • Confirm your Contract attribute of Endpoint element is pointing to appropriate Service contract instead of "IService1" unless you are still using "IService1" as service contract.  
  • Confirm your Name attribute of Service Element is set appropriately to Service class implementation instead of "Service1" unless you're still using "Service1" as service implementation.
  • Also, Examine ServiceHost directive declaration in service1.svc markup.  Clean up any scrap you see and provide fully qualified namespace for the service class for service attribute.

 I strongly recommend you use Service Configuration Editor for any kind of poking around web.config/app.config related to WCF service. This way, you'll keep service configuration neat and clean. especially with complex configuration files, this tool will come handy in organizing the service elements easily.

WCF errors: Type 'xxx' is an invalid collection type since it has DataContractAttribute attribute.

If you have ever happen to get "Type xxx is an invalid collection type since it has DataContract Attribute attribute" error at any time when ever publishing WCF service, Make sure you annotate your custom collections with CollectionDataContract attribute instead of DataContract attribute. This attribute will appropriate serialize and deserialize collection.


CollectionDataContract attribute is typically utilized in scenarios involving non-WCF providers/clients to extract exact shape of data. But, you loose one important benefit with "CollectionDataContract" is "Cross Collection Interchangeability". For instance, in case of homogeneous environment of WCF client and service though WCF service exposes List collections as response, client expecting different native collection type like ArrayList/Collection can still consume the collection.


You loose this benefit if you use CollectionDataContract attribute with Collection Types.

WCF also imposes additional requirements when using collections. Keep in mind of following items when exposing custom collections via WCF service or else custom collections are not serialized/deserialized.


  • Collection should support Add method.
  • Collection should have default constructor.