Silent PDF printing in Silverlight .. Finally!

Apr 20 2011

Silent PDF printing without Acrobat Reader popping up is one of the many issues that dampen their spirits of developers, make them wonder why would such a simple issue is so elusive.

Come to Silverlight, Print() function .. in Silverlight 4 (yet to check in recently released Silverlight 5), mandates Printer dialog prompt to select a printer which adds 2 levels of user intervention, one to select printer and another to close Acrobat Reader.

I had thoughts of handling the print dialog issue using NESL to get the list of printers and giving command line print to Acrobat Reader to print PDF files. This will at least not prompt the user to select printer. But issue with Acrobat reader opening is still an issue. After much searching, found this cheapest solution that fits the equation.

Apart from basic software like VS2010 and Silverlight 4 tools, you will be needing licensed version of TotalPDFPrinterX(Which prints pdfs without needing Acrobat Reader installed on the client machine, silently to selected printer), couple of VBScripts, NESLv2.

How do we achieve the end goal? First we need printers list in Silverlight which with current capabilities and restrictions of Silverlight we cannot. So we call a VBScript file which will write all available printer names in a comma separated format to a file using WMI. In Silverlight UI, read and populate it to combobox or whereever necessary. Now to download PDF to any folder of our choice. Silverlight does not allow it. Silverlight mandates IsolatedStorage, but there is no strightforward way of knowing the path. So another VBScript file will download the PDF to known location. In the same script file we call TotalPDFPrinterX to print the PDF silently :)

Code is available at https://github.com/pooran/NESLSilentPDFPrint

2 responses so far

Copy the project output as another project’s resource in a solution

Jan 31 2011

There are many scenarios where we need one project’s output to be deployed to another project folder where either it will be used as reference or executable at runtime

So in the project properties go to ‘Build Events’ > ‘Post build event command line’ and type in the string below.

copy /Y “$(TargetPath)” “$(SolutionDir)\<project>\<folderpath>”

We had couple of requirements like this.. one where an exe has to be used as content in another project and in another we wanted a dll to be deployed to a specific folder in another project. Both cases this worked wonderfully :)

Hope it helps someone who is doing this copy process manually :)

No responses yet

Tip: JSON Serialization in Silverlight

Jan 24 2011

To enable JSON Serialization/Deserialization in Silverlight, if we just add reference to System.Runtime.Serialization, it will not be enough. You also need to add System.ServiceModel.Web reference too. Figured it out after lot of web searches.

Hope that helps somebody who is desperate with this issue :)

Source : Chris Pietschmann’s blog. Refer the article for a neat example on JSON Serialization/Deserialization.

No responses yet

Converting Silverlight application to run from IIS

Jan 24 2011

Many a times when we have to switch from Development environment to Production environment in Silverlight application, we need to test it locally.

Go to  <SilverlightApp>.Web properties. Navigate to Web > Servers. You will have many options. Choose ‘Use local IIS web server’ and try creating Virtual Directory for the same. You might get the following error.

—————————
Microsoft Visual Studio
—————————
Unable to create the virtual directory. To access local IIS Web sites, you must install the following IIS components:

      IIS 6 Metabase and IIS 6 Configuration Compatibility

In addition, you must run Visual Studio in the context of an administrator account.

For more information, press F1.
—————————
OK  
—————————

In Windows 7, go to control panel > Programs > Turn Windows features on or off. Install the required component ‘IIS 6 Metabase and IIS 6 Configuration Compatibility’ under ‘Internet Information Services’ and retry creating Virtual Directory .. and you are good to go :)

No responses yet

Log4Net needs full version of .Net 4.0 runtime

Jan 04 2011

If you are using/plan to use Log4Net in your project for error logging, and have decided to use the .Net 4.0 Client Profile, you will not be able to do so. Log4Net needs full version of .Net 4.0!

Just a heads up for someone who is in this scenario Smile

Technorati Tags: ,,,

One response so far

The specified solution configuration "Debug|BNB" is invalid.

Dec 30 2010

Sometimes in Blend 4, while compiling you will get an error saying ‘The specified solution configuration “Debug|BNB” is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform=”Any CPU”) or leave those properties blank to use the default solution configuration.
Done building project “XYZ.sln” — FAILED.
Build failed.

There are many variants like BNB, HPD and only known fix for this is to remove ‘Platform’ key under ‘HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet \Control \Session Manager \Environment’ using regedit, and restarting the machine.

Got this fix after couple of searches. Hope it saves couple of hours of searching for somebody Smile

Technorati Tags: ,,,

No responses yet

History Series | Web Services

Dec 12 2010

Lets consider a simple calculation program that does calculation like below.

Easiest way to calculate is to do it on click event of Calculate Button like below

