SharePoint Copy Webservice

Pho3nix

The Legend
Joined
Jul 31, 2009
Messages
32,825
Reaction score
3,033
Location
On the toilet
I'm looking to upload a file from a clients local pc onto the SharePoint site using this webservice via a windows form application but I haven't found a workable example on the net as of yet.
Tried a number of varying examples but nothing :( Anyone have some experience using this?
 
I'm looking to upload a file from a clients local pc onto the SharePoint site using this webservice via a windows form application but I haven't found a workable example on the net as of yet.
Tried a number of varying examples but nothing :( Anyone have some experience using this?

I guess you are using REST or SOAP? I've not had the honor to play around with this yet :o
 
I'm looking to upload a file from a clients local pc onto the SharePoint site using this webservice via a windows form application but I haven't found a workable example on the net as of yet.
Tried a number of varying examples but nothing :( Anyone have some experience using this?

What web service?
What form application?
 
Code:
        private void btnUpload_Click_1(object sender, EventArgs e)
        {
            System.IO.File.Copy(strFileName, strUploadTo);

            string SaveDOBFile = Application.StartupPath;
            string strFullFilePath = (strName + ".bob");
            SaveDOBFile = Path.Combine(SaveDOBFile, strFullFilePath);
            using (FileStream testStream = System.IO.File.Open(SaveDOBFile, FileMode.Create))
            using (BinaryWriter bwrite = new BinaryWriter(testStream))
            {
                bwrite.Write(strUploadTo);
                
            }
            ClientContext context = new ClientContext("http://site2010");
            using (FileStream fs = new FileStream(@SaveDOBFile, FileMode.Open))
            {
                string strUploadURL = (("/Test%20Library/") + strFileName);
                Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, strUploadURL, fs, true);
            }
            MessageBox.Show("File has been successfully copied over");
        }

    }

Using the Client OM this seems to build. Will test and report back. Don't know why I went with the Web Service :o and the error i kept getting was the web service wasnt been referenced correctly for some reason :\.

Ok this works :) now to my next connundrum. Please see the post below.
 
Last edited:
Code:
[STAThread]
        static void Main(string[] args)
        {
            string p = args[0];
            FileStream readStream ;
            string e = Path.GetExtension(p);
            if (e == ".bob")
            {
                    readStream = new FileStream(p, FileMode.Open);
                    BinaryReader readBinary = new BinaryReader(readStream);
                    string FilePath = readBinary.ReadString();
                    //MessageBox.Show(msg);
                    Process.Start(FilePath);
                    readStream.Close();
            }
            else
            {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
            
            }

Did I miss something here? The application is supposed to open the target file's default application if a file with the extention .bob is opened but doesn't. And when this doesnt happen the application should just open.. Thoughts?
 
Did I miss something here? The application is supposed to open the target file's default application if a file with the extention .bob is opened but doesn't. And when this doesnt happen the application should just open.. Thoughts?

Yea the Client OM is friggin awesome! :D

What is it doing at the moment?

Also, if the extension is .bob, why do you open the file and use the text inside the file as the filepath, why not use the file path passed as an argument?

EDIT: Sorry that's a bit confusing... what I'm saying is, why not use "Process.Start(p);" instead of "Process.Start(FilePath);". Unless I'm not understanding this correctly.
 
Last edited:
No your getting it right, used FilePath because the file being opened is a Shortcut for lack of a better word and a mix-masala way of getting around the SP 2Gb upload limit, what happens is I move a file to a file-share drive and the .bob file has the filepath uploaded onto sharepoint. Now when a user wants to use said file, they click on the file and the filepath kept inside the .bob file is passed and the file is accessed from the fileshare and opened using the default viewer.

Hope this makes sense :\

As too whats it's doing, during debugging unless set the command line argument to a existing .bob file I get Error : Index was outside the bounds of the array. on the line below
Code:
string p = args[0]
 
Last edited:
Ah k... cool solution.

So to get past the IndexOutOfBounds exception, structure the code something like this:

Code:
[STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if(args.Length > 0)
            {
                string p = args[0];
                FileStream readStream ;
                string e = Path.GetExtension(p);
                if (e == ".bob")
                {
                    readStream = new FileStream(p, FileMode.Open);
                    BinaryReader readBinary = new BinaryReader(readStream);
                    string FilePath = readBinary.ReadString();
                    //MessageBox.Show(msg);
                    Process.Start(FilePath);
                    readStream.Close();
                }
                else
                {                    
                    Application.Run(new Form1());            
                }
            }
            else
            {
                Application.Run(new Form1());
            }
        }

So when you do pass a valid path, does it work?
 
Thanks Frikkenator, that got it working :) and yes, when I did pass a valid path if worked. Now to continue testing..anyone have a 50gb file lying around??
 
Will try speak to the DB Managers to lend me one lol :) Was wondering if anyone here had also added a custom action that can open the application using a new custom button on the Ribbon menu.
 
Will try speak to the DB Managers to lend me one lol :) Was wondering if anyone here had also added a custom action that can open the application using a new custom button on the Ribbon menu.

I have done a custom ribbon button, but not to launch an external application though. It seems possible though, all you have to do is have your application's installer add a registry entry.

Have a look at this to add the button:
http://msdn.microsoft.com/en-us/library/ff630938.aspx

And this to have it launch your application:
http://sharepoint.stackexchange.com...nch-local-application-exe-from-ribbon-control
 
