Razan Paul Blog

Explaining thoughts and findings is a great way to learn
MST file to automate MSI file editing

Default Setup project in visual studio does not give all the options we need. As a result, many people employ third party setup projects. Another option is using ORCA tool from Microsoft to edit the MSI file for your requirement. In the later approach, you first need to build the MSI file (Windows Installer package) using visual studio, then open the MSI file in ORCA and make the necessary changes. Basically MSI file contains a database (a number of tables) that you can edit using ORCA; Editing operations include adding new rows and editing existing rows to different tables.

However, there is a problem in the process of using ORCA. The problem is that each time you make changes in the project and build a new installer; you have to make the same changes in ORCA. To address this issue, Microsoft offers MST file (kind of a batch file) to automate the process. To make an MST file, you can follow the following steps:

1. Open an MSI file in ORCA

2. use Transform -> New Transform menu to start editing

3. modify what you need

4. use Transform -> Generate Transform menu to save the transform to a MST file

Once you have the MST file, you will apply the MST file to MSI file to update MSI file each time you update the MSI file. However, there is a catch, specially if you have embedded binary streams (such as embedded cabinet files)

1. Open the newly created MSI file by file->open

2. Then click Transform->Apply Transform and select the previously created MST file

3. If you have embedded binary streams, go to Tools/Options, on the “Database” tab there is an option called “Copy embedded streams during ‘Save As’.” and enable it.

4. Finally save the MSI using "Save Transformed as" under file menu.

Alternatively, you can apply MST file from command line or using a batch file:

cscript WiUseXfm.vbs [path to original database][path to transform file][options]

For details, look at MSDN

The Orca editor is available in the Windows Installer SDK. Hope this will save some of your time!

A Simple Online Document Management System Using Asp.net MVC 3
Nowadays we have a number of online file management systems (e.g. DropBox, SkyDrive and Google Drive). People can use them to manage different types of documents. However, one might need a system to manage documents when they do not want to publish the company documents to the cloud. In that case, they need to build an online document management system. This project is intended to meet this purpose. However, it is in the early stage. All the functionalities seem working. A lot of work is needed in the UI. Besides this, code needs refactoring. Please find the project at the following link:

https://documentmanagementsystem.codeplex.com/

Emulating Synchronous Web Service Call in Silverlight 3

As we know, only option for web service calling in Silverlight is asynchronous and Silverlight framework does not provide any API for synchronous call. In this post, i will show how we can emulate synchronous web service call using the default asynchronous web service call mechanism of Silverlight.

One simple idea to solve this problem is sleeping UI thread after web service call until result back. But it will block UI thread. So Dispatcher will be blocked and UI will be freeze. No interaction will be possible with the Silverlight UI. So blocking the UI thread is not the Solution.

To solve this problem, i have performed asynchronous service calling in a worker thread and blocked the worker thread until result is retrieved. Result is send to the UI thread using Dispatcher.invoke to Update UI. To block the worker thread until the result is retrieved from the web service, I have used thread synchronization mechanism AutoResetEvent. For emulating synchronous web service call, the following code has been used.

   1: public partial class MainPage : UserControl
   2:    {
   3:        private  AutoResetEvent autoResetEvent = new AutoResetEvent(false);
   4:        public MainPage()
   5:        {
   6:            InitializeComponent();
   7:            StartServerTimeUpdatingSyncronosly();
   8:        }
   9:        private void StartServerTimeUpdatingSyncronosly()
  10:        {
  11:            try
  12:            {
  13:                Thread thread = new Thread(new ThreadStart(UpdateTimeSyncronosly));
  14:                thread.Start();
  15:            }
  16:            catch (Exception ex)
  17:            {
  18:                MessageBox.Show(ex.Message, "SynchronousWebServiceCalling", MessageBoxButton.OK);
  19:            }
  20:        }     
  21:        private void UpdateTimeSyncronosly()
  22:        {
  23:            SynchronousWebServiceCalling.ContentServiceReference.ContentServiceClient contentServiceClient = new SynchronousWebServiceCalling.ContentServiceReference.ContentServiceClient();
  24:            contentServiceClient.ReturnServerTimeCompleted += new EventHandler<SynchronousWebServiceCalling.ContentServiceReference.ReturnServerTimeCompletedEventArgs>(ReturnServerTimeCompleted);
  25:            string message = "Retrieving new server time...";
  26:            while (true)
  27:            {
  28:                this.Dispatcher.BeginInvoke(new Action<string>(DisplayBusyMessage), message);
  29:                contentServiceClient.ReturnServerTimeAsync();
  30:                autoResetEvent.WaitOne();
  31:            }
  32:        }
  33:        void ReturnServerTimeCompleted(object sender, SynchronousWebServiceCalling.ContentServiceReference.ReturnServerTimeCompletedEventArgs e)
  34:        {
  35:            this.Dispatcher.BeginInvoke(new Action<string>(DisplayTime), e.Result);         
  36:            string message = "New server time is retrieved";
  37:            this.Dispatcher.BeginInvoke(new Action<string>(DisplayBusyMessage), message);
  38:            System.Threading.Thread.Sleep(5000);
  39:            autoResetEvent.Set();
  40:        }
  41:        private void DisplayTime(string time)
  42:        {
  43:            tblTime.Text = time;
  44:        }
  45:        private void DisplayBusyMessage(string message)
  46:        {
  47:            StatusLabel.Text = message;
  48:        }
  49:    }