private void CalculateButton_Click(object sender, EventArgs e)
        {
            if (IsNumeric(FirstTextBox.Text) && IsNumeric(SecondTextBox.Text))
            {
                switch (OperatorCombobox.SelectedItem.ToString())
                {
                    case “+”:
                        ResultLabel.Text = (double.Parse(FirstTextBox.Text.ToString()) + double.Parse(SecondTextBox.Text.ToString())).ToString();
                        break;
                    case “-”:
                        ResultLabel.Text = (double.Parse(FirstTextBox.Text.ToString()) – double.Parse(SecondTextBox.Text.ToString())).ToString();
                        break;
                    case “*”:
                        ResultLabel.Text = (double.Parse(FirstTextBox.Text.ToString()) * double.Parse(SecondTextBox.Text.ToString())).ToString();
                        break;
                    case “/”:
                        if (double.Parse(SecondTextBox.Text.ToString()) != 0.0)
                            ResultLabel.Text = (double.Parse(FirstTextBox.Text.ToString()) / double.Parse(SecondTextBox.Text.ToString())).ToString();
                        else
                            ResultLabel.Text = “Division by zero!”;
                        break;
                    default:
                        ResultLabel.Text = (double.Parse(FirstTextBox.Text.ToString()) + double.Parse(SecondTextBox.Text.ToString())).ToString();
                        break;
                }
            }
            else
            {
                ResultLabel.Text = “Please enter numbers!”;
            }
        }

        public static System.Boolean IsNumeric(System.Object Expression)
        {
            if (Expression == null || Expression is DateTime)
                return false;

            if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
                return true;

            try
            {
                if (Expression is string)
                    Double.Parse(Expression as string);
                else
                    Double.Parse(Expression.ToString());
                return true;
            }
            catch { } // just dismiss errors but return false
            return false;
        }

Now consider a scenario where this same function is supposed to be used in many places in a same application under different scenarios. In this scenario, it would be advised to create a class library and create a .dll (Dynamic Link Library) out of it and add it as a reference to it in the application. Sample class file will be as below

using System;

namespace CalculateLibrary
{
    public class Calculate
    {
        public string Calculate2numbers(string FirstNumber, string SecondNumber, string OperatorString)
        {
            ….
         }

        private static System.Boolean IsNumeric(System.Object Expression)
        {

            …
        }
    }
}

And the button click event will look like below

private void CalculateButton_Click(object sender, System.EventArgs e)
{
    CalculateLibrary.Calculate CalculateObject = new CalculateLibrary.Calculate();
    ResultLabel.Text = CalculateObject.Calculate2numbers(FirstTextBox.Text, SecondTextBox.Text, OperatorCombobox.SelectedItem.ToString());
}

Now, consider a scenario where many windows/web applications will be accessing this same calculate class and it has to be accessed from a remote website. Assume this calculate function is one of the most difficult one and you want to keep the implementation hidden, and want others to use it over web. In this scenario, one would create a web service to make it accessible over a url. Simple web service code would look like below. Each method that you want to expose will have [WebMethod] attribute over its declaration. Other functions that need not be publicaly available will not have the [WebMethod] attribute over it

using System;
using System.Web.Services;

