Tuesday, February 19, 2013

Calling Winform function from SharePoint page.

Consider a scenario like passing a value from SharePoint page(ex. document library URL) or something to a windows form application function and execute a code based on the value passed. Web page and windows form may seem like two completely non-linked entities. But there is a way to establish connection to and fro.
 
Below are the steps to call a windows form function from a SharePoint page. 

1. Create a Win formand add a webbrowser control. Give the SharePoint site URL as the webbrowser control URL property.

2. Inside the Win formadd the ComVisibleAttribute to the class level.

 [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public partial class Save : System.Windows.Forms.Form
    {}

3. Add the ObjectForScripting property. This will act as a interface between the webpage and Win form

        [BrowsableAttribute(false)]
        public Object ObjectForScripting { get; set; }


4.  Add a function in Win form with a parameter just for test purpose. We will call this function from the SharePoint page.


        public void Test(String docurl)
        {
          MessageBox.Show(docurl);
        }

5. Now in the SharePoint page in the aspx page(if its an application page) call the Winform function by calling the below javascript code.

window.external.Test('url');

This will call the parent WinForm function and popup the message box.

6. To call this in .cs file code register with client script like below

this.Page.ClientScript.RegisterStartupScript(this.GetType(), "opendoc", "window.external.Test('" + locationpath + "/" + docname.Text);", true);


Tuesday, January 8, 2013

File not found exception in Office 2010 addin / ClientContext Code not executing

When we add any reference dlls(say in the example Microsoft.SharePoint.Client dll)  in Office 2010 addin and package it using Click once and install it in client machine it gives an


System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.SharePoint.Client, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.

File name: 'Microsoft.SharePoint.Client, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'

   at WordAddIn1.Form1.UploadDocument(Byte[] docbytes)

   at WordAddIn1.Form1.button1_Click(Object sender, EventArgs e)



Assembly manager loaded from:  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll

Running under executable  C:\PROGRA~1\MICROS~2\Office14\WINWORD.EXE

Fix:


Add the reference dlls in the root of the project like below and publish again. This took me a day to figure out :(.

There were no good article to debug and fix this issue in msdn forums so thought this might be useful to someone

Upload a word document from Office 2010 plugin to SharePoint Doc library

When we create a Office 2010 addin  say for word and try to access SharePoint resources from it we know pretty much better option is 'Client Object model'.

1. Create a new Word 2010 addin and a button called 'Save'
2. Include a win form and add a button called "Upload doc"
3. Call this form on click of Save button.

4 Below code is to upload a current open word document in Office 2010 to a SharePoint site without saving locally on click of Upload Doc button.



 public void UploadDocument(byte[] docbytes)
        {

            ClientContext clientContext = new ClientContext("http://sharepointsiteurl/");

            List documentsList = clientContext.Web.Lists.GetByTitle("Events");

            var fileCreationInformation = new FileCreationInformation();

            fileCreationInformation.Content = docbytes;

            fileCreationInformation.Overwrite = true;

            fileCreationInformation.Url = "http://sharepointdoclibrarylocation/la.doc";
            Microsoft.SharePoint.Client.File uploadFile = documentsList.RootFolder.Files.Add(fileCreationInformation);
            uploadFile.ListItemAllFields.Update();
            clientContext.ExecuteQuery();
}

and on button click below code grabs the current document content as byte array and calls the above function to upload it to SharePoint

 private void button1_Click(object sender, EventArgs e)
        {

            Microsoft.Office.Interop.Word.Document doc = Globals.ThisAddIn.Application.ActiveDocument;

            doc.ActiveWindow.Selection.WholeStory();
            doc.ActiveWindow.Selection.Copy();

            IDataObject data = Clipboard.GetDataObject();

            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data.GetData(DataFormats.Html).ToString());


            MessageBox.Show("Before Upload");
            try
            {
                UploadDocument(bytes);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());

            }
            MessageBox.Show("Uploaded to SharePoint Successfully");

        }

The difference from other solutions  is here we dont save the document anywhere locally instead directly grabbing the content as byte array and uploading it to SharePoint doc library which will improve the performance drastically.