Check for appplication updates programmatically using ClickOnce Deployment

By default, ClickOnce provides two ways to update the application after installed in the client.

  1. Check everytime when the customization runs
  2. Check at regular intevals
ClickOnce Deployment Update Options

Default update types in ClickOnce Deployment

With the above, the user has to wait till it completes checking for the updates every time when the customization is loaded or at some time interval. It will be a waste of time for the users if application does not  update builds frequently.

How it would be if we provide a button for checking for updates when the user wish to do?

Hmm… Do you think that this is a headache process and hard to implement?

But, NO!

Here are the quick and simple steps to do this.

  1. Create a Windows Forms Application
  2. Place a button and call the following code. (It will check for updates and install them for you when the button is clicked)
Private Sub InstallUpdateSyncWithInfo()
    Dim info As UpdateCheckInfo = Nothing

    If (ApplicationDeployment.IsNetworkDeployed) Then
        Dim AD As ApplicationDeployment = ApplicationDeployment.CurrentDeployment

        Try
            info = AD.CheckForDetailedUpdate()
        Catch dde As DeploymentDownloadException
            MessageBox.Show("The new version of the application cannot be downloaded at this time. " + _
                                       ControlChars.Lf & ControlChars.Lf & "Please check your network" + _
                                       "connection, or try again later. Error: " + dde.Message)
            Return
        Catch ioe As InvalidOperationException
            MessageBox.Show("This application cannot be updated. It is likely not a ClickOnce application." + _
                                      "Error: " & ioe.Message)
            Return
        End Try

        If (info.UpdateAvailable) Then
            Dim doUpdate As Boolean = True

            If (Not info.IsUpdateRequired) Then
                Dim dr As DialogResult = MessageBox.Show("An update is available. Would you like to " + _ 
                                                 "update the application now?", "Update Available", 
                                                 MessageBoxButtons.OKCancel)
                If (Not System.Windows.Forms.DialogResult.OK = dr) Then
                    doUpdate = False
                End If
            Else
                ' Display a message that the app MUST reboot. Display the minimum required version.
                MessageBox.Show("This application has detected a mandatory update from your current " & _
                    "version to version " & info.MinimumRequiredVersion.ToString() & _
                    ". The application will now install the update and restart.", _
                    "Update Available", MessageBoxButtons.OK, _
                    MessageBoxIcon.Information)
            End If

            If (doUpdate) Then
                Try
                    AD.Update()
                    MessageBox.Show("The application has been upgraded, and will now restart.")
                    Application.Restart()
                Catch dde As DeploymentDownloadException
                    MessageBox.Show("Cannot install the latest version of the application. " & ControlChars.Lf 
                                              & ControlChars.Lf & "Please check your network connection," + _ 
                                               " or try again later.")
                    Return
                End Try
            End If
        End If
        End If
End Sub

Now say, Ain’t this cool? 🙂

Reference: http://msdn.microsoft.com/en-us/library/ms404263.aspx

Hope this helps!

intereSTRINGS

‘inetreStrings’ – liked the nomenclature and the sense of humor of the author of it very much.

String vs string
Lower case string is simply an alias for System.String in the .NET Framework.

== or .Equals
A rule of thumb is that for almost all reference types e.g. objects, use Equals when you want to test equality. == compares whether two references (i.e. object instances) refer to the same object.
Primitive types can be compared for equality using ==, but in the case of strings, the variables on each side of the operators must be of type string.

Have a look at the following code and output, taken from Jon Skeet’s blog.

01    using  System;
02    
03    public class Test
04    {
05    static void Main()
06    {
07    // Create two equal but distinct strings
08    string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
09    string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
10    
11    Console.WriteLine (a==b);
12    Console.WriteLine (a.Equals(b));
13    
14    // Now let's see what happens with the same tests but
15    // with variables of type object
16    object c = a;
17    object d = b;
18    
19    Console.WriteLine (c==d);
20    Console.WriteLine (c.Equals(d));
21    }
22    }
23    The results are:
24    
25    True
26    True
27    False
28    True