Here AutoResetEvent plays an important role to implement this. It has a method WaitOne. According to MSDN, WaitOne blocks the current thread until the current instance receives a signal. So in the worker thread, we call WaitOne() after calling the web service method to block the worker thread until the result of web service operation is received. When the result of web service operation is received in ReturnServerTimeCompleted method, Set() method of AutoResetEvent is used to signal the worker thread so that next consecutive web service call can be made.

You can download the sample code from here. Hope this will save some of your time.

A simple Text Marquee Control in Silverlight

marq1

A Silverlight text marquee is a scrolling piece of text displayed either horizontally across or vertically down your container. Here i will describe how I came up to make a marquee text control using Canvas and TextBlock. This marquee text control scrolls text in Left to right, right to left, top to bottom and bottom to top. The following three techniques are used to achieve marquee animation:

Negative Positioning in canvas: If we set negative value to any of the positioning property of Canvas: Left, Right, Top and Bottom for an UIelement , Canvas draws that UIelement outside of Canvas area.

Clip Geometry: In WPF, if you set the value of the ClipToBounds property of canvas to true, Canvas will clip its children when they go outside of Canvas.But there is no ClipToBounds property of canvas.Every UIelement has a Property named clip, which is Geometry type. You can set any geometry used to define the outline of the contents of an element. Only the area that is within the region of the geometry will be visible. Portion of UIelement outside the geometry will be visually clipped in the rendered layout. To clip the marquee when they go outside of Canvas (container), I have used rectangle geometry as clip geometry of the Canvas.

Changing Position of UIelement continuously: By changing continuously any of the canvas positioning property Left and Top, we can get moving text. Here marquee text control is a user control consists of TextBlock and canvas.

The XAML of marquee text control is in the following:

   1: <UserControl x:Class="SilverlightMarqueeText.MarqueeText"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   4:     <Canvas Name="canMain" >
   5:         <TextBlock Name="tbmarquee"> </TextBlock>
   6:     </Canvas>
   7: </UserControl>

How is Left to right marquee text implemented in this control?

Here a canvas is used as the container of marquee text. To move the text outside of canvas negative Left property of canvas is used. However, if negative left property of canvas is applied to any UIelement like TextBlock, it will go outside of its parent container but will still remain visible outside of the parent container. To make marquee text invisible outside of canvas, i have set a rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation left property of canvas for that element is being changed continuously to get moving text. The whole thing is done using the following code.

   1: private void LeftToRightMarquee()
   2:      {
   3:          RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:          rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:          canMain.Clip = rectangleGeometry;
   6:          double height = canMain.Height - tbmarquee.ActualHeight;
   7:          tbmarquee.Margin = new Thickness(0, height / 2, 0, 0);
   8:          DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:          doubleAnimation.From = -tbmarquee.ActualWidth;
  10:          doubleAnimation.To = canMain.Width;
  11:          doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:          doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:          Storyboard storyboard = new Storyboard();
  14:          storyboard.Children.Add(doubleAnimation);
  15:          Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:          Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
  17:          storyboard.Begin();
  18:      } 

How is right to left marquee text implemented in this control?