namespace CalculateWebService
{
    /// <summary>
    /// Summary description for CalculateService
    /// </summary>
    [WebService(Namespace = http://tempuri.org/)]http://tempuri.org/&)]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    // [System.Web.Script.Services.ScriptService]
    public class CalculateService : System.Web.Services.WebService
    {
        [WebMethod]
        public string Calculate2numbers(string FirstNumber, string SecondNumber, string OperatorString)
        {
           …
        }

        private static System.Boolean IsNumeric(System.Object Expression)
        {
            …
        }
    }
}

User has to add web reference/service reference depending on version of .Net you are using, and the button click event will look like below

private void CalculateButton_Click(object sender, System.EventArgs e)
{
    CalculateService.CalculateServiceSoapClient CalculateServiceClient = new CalculateService.CalculateServiceSoapClient();
    ResultLabel.Text = CalculateServiceClient.Calculate2numbers(FirstTextBox.Text, SecondTextBox.Text, OperatorCombobox.SelectedItem.ToString());
}

Now consider a scenario where web service has to be made more secure and reliable, accessible faster in local intranet or accessible in local system via named pipes but running on different thread, WCF [Windows Communication Foundation] Services is the way to go. For WCF service, one needs to have Service Contract and  Data Contract where Service Contract is an interface and Data Contract is the implementation. When you create a WCF service with name CalculateService, it will create ICalculateService.cs and CalculateService.svc files. ICalculateService.cs will look like below

using System.ServiceModel;

namespace CalculateWCFService
{
    [ServiceContract]
    public interface ICalculateService
    {
        [OperationContract]
        string Calculate2numbers(string FirstNumber, string SecondNumber, string OperatorString);
    }
}

And CalculateService.svc will look like below

using System;

namespace CalculateWCFService
{
    public class CalculateService : ICalculateService
    {
        public string Calculate2numbers(string FirstNumber, string SecondNumber, string OperatorString)
        {
            …
        }

        private static System.Boolean IsNumeric(System.Object Expression)
        {
           …
        }
    }
}

One has to add Service Reference to the WCF service. This assumes one is building apps in .Net 3.5 or .Net 4.0. The button click event will look like below

private void CalculateButton_Click(object sender, System.EventArgs e)
{
    CalculateServiceReference.CalculateServiceClient CalculateServiceClientObject = new CalculateServiceReference.CalculateServiceClient();
    ResultLabel.Text = CalculateServiceClientObject.Calculate2numbers(FirstTextBox.Text, SecondTextBox.Text, OperatorCombobox.SelectedItem.ToString());
}

While adding reference to the WCF service, in the advanced settings, if the user selects for Asynchronous Methods, the button click events will look like below. With Async methods, the UI will be more resonsive while the actual work happens on different thread.

private void CalculateAsyncButton_Click(object sender, System.EventArgs e)
{
    CalculateServiceReference.CalculateServiceClient CalculateServiceClientObject = new CalculateServiceReference.CalculateServiceClient();
    CalculateServiceClientObject.Calculate2numbersCompleted += new System.EventHandler<CalculateServiceReference.Calculate2numbersCompletedEventArgs>(CalculateServiceClientObject_Calculate2numbersCompleted);
    CalculateServiceClientObject.Calculate2numbersAsync(FirstTextBox.Text, SecondTextBox.Text, OperatorCombobox.SelectedItem.ToString());
    ResultLabel.Text = “Calculating asynchronously”;
}
void CalculateServiceClientObject_Calculate2numbersCompleted(object sender, CalculateServiceReference.Calculate2numbersCompletedEventArgs e)
{
    ResultLabel.Text = e.Result;
}

Sample code is available below

No responses yet

Silverlight Out Of Browser with Simple Sync

Dec 12 2010

Silverlight allows a XAP file to run out of browser with simple settings. When the application is running in Out Of Browser [OOB], there are few scenarios to consider like

  • What if the connection to the server is down
  • How to store data until connection is restored and sync back.
  • What strategy one has to handle concurrency

So, I went ahead and tried out a sample application where I take an input in a textbox and store it in IsolatedStorage as a serialized object if connection is off and Sync back the data on to the textbox once connection is restored.

While building the application, I learnt quite a deal about how to handle most of the issues

To check if connection is available, check the simple line of code below

bool IsNetworkAvailable = NetworkInterface.GetIsNetworkAvailable();

To check if application is installed as a desktop application, check the code below

InstallState installState = Application.Current.InstallState;
switch (installState)
{
    case InstallState.NotInstalled:
        ApplicationStatus = “Running Online”;
        break;
    case InstallState.Installing:
        ApplicationStatus = “Installing”;
        break;
    case InstallState.Installed:
        ApplicationStatus = “Installed”;
        IsOutOfBrowser = true;
        break;
    case InstallState.InstallFailed:
        ApplicationStatus = “Install Failed”;
        break;
    default:
        ApplicationStatus = “Unknown State”;
}

To install application as out of browser application, simply we can right click and install it. Btw, we need to set the Out of browser settings in the project properties. In case we want to a button to install the application as a out of browser application, we can use the code below

public void DetachFromBrowserAction(object param)
{
    if (Application.Current.InstallState != InstallState.Installed)
    {
    try
    {
        Application.Current.Install();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    }
}

To close the application when it is running out of browser, check the hack by Enrico Gebauer below

dynamic _winObject = null;
public void CloseWindowAction(object param)
{
    if (Application.Current.IsRunningOutOfBrowser)
    {
    _winObject = AutomationFactory.CreateObject(“WScript.Shell”);
        _winObject.Run(@”cmd /k taskkill /IM sllauncher.exe & exit”, 0);
    }
}

IsolatedStorage is used to store serialized objects and files mainly for offline use. Below is a simple line of code to add an object to IsolatedStorage

IsolatedStorageSettings.ApplicationSettings.Add(“MyDataStore”, MyDataObject);

Below is the code to retrieve the object from IsolatedStorage as an object

if (IsolatedStorageSettings.ApplicationSettings.Contains(“MyDataStore”))
{
     MyData StoredMyData = (MyData)IsolatedStorageSettings.ApplicationSettings["MyDataStore"];
}

To remove the object from IsolatedStorage, use the code below

if (IsolatedStorageSettings.ApplicationSettings.Contains(“MyDataStore”))
{
     IsolatedStorageSettings.ApplicationSettings.Remove(“MyDataStore”);
}

Most of the codebase is inspired by MSDN article.Sample source code is available below

Sample code is built on Model-View-ViewModel( M-V-VM or simply MVVM) pattern. So look out for Commanding, Databinding and Converters usage.

No responses yet

History series | Evolution of data access

Dec 06 2010

Before 1989, there were many modes of storage of data like text files, CSV files etc. and in those days, custom programming to access data was the only way.

Until 1992, some Direct APIs were used like DB library, ESQL for C etc.

In September 1992, ODBC as a standard emerged that connected various data stores like text files, CSV and gave a good abstract layer for programmers to address various types of data stores

Then there was a need of accessing data remotely. As a result RDO was introduced in August 1995

Though ODBC and RDO could provide access to various data stores, some pointer capable languages found it difficult and hence OLEDB concept emerged in August 1996. ODBC become most efficient full featured API for SQL Server.

In October 1996, Microsoft announced ActiveX Data Objects (ADO) which is a set of Component Object Model (COM) objects for accessing data sources. A part of MDAC, it provides a layer between programming languages and OLE DB (a means of accessing data stores, whether they be databases or otherwise, in a uniform manner). ADO allows a developer to write programs that access data without knowing how the database is implemented. It also supported pointers based languages. ADO was mainly used for scripting and Classic ASP

In the years that followed till 2008 there were many native ODBC clients written. ODBC was a much better choice in most cases to access data across various data sources

In Feb 2002, Microsoft launched ADO.Net with core services being same, provided various data adapters for SQL server called SQL client, ODBC and OLEDB for various other data sources including XML

Over time it matured and XML was becoming a most versatile way of storing data when data is not huge. Close competitor was JSON. In November 2007, general-purpose query facilities added to the .NET Framework apply to all sources of information, not just relational or XML data. This facility is called .NET Language-Integrated Query (LINQ). LINQ defines a set of method names (called standard query operators, or standard sequence operators), along with translation rules from so-called query expressions to expressions using these method names, lambda expressions and anonymous types.
It picked up so well that people started writing many variants like some listed below

  • Data Services: LINQ to ADO.NET Data Services
  • dotConnect: LINQ to Oracle, MySQL, PostgreSQL, and SQLite
  • Entity Framework: LINQ to Entities
  • Windows Search: LINQ to System Search
  • Google search: LINQ to Google
  • DbLinq: LINQ to MySQL, PostgreSQL, Oracle, Ingres, SQLite and Microsoft SQL Server
  • NHibernate: LINQ to NHibernate contribution project
  • DataObjects.NET: LINQ to DataObjects.NET
  • LLBLGen Pro: LINQ to LLBLGen
  • OpenMapi: LINQ to MAPI
  • CSV: LINQ to CSV
  • Twitter: LINQ to Twitter
  • db4o: LINQ to db4o
  • Wikipedia: LINQ to Wikipedia
  • LINQ to XSD: LINQ to XML Schema

In August 2008 Entity framework and Entity Data model based on LINQ for Entities was proposed which was a very good foundation for Object Relational Mapping

And very recently, along with a bandwagon of WCF, WCF Data Services and WCF RIA services came into existence. With OData Restful services also emerged.

Hope that gives a brief history lesson for starters :)

No responses yet

System.ArithmeticException: Overflow or underflow in the arithmetic operation !

Nov 30 2010

In WPF/Windows forms applications, you will encounter the error that says ‘System.ArithmeticException: Overflow or underflow in the arithmetic operation.’ It occurs usually when we do something with the way the forms/windows/components/elements are rendered/changed/modified at runtime. Though many blogs and real world experiences claim that the issue is because of wrong/conflicting display drivers, no permanent fix is available without code change.

From our experience, in places where there is text input, this error appears in some machines. Whenever user tries to enter a value, we get this error.

Ideal fix for this is to use _fpreset function from msvcr70.dll, If you are running Windows Vista/7, you many not find this file in your system. Better download it from dlldump.com.

Add the dll to your project with Build Action as ‘Content’ and ‘Copy to Output Directory’ as ‘Copy Always’

If you have many instances of error at various places, it is recommended to use a shared static class.

public static class SharedData
{
    [DllImport("msvcr70.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int _fpreset();
}

And wherever we expect to get error try this code below. We get this error on Window_KeyDown event more often

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    try
    {
        SharedData._fpreset();
        //logic goes here
    }
    catch (Exception ex)
    {   
        //logic goes here
    }
}

This is not a fool proof solution, but at least your customer does not see this error message Smile

No responses yet

Older posts »