@ before a string
Using @ before a string means the escape sequences are not processed. This making it easier to write fully qualified path names for example.
@”c:\Docs\Source\a.txt” // rather than “c:\\Docs\\Source\\a.txt”

Stringbuilder
String objects are immutable, and so editing them, using Replace for example, results in a entirely new string being created, with new memory allocation. The original string is left intact in memory.
The StringBuilder class is designed for situations when one needs to work with a single string and make an arbitrary number of iterative changes to it. New memory allocation is not needed.

Came across the above on Bishop’s Blog while searching about something related to VSTO.

Importing an EML File into Outlook

I am trying to create a mail item in Outlook with old date and time, which looks some thing like an Inbox Mail Item which arrived long back. After some painful hours of searching and reading forums, 3rd party libraries, somehow, I got a solution to do this and would like to share it with you here.

Here you go!

Sub CreateMailFromEML()

Dim objPost As Outlook.PostItem
Dim objSafePost As Redemption.SafePostItem
Dim objNS As Outlook.NameSpace
Dim objInbox As Outlook.MAPIFolder
Const PR_ICON_INDEX = &H10800003

Try

objNS = Application.GetNamespace(“MAPI”)
objInbox = objNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
objPost = objInbox.Items.Add(Outlook.OlItemType.olPostItem)
objSafePost = CreateObject(“Redemption.SafePostItem”)
objPost.Save()
objSafePost.Item = objPost
objSafePost.Import(“c:\SampleEml.eml”, RedemptionSaveAsType.olRFC822)
objSafePost.MessageClass = “IPM.Note”
‘ remove IPM.Post icon
objSafePost.Fields(PR_ICON_INDEX) = String.Empty
objSafePost.Save()

Catch ex As Exception

MessageBox.Show(“Error: ” & ex.ToString)

Finally

objSafePost = Nothing
objPost = Nothing
objInbox = Nothing
objNS = Nothing

End Try

End Sub

Notes:

  • We have to create an instance of Outlook.PostItem instead of Outlook.MailItem.
  • We can also do it using RDOMail which is much simpler than this. (I will discuss about this in separate post).

I have created the mail item with old date time stamps, attachments successfully. But, couldn’t reset the icon of the PostItem that is created. Searching for a solution to it . Will update it in this post once I got that.

Uploading files using .NET as client and PHP as Server

I was fed up with uploading the attachments using FTP as it was too slow (and vulnerable too), maintaining credentials to connect to server, managing permissions to specific folder etc. and all that nasty stuff.  Clients have also complained on this. After head-scratching and wall banging efforts, I planned to search for an alternative for FTP to upload the files. Found this way… Its pretty cool and uploading files much faster compared to FTP approach. Just wanted to share it with you, hoping that it may help someone who are in need!

This is a small tutorial which will teach you how to upload files using a C# client application to a server running PHP.

We’ll call the PHP Script “upload.php”, this is what it should contain:

<?php
$uploaddir = ‘upload/’; // Relative Upload Location of data file
if (is_uploaded_file($_FILES[‘file’][‘tmp_name’]))
{
$uploadfile = $uploaddir . basename($_FILES[‘file’][‘name’]);
echo “File “. $_FILES[‘file’][‘name’] .” uploaded successfully. “;
if (move_uploaded_file($_FILES[‘file’][‘tmp_name’], $uploadfile))
{
echo “File is valid, and was successfully moved. “;
}

else
print_r($_FILES);
}
else
{
echo “Upload Failed!!!”;
print_r($_FILES);
}
?>

and here is the C# code…