As we know, a canvas is used as the container of marquee text. Here marquee text is moved outside of canvas area equal to marquee text width and it is moved equal to canvas width using double animation. To move the text outside of canvas in the right direction, the value of left property of canvas is set equal to the width of the canvas. By this way, marquee text will go outside of its parent container but will remain visible outside of the parent container. To make marquee text invisible outside of canvas, i have set rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation left property of canvas for that element is being changed continuously to get moving text. The whole thing is done using the following code.

   1: private void RightToLeftMarquee()
   2: {
   3:     RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:     rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:     canMain.Clip = rectangleGeometry;
   6:     double height = canMain.Height - tbmarquee.ActualHeight;
   7:     tbmarquee.Margin = new Thickness(0, height / 2, 0, 0);
   8:     DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:     doubleAnimation.From = canMain.Width;
  10:     doubleAnimation.To = -tbmarquee.ActualWidth;
  11:     doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:     doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:     Storyboard storyboard = new Storyboard();
  14:     storyboard.Children.Add(doubleAnimation);
  15:     Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:     Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
  17:     storyboard.Begin();
  18: }

How is top to bottom marquee text implemented in this control?

Here marquee text is moved outside of canvas area equal to marquee text height and to behave like scrolling text, it is moved equal to canvas height using double animation. To move the text outside of canvas in the top direction, negative top property of canvas is used. However, if someone uses negative top property of canvas, it will go outside of its parent container but will remain visible outside of the parent container. To make marquee text invisible outside of canvas, i have set rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation top property of canvas for that element is being changed continuously to get moving text in the top to bottom direction. The whole thing is done using the following code.

   1: private void TopToBottomMarquee()
   2: {
   3:     RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:     rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:     canMain.Clip = rectangleGeometry;
   6:     double width = canMain.Width - tbmarquee.ActualWidth;
   7:     tbmarquee.Margin = new Thickness(width / 2, 0, 0, 0);
   8:     DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:     doubleAnimation.From = -tbmarquee.ActualHeight;
  10:     doubleAnimation.To = canMain.Height;
  11:     doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:     doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:     Storyboard storyboard = new Storyboard();
  14:     storyboard.Children.Add(doubleAnimation);
  15:     Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:     Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
  17:     storyboard.Begin();
  18: }

How is bottom to top marquee text implemented in this control?

To behave like each character coming out at a time, marquee text is placed outside of canvas area equal to marquee text height. To behave like scrolling text, it is moved equal to canvas height using double animation in the bottom to top direction. To place the text outside of canvas in the bottom direction, the value of top property of canvas is set equal to the height of the Canvas. To make marquee text invisible outside of canvas, i have set rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation on top property of canvas for that element is being changed continuously to get moving text in the top to bottom direction. The whole thing is done using the following code.

   1: private void BottomToTopMarquee()
   2: {
   3:     RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:     rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:     canMain.Clip = rectangleGeometry;
   6:     double width = canMain.Width - tbmarquee.ActualWidth;
   7:     tbmarquee.Margin = new Thickness(width / 2, 0, 0, 0);
   8:     DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:     doubleAnimation.From = canMain.Height;
  10:     doubleAnimation.To = -tbmarquee.ActualHeight;
  11:     doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:     doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:     Storyboard storyboard = new Storyboard();
  14:     storyboard.Children.Add(doubleAnimation);
  15:     Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:     Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
  17:     storyboard.Begin();
  18: }
You can download the sample code from here. Hope this will save some of your time.
CodeProject MVP for 2010

I have been awarded a CodeProject MVP for the articles I wrote in 2009. Thanks Codeproject for this recognition, which will encourage me to keep my passion on writing article.

I love CodeProject.

Thanks All.

Razan

My CodeProject Profile

Posted: Jan 12 2010, 07:54 PM by RazanPaul | with no comments
Filed under: ,
Exploring Clip Property of UIelement to Make Animation in WPF

Every UIelement has a Property named clip, which is Geometry type. You can set any geometry used to define the outline of the contents of an element. Only the area that is within the region of the geometry will be visible. Portion of UIelement outside the geometry will be visually clipped in the rendered layout. Using Clip property of UIelement in WPF, you can do lots of animation. I think it is a powerful way of doing animation. Possibilities are endless. You can do most geometrical type of animation in 2D using this technique. I have just published an article about this technique.

Here it is:

http://www.codeproject.com/KB/WPF/ClipBasedAnimationWPF.aspx

Posted: Dec 31 2009, 09:43 PM by RazanPaul | with no comments
Filed under: , ,
Making a Simple Marquee Text Control, Drip Animation and Roll Animation in WPF

An animation consists of a series of frames. To perform the animation, these frames are shown one after the other at a regular time interval. I have just published an article about how i came up with marquee text control, Drip animation, and Roll animation.

Here it is:

http://www.codeproject.com/KB/WPF/WPFAnimation1.aspx

Posted: Dec 31 2009, 09:40 PM by RazanPaul | with 1 comment(s)
Filed under: , ,
A simple snapshot taker application in WPF

The simple application is implemented using media player in WPF. You can also use this code to make preview of video in WPF. Here MediaPlayer is used to play video instead of MediaElement. There is nothing ground breaking here. The overall idea is: as we are playing video in content control which is a visual and we know, we can make image from any visual, so we are just making image from the video content control. The simple snapshot taker application looks like the following:

snapshotTaker

Here an openfiledialog is used to open video file. If you select non-video file, the application will give you the message “invalid file”. Process.Start(filename) starts a viewer by specifying a file name. It is similar to typing the information in the run dialog box of the Windows Start menu. The used c# code for this is in the following:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Windows;
   6: using System.Windows.Media;
   7: using System.Windows.Controls;
   8: using System.Windows.Media.Imaging;
   9: using System.Windows.Shapes;
  10: using System.IO;
  11:  
  12: namespace SnapShotUsingMediaPlayer
  13: {
  14:     public class MediaPlayerControl : ContentControl
  15:     {      
  16:         MediaPlayer _MediaPlayer;
  17:         private Uri _Source = null;
  18:         public Uri Source
  19:         {
  20:             get { return _Source; }
  21:             set
  22:             {
  23:                 _Source = value;
  24:                 Play(value);
  25:             }
  26:         }
  27:  
  28:         public void Play(Uri source)
  29:         {
  30:             if (_MediaPlayer == null)
  31:             {
  32:                 _MediaPlayer = new MediaPlayer();
  33:  
  34:             }
  35:             _MediaPlayer.MediaFailed += new EventHandler<ExceptionEventArgs>(_MediaPlayer_MediaFailed);           
  36:             _MediaPlayer.MediaOpened += new EventHandler(_MediaPlayer_MediaOpened);
  37:             _MediaPlayer.Open(source);     
  38:         }
  39:  
  40:         void _MediaPlayer_MediaOpened(object sender, EventArgs e)
  41:         {
  42:             System.Threading.Thread.Sleep(1000);
  43:             VideoDrawing videoDrawing = new VideoDrawing();
  44:             videoDrawing.Player = _MediaPlayer;
  45:             videoDrawing.Rect = new Rect(0, 0, _MediaPlayer.NaturalVideoWidth, _MediaPlayer.NaturalVideoHeight);
  46:             Rectangle rectangle = new Rectangle();
  47:             rectangle.Height = this.Height;
  48:             rectangle.Width = this.Width;
  49:             Brush brush = new DrawingBrush(videoDrawing);
  50:             rectangle.Fill = brush;
  51:             this.Content = rectangle;
  52:             _MediaPlayer.Play();           
  53:         }
  54:  
  55:         void _MediaPlayer_MediaFailed(object sender, ExceptionEventArgs e)
  56:         {
  57:             MessageBox.Show("Invalid File");
  58:         }
  59:  
  60:         public string Takesnapshot()
  61:         {            
  62:             RenderTargetBitmap renderBitmap = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Pbgra32);
  63:             renderBitmap.Render(this);
  64:             string filename = "Temp" + ".gif";
  65:             FileStream fs = new FileStream(filename, FileMode.Create);
  66:             BitmapEncoder encoder = new GifBitmapEncoder();
  67:             encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
  68:             encoder.Save(fs);
  69:             fs.Close();
  70:             return filename;
  71:         }
  72:     }
  73: }

VideoDrawing draws video to the specified rectangle. Here we have used fixed size rectangle with size 300*300 to show the video from VideoDrawing. We have made drawing brush from video drwaing and used this video drwaing to fill the rectangle. As we have not made VideoDrawing freeze, so it will change its content with time when media player is playing. RenderTargetBitmap Class is used to convert the video container element into a bitmap. Then GifBitmapEncoder is used to encode the bitmap into gif format and then the gif file is saved as temp.gif.