Code:
private void btnUpload_Click_1(object sender, EventArgs e)
        {
            #region CopyCode

            FileInfo sourceFile = new FileInfo(strFileName);
            long fileLen = sourceFile.Length;

            int buffer = DefineCache();
            byte[] buf = new byte[buffer];
            long totalBytesRead = 0;
            double pctDone = 0;
            string msgs = "";
            int numRead = 0;
            using (FileStream sourceStream = new FileStream(strFileName, FileMode.Open))
            {
                using (FileStream destStream = new FileStream(strUploadTo, FileMode.CreateNew))
                {
                    while (true)
                    {
                        numRead++;
                        int bytesRead = sourceStream.Read(buf, 0, buffer);
                        if (bytesRead == 0) break;
                        destStream.Write(buf, 0, bytesRead);

                        totalBytesRead += bytesRead;
                        if (bytesRead < buffer) break;
                    }
                }
            }
            #endregion

            #region SaveToSharPoint
            string SaveDOBFile = Application.StartupPath;
            string strFullFilePath = (strName + ".bob");
            SaveDOBFile = Path.Combine(SaveDOBFile, strFullFilePath);
            using (FileStream testStream = System.IO.File.Open(SaveDOBFile, FileMode.Create))
            using (BinaryWriter bwrite = new BinaryWriter(testStream))
            {
                bwrite.Write(strUploadTo);
                
            }
            ClientContext context = new ClientContext("http://kamo-pc");
            using (FileStream fs = new FileStream(@SaveDOBFile, FileMode.Open))
            {
                string strUploadURL = (("Test%20Library") + strFullFilePath);
                Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, strUploadURL, fs, true);
            }
            MessageBox.Show("File has been successfully copied over");
            #endregion

Kinda need help with a progress bar for the application aswell :o, help ?
 
Okay before you get to progress bars and all the little nice to haves, there is something to consider first. The way your're copying the file now, will read the entire file into memory and then save it, which means that a big file will most likely cause the PC to run out of memory.

What you rather want to do is have windows manage the copying of the file, with something like:
Code:
System.IO.File.Copy(sourceFileName, destFileName);

Doing that however will not give you progress feedback.

To show progress on your form's UI, you need to run the copy process in a different thread than the UI thread, otherwise the UI will lock up while processing the file.

So I've found an example of a copy method that implements a BackgroundWorker thread witch shows progress in a progress bar. See the answer to this question: http://social.msdn.microsoft.com/Fo.../thread/a285bdb9-6838-48f3-b8ed-1bf0156f8c51/

Alternatively, Visual Basic has got some methods of doing this with much less code, and it can be used in C#, see the example here: http://msdn.microsoft.com/en-us/library/cc165446.aspx

Lemme know how it goes!
 
I thought about that and that why I'm buffering the the bytes instead of keeping everything in memory.. Tried using
Code:
System.IO.File.Copy(sourceFileName, destFileName);
but my system hangs as soon as I try move a file over 20gb's (have 16gb of RAM, maybe 2-3GB's is available as I run SP and SQL on the laptop). Using the method above with a buffer of 1MB it works and transfers a 25gbs file in 20min..

Shouldn't this work :? Will look into the backgroundworker thread in the interim.
 
Hmmm, interesting!

If it works well then leave it like that, all you'll have to do, is run your code in a BackgroundWorker, and use callbacks to get the progress back to your main thread.

Good tutorial found here: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

Most important bit is setting up the event handlers:
Code:
bw.DoWork += 
    new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += 
    new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

Then when copying starts, set the progressbar's Maximum to the file size (use System.IO.File to get filesize, in MB). then in your ProgressChanged event, pass back the number of copied bytes devided by 1048576 (to get MB), and set that as the progress bar's value in your UI thread's handler (ProgressChangedEventHandler).
 
Tried it a different way. Set the maximub to the Files Length.
Code:
progBar.Maximum = (int)fileLen;
then added
Code:
progBar.Value = (int)totalBytesRead;
to
Code:
using (FileStream sourceStream = new FileStream(strFileName, FileMode.Open))
            {
                using (FileStream destStream = new FileStream(strUploadTo, FileMode.CreateNew))
                {
                    while (true)
                    {
                        numRead++;
                        int bytesRead = sourceStream.Read(buf, 0, buffer);
                        if (bytesRead == 0) break;
                        destStream.Write(buf, 0, bytesRead);
                        totalBytesRead += bytesRead;
                        progBar.Value = (int)totalBytesRead;
                        if (bytesRead < buffer) break;
                    }
                }
 
Last edited:
Tried it a different way. Set the maximub to the Files Length.
Code:
progBar.Maximum = (int)fileLen;
then added
Code:
progBar.Value = (int)totalBytesRead;
to
Code:
using (FileStream sourceStream = new FileStream(strFileName, FileMode.Open))
            {
                using (FileStream destStream = new FileStream(strUploadTo, FileMode.CreateNew))
                {
                    while (true)
                    {
                        numRead++;
                        int bytesRead = sourceStream.Read(buf, 0, buffer);
                        if (bytesRead == 0) break;
                        destStream.Write(buf, 0, bytesRead);
                        totalBytesRead += bytesRead;
                        progBar.Value = (int)totalBytesRead;
                        if (bytesRead < buffer) break;
                    }
                }

Which seems to be working. Didn't add the background process which I know isn't best-practice but this is POC work for the most part. Will update when/if I figure out how to add the custom button actions.

Thanks for the help once again Frikkenator :)

If it's POC then whatever works, works! :D

No a problem, quite a clever solution you came up with there!
 
Top
Sign up to the MyBroadband newsletter
X