System.Net.WebClient Client = new System.Net.WebClient ();
Client.Headers.Add(“Content-Type”,”binary/octet-stream”);
byte[] result = Client.UploadFile (“http://your_server/upload.php&#8221;,”POST”,”C:\test.jpg”);
String s = System.Text.Encoding .UTF8 .GetString (result,0,result.Length );

In the C# part, replace “your_server.com” with your server, also notice that this is a test code, it will upload c:\\test.jpg, because I am testing with an image file, I am using the header “binary/octet-stream” as it works with all files (image, txt, etc)…

Hope this helps someone out there as I couldn’t find any tutorials about this specific matter on googling!

Opening default web browser from Windows Application

This post deals with opening default web browser from a .NET Application (esp. a Windows Application).

First, copy the following code and paste it in your class.

Private Declare Function ShellExecute _
                            Lib "shell32.dll" _
                            Alias "ShellExecuteA"( _
                            ByVal hwnd As Long, _
                            ByVal lpOperation As String, _
                            ByVal lpFile As String, _
                            ByVal lpParameters As String, _
                            ByVal lpDirectory As String, _
                            ByVal nShowCmd As Long) _
                            As Long

Then, you can use the function ShellExecute() as follows.

Private Sub Button1_Click()
   Dim objBrowser As Long
   objBrowser = ShellExecute(0, "open", "https://easyvsto.wordpress.com", 0, 0, 1)
End Sub

We can also open the default web browser as:

Process.Start("https://easyvsto.wordpress.com")

I usually create a Form and place a WebBrowser control in it and use it for opening any web pages. I will get back to you with that soon.

Microsoft reference for the topic, Click here

Enhanced FTP Code

Here is the enhanced version of the code which sends files to remote computer using FTP which I have posted long back!

Public Function CheckDir(ByVal FolderName As String, ByVal thePath As String) As Boolean
Dim sr As StreamReader = Nothing
Dim dirList() As String = Nothing
Try
Dim myFtpReq As FtpWebRequest = FtpWebRequest.Create(New Uri(thePath))
myFtpReq.Method = WebRequestMethods.Ftp.ListDirectory
myFtpReq.KeepAlive = False
myFtpReq.Proxy = Nothing
myFtpReq.UsePassive = True
myFtpReq.Credentials = New NetworkCredential(userName, paswd)
Dim myFtpResp As FtpWebResponse = CType(myFtpReq.GetResponse(), FtpWebResponse)
Dim ftpRespStream As Stream = myFtpResp.GetResponseStream()
sr = New StreamReader(ftpRespStream, System.Text.Encoding.Default)
Dim folderList As String = sr.ReadToEnd()
‘MsgBox(“Folder List: ” & folderList)
If Not folderList Is Nothing Or folderList <> “” Then
For Each theDir In folderList.Split(vbCrLf)
If theDir.Contains(“/”) Then
If FolderName = theDir.Split(“/”)(1) Then
‘MsgBox(FolderName & ” Folder exist “)
Return True
End If
End If
Next
End If
Return False
Catch ex As Exception
MessageBox.Show(“Error: ” & ex.Message & ” | ” & ex.StackTrace)
Return 0
Finally
If Not sr Is Nothing Then
sr.Close()
sr = Nothing
End If
End Try
End Function

Checking whether a program is running or not

While performing installation, sometimes, we need to check whether the instance of a particualr program exist or not.

I got this problem while installing my plug-in. Outlook should be closed before the installation starts. So, I need to check for the existance of Outlook before installation. After so many days and lot of efforts, finally I have got a solution for this.

While Process.GetProcessesByName(“Outlook”).Length > 0

MsgBox(“Notepad is open”)
End While

MsgBox(“Outlook is still open. Please close it”)

End While

This loop will iterate until the Outlook is closed.

We can also close a program forcibly using the following code.

Dim myProcesses() As Process

Dim instance As Process

myProcesses = Process.GetProcessesByName(“Outlook”)

For Each instance In myProcesses

instance.CloseMainWindow() ‘ This will close the application that is running

Next