The used XAML for this is in the following:

   1: <Window x:Class="SnapShotUsingMediaPlayer.Window1"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:         xmlns:local ="clr-namespace:SnapShotUsingMediaPlayer"
   5:     Title="Window1" Height="500" Width="500">
   6:     <StackPanel>
   7:         <Button FontSize="20"  Margin="0,5,0,0"  HorizontalAlignment="Center" Width="Auto" Name="btnOpenFile" Click="btnOpenFile_Click"  Content="Open Video File"/>
   8:         <Border BorderThickness="2" Margin="0,10,0,0" Height="300" Width="300" BorderBrush="Black">
   9:             <local:MediaPlayerControl x:Name="player" Background="Black"  Width="300" Height="300"  />
  10:             </Border>
  11:         <StackPanel Margin="0,5,0,0"  Orientation="Horizontal" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center" >
  12:             <Button FontSize="20" Name="btnTakeSnapShot" Click="btnTakeSnapShot_Click"  Content="Take SnapShot"/>
  13:         </StackPanel>
  14:     </StackPanel>
  15: </Window>

You can download the sample code from here. Hope this will save some of your time.

Internationalization in the web service method of Asp.net

Asp.net internationalization facilitates to adapt an asp.net web site to different languages and regional differences. If we use browser’s language/ culture for internationalization, we only need to set the following line in web.config under system.web : <globalization culture="auto" uiCulture="auto" enableClientBasedCulture="true"/>.

If we use user-preferred language/ culture for internationalization, we have to do more work. As we know, to support Internationalization in an asp.net page, we can override InitializeCulture method. In the override InitializeCulture method, we can change both the Culture and UI culture. However, in the web service method call of asp.net, asp.net does not provide any functionality to override this method or this type of functionality. Another point is we can change the both culture and UI culture when the web service method is invoked but it does not have an effect on the internationalization.

As we know, on every web service call or asp.net page request, BeginRequest event of global.asax is fired before any specific processing. If we change the Culture and UIculture of current thread in the BeginRequest event of global.asax, it affects the Internationalization both in web service method and asp.net page and we can get the desired result. We can write the following code to implement so in global.asax:

   1: void Application_BeginRequest(Object Sender, EventArgs e)
   2:   {
   3:       string culture= string.Empty;
   4:       if (HttpContext.Current.Request.Cookies["language"] != null)
   5:       {
   6:           culture = Request.Cookies.Get("language").Value.ToString();
   7:       }
   8:       else
   9:       {
  10:           culture = "en-US";
  11:       }
  12:       System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(culture);
  13:       System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(culture);
  14:   }

Changing the CurrentCulture of current thread based on the cookie value will change the number formats, date format according to user-selected culture. As we know, a new resource file is created for each language/culture that the website supports. Then culture wise strings are retrieved by name. Changing the CurrentUICulture of current thread based on the cookie value will select proper resource file according to user-selected culture.

Now the question is how we can get the current culture to set in the BeginRequest event of global.asax. A cookie is a small text that associated with every http request for a particular domain. We can set cookie from both the server side and client side. In the client side, we can keep the culture setting in cookie using JavaScript code and retrieve it from the request object in the BeginRequest event of global.asax. Moreover, When BeginRequest method is invoked, the session object is not initialized that time for this request. Therefore, we cannot keep the culture setting in the session. In client side, you can set the cookie using the following Jquery code: $.cookie('language', prefLanguage). In server side, you can use the following code to set the cookie:

   1: System.Web.HttpCookie aCookie = new System.Web.HttpCookie("language");
   2: aCookie.Value = prefLanguage.ToString();
   3: System.Web.HttpContext.Current.Response.Cookies.Add(aCookie);  

Hope this will save some of your time.

Implementation of Auto Logoff based on User Inactivity in WPF Application

In some applications, we need to implement Auto logoff feature for security reason. In auto log off feature, the application redirects the user into login window, if the user remains inactive for a certain amount of time. I have just published how I came up with implementing auto logoff feature based on user inactivity in WPF application.

Here it is:

http://www.codeproject.com/KB/WPF/AutologoffWPF.aspx

Posted: Oct 09 2009, 01:04 PM by RazanPaul | with 2 comment(s)
Filed under:
More Posts Next page »