In some projects there was a need to run code on the client machine for interaction with SharePoint. If’ve realized this kind of applications as “ClickOnce” apps. It’s possible to deploy them as “SharePoint Solution Package”. If you do so the ClickOnce files can be deployed to every WFE. Updating the ClickOnce is easy.
Here I want to show you how to deploy a ClickOnce app als SharePoint Solution.
Let’s start.
1. Create your ClickOnce app. – If you have an existing one skip to step 5. – Otherwise continue reading. I’ll show you how to create a very simply ClickOnce.
Open Visual Studio 2010. Create a new project of type “Windows Forms Application” or “WPF Application”. I’ll use the first one and name the project “MyClickOnce”.
Design you app. – I drag 2 Label controls, 2 Checkbox controls and 2 Textbox controls to the surface. I do not change their names but their fonts
In my app I’d like to show the “running context”: locally started EXE or online started ClickOnce. Furthermore I’d like to show the URL if started online.
2. Open the Code view of the form.
First of all you need to add a assembly reference for “System.Web”!
Then insert this code. Maybe you need to correct the name of the controls.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Deployment.Application;
using System.Web;
namespace MyClickonce
{
public partial class Form1 : Form {
public Form1()
{
InitializeComponent();
ParseParams();
checkBox1.Checked = !IsOnline;
checkBox2.Checked = IsOnline;
textBox1.Text = Url;
textBox2.Text = Parameters["Param1"];
}
private bool _isOnline = false;
private NameValueCollection parameters = null;
private string _url = "";
public bool IsOnline
{
get {
return _isOnline;
}
}
public string Url
{
get {
return _url;
}
}
public NameValueCollection Parameters
{
get {
return parameters;
}
}
private void ParseParams()
{
NameValueCollection nameValueTable = new NameValueCollection();
if( ApplicationDeployment.IsNetworkDeployed )
{
_isOnline = true;
_url = ApplicationDeployment.CurrentDeployment.ActivationUri.ToString();
string queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
parameters = HttpUtility.ParseQueryString(queryString);
}
else {
_isOnline = false;
parameters = HttpUtility.ParseQueryString(string.Join("&", Environment.GetCommandLineArgs()));
}
}
}
}
The method “ParseParams” will be useful while developing the app and later running the app: This method is able to parse both “command line parameter” sources: URL and native (EXE). During development you maybe need to pass parameters to the app for testing purpose. Than you define this parameters in the “Debug” tab of the project properties.
Here is a screenshot of the app’s debug settings:
You see there is a parameter “Param1” follwed by “=” and it’s value. This is similar to URL style query string parameters. But you do not separate them with “&”! Instead use a single whitespace. – Later in the URL you will use “&” as normal!
Now just run the app!
Nice, isn’t it?
3. Now you need to configure the application to become a ClickOnce.
Open the Project Properties of your Windows Form App project.
Select the “Signing” tab and create a self signed certificate. Or use a valid Code Signature certificate.
Now switch to the “Publish” tab of the project settings.
Here you can change the settings as you need it. – I’ll leave it as is EXCEPT one setting: Click the “Options…” button and select “Manifests”. Check “Allow URL parameters to be passed to application”:
[If you do not set this the app will fail in the following line because “ActivationUri” will be null: “_url = ApplicationDeployment.CurrentDeployment.ActivationUri.ToString(); “]
The other settings:
Click “Publish Now”.
Than the project will be build and stored to the sub folder “Publish” of your project folder in the file system.
4. If you now try to run the app locally you may get this error:
This is caused by your ClickOnce publishing in the step before.
The resolve this open the project settings, select the “Security” tab and clear the checkbox “Enable Clickonce security settings”:
This you need to do after each ClickOnce publishing!
5. Now we create the SharePoint Solution Package.
In the Solution Explorer click on the solution item, click “Add” and click “New project”.
Now chooce “Empty SharePoint Project” and name it “MyClickonceDeployment”.
As local site I use “http://sharepoint.local/sites/clickonce”. It has to be a “Farm Solution”!!
Now create a “Module” project item. Name it “MyClickonce”.
Remove the file “Sample.txt”
6. Now open the solutions path in Windows Explorer.
Go into the folder of the Windows Forms Application. There go into the “Publish” folder.
Select the “.application” file of your ClickOnce app and select the “Application Files” folder. This items you need to copy. Just select “Copy” from the context menu or press Ctrl+C.
No open the folder of “MyClickonceDeployment” and go into the folder “MyClickonce”. There insert (paste) the selected items.
Now you folder should look like this:
In the “Application Files” folder you’ll see another folder “1_0_0_0” or with another version number. This version number will be increased by every ClickOnce publishing if you did not disable this function.
7. Back in the Visual Studio go into the Solution Explorer and click this icon:
This will show you all files in the project folder, not even project items.
Select the “MyClickonce” module project item. Maybe you need to click the icon:
You should see this:
Right click on “MyClickonce.application” and select “Include in project”. Right click on “MyClickonce_1_0_0_0” and select “Include in project”.
Now you need to edit the “Elements.xml” file of you module project item.
First of all add an attribute named “Path” to the “Module” tag. This will define the URL of your ClickOnce app. Select a unique name so that the solution won’t get in conflict with other solutions. You could choose a GUID here or use date and time:
Now you can remove the string “MyClickonce/” of the beginning of every “Path” attribute of the child nodes of the “Module” tag.
After removing the string the file should have this content:
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Module Name="MyClickonce" Url="MyClickonce20110815152200"> <File Path="MyClickonceMyClickonce.application" Url="MyClickonce.application" /> <File Path="MyClickonceApplication FilesMyClickonce_1_0_0_0MyClickonce.application" Url="Application Files/MyClickonce_1_0_0_0/MyClickonce.application" /> <File Path="MyClickonceApplication FilesMyClickonce_1_0_0_0MyClickonce.exe.deploy" Url="Application Files/MyClickonce_1_0_0_0/MyClickonce.exe.deploy" /> <File Path="MyClickonceApplication FilesMyClickonce_1_0_0_0MyClickonce.exe.manifest" Url="Application Files/MyClickonce_1_0_0_0/MyClickonce.exe.manifest" /> </Module> </Elements>
8. Now deploy your SharePoint Solution Package!
9. To verify the ClickOnce was deployed correctly just open the site with SharePoint Designer 2010.
Open SPD.
Click “All Files”.
Now you should find your folder “MyClickonce20110815152200”.
9. Open the SharePoint site you deployed to.
Enter the complete URL of the ClickOnce app in the address bar of the browser. In my case the URL is:
http://sharepoint.local/sites/Clickonce/MyClickonce20110815152200/MyClickonce.application
Open the URL.
The ClickOnce should start after some seconds. During installation or update you’ll see these windows:
It will look like this:
10. Now lets add a Quicklaunch entry for this:
In the link I’ve used “Param1”: http://sharepoint.local/sites/Clickonce/MyClickonce20110815152200/MyClickonce.application?Param1=Hey, Ingo!
Just click the Quicklaunch entry.
You’ll get:
That’s it. – Please let me know if it worked for you!
Of course you could build query strings in JavaScript to pass dynamically generated parameters to the ClickOnce!! This is charming and makes ClickOnce apps to become usefull in SharePoint development. You could create custom Ribbon menu items and call a ClickOnce app on click. As parameters you could pass ListID, Web URL, ItemID, … to the app! Very cool!
Have fun! – Please post your comments on this!