Use Sharepoint Copy web service to copy folder and contents - c#

I am trying to make a program that copies all of a Sharepoint folder's contents (all subfolders and files) into another Sharepoint folder. Both of these folders will be on the same Sharepoint site.
However, I am trying to do this remotely - if possible*. Therefore, I have tried using the Copy web service without success. The Copy web service appears to only work with copying files, not folders. In addition, I cannot determine a way to iterate through the folder's contents to copy everything - it will only copy one item.
Thank you for any insights or tips,
Scott
*From a custom CRM workflow activity
~~Edited for clarification~~

In the end, I decided to create my own custom web service in Sharepoint that I was able to successfully access from Microsoft CRM. If anyone is interested, I've pasted the C# code I used to copy the folder structure:
public String CopyFolderContents(String sourceURL, String folderURL, String destinationURL)
{
try
{
#region Copying Code
//Get the SPSite and SPWeb from the sourceURL
using (SPWeb oWebsite = new SPSite(sourceURL).OpenWeb())
{
//Get the parent folder from the folderURL
SPFolder oFolder = oWebsite.GetFolder(folderURL);
//Create a list of all files (not folders) on the current level
SPFileCollection collFile = oFolder.Files;
//Copy all files on the current level to the target URL
foreach (SPFile oFile in collFile)
{
oFile.CopyTo(destinationURL + "/" + oFile.Name, true);
}
//Create a list of all folders on the current level
SPFolderCollection collFolder = oFolder.SubFolders;
//Copy each of the folders and all of their contents
String[] folderURLs = new String[collFolder.Count];
int i = 0;
foreach (SPFolder subFolder in collFolder)
{
folderURLs[i++] = subFolder.Url;
}
for (i = 0; i < folderURLs.Length; i++)
{
SPFolder folder = collFolder[folderURLs[i]];
folder.CopyTo(destinationURL + "/" + folder.Name);
}
}
#endregion Copying Code
}
catch (Exception e)
{
#region Exception Handling
String Message;
if (e.InnerException != null)
Message = "MESSAGE: " + e.Message + "\n\n" +
"INNER EXCEPTION: " + e.InnerException.Message + "\n\n" +
"STACK TRACE: " + e.StackTrace + "\n\n" +
"Source: " + sourceURL + "\n" +
"Folder: " + folderURL + "\n" +
"Destination: " + destinationURL;
else
Message = "MESSAGE: " + e.Message + "\n\n" +
"STACK TRACE: " + e.StackTrace + "\n\n" +
"Source: " + sourceURL + "\n" +
"Folder: " + folderURL + "\n" +
"Destination: " + destinationURL;
throw new Exception(Message);
#endregion Exception Handling
}
return "Operation Successful!";
}
All I did was add this method into a Sharepoint web service and called it from CRM and it works.
Thanks to everyone who provided other answers,
Scott

There is a simple solution to this problem , as its just about copy and paste use the simple XCOPY command
XCOPY Copy files and/or directory trees to another folder. XCOPY is similar to the COPY command except that it has additional switches to specify both the source and destination in detail.
To copy a folder including all subfolders
XCOPY C:\utils\* D:\Backup\utils /s /i
here /i defines the destination as a folder
for more detail please refer this link

Related

Enreco Video Rotation in Asp.Net Virtual Machine is not completing

I am developing an ASP.NET Web Api in which I need to concatenate some video clips and rotate them. I could achieve the same when I tried in my local system. When I deployed the same project to an Azure Virtual Machine I am not getting response. I am pretty sure that there isn't any issue till video concatenation because I could see the concatenated video in the expected folder. Here is the code snippet.
var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
NReco.VideoConverter.ConcatSettings set = new NReco.VideoConverter.ConcatSettings();
ffMpeg.GetVideoThumbnail(_fileNames[0], imageRootPath + tobename + ".jpg");
if (_fileNames.Count() > 1)
{
ffMpeg.ConcatMedia(_fileNames, videoRootPath + tobename + "_r.mp4", NReco.VideoConverter.Format.mp4, set);
string path = HttpContext.Current.Server.MapPath("~\\bin\\");
System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process();
ffmpeg.StartInfo.FileName = path + "\\" + "ffmpeg.exe";
ffmpeg.StartInfo.Arguments = "-i " + videoRootPath + tobename + "_r.mp4" + " -c copy -metadata:s:v:0 rotate=90 " + videoRootPath + tobename + ".mp4";
ffmpeg.Start();
ffmpeg.WaitForExit();
}
ffmpeg.ConcateMedia is working fine. I can't figure out why the External process that I have invoked does not complete. The same piece is working fine in my local Visual Studio.
Thank you in advance
It seems you are using Nreco VideoConvertor for joinging videos and external process to rotate the video.
You can always use Invoke method to write the custom commandline. something like this
ffMpeg.Invoke("-i " + videoRootPath + tobename + "_r.mp4" + " -c copy -metadata:s:v:0 rotate=90 " + videoRootPath + tobename + ".mp4");
Hope this Helps...
Your path ends with a slash, and when adding the paths together you also add a slash.
Use Path.Combine:
string path = HttpContext.Current.Server.MapPath("~\\bin");
ffmpeg.StartInfo.FileName = System.IO.Path.Combine(path, "ffmpeg.exe");

Copy file to remote location throws network path not found intermittently

I am trying to copy a file generated (Excel file) by my c# code into a remote network path to which I have access as below:
string folder = "\\\\testing-path\\Audit\\Reports";
if (!(Directory.Exists(folder + "\\" + DateTime.Now.ToString("MM-dd-yyyy") + "\\" + "Audit")))
{
Directory.CreateDirectory(folder + "\\" + DateTime.Now.ToString("MM-dd-yyyy") + "\\" + "Audit");
}
folder = folder + "\\" + DateTime.Now.ToString("MM-dd-yyyy") + "\\" + "Audit";
if (File.Exists(folder + "\\Audit- " + fname + ".xlsx"))
{
File.Delete(folder + "\\Audit- " + fname + ".xlsx");
}
string fileName = folder + "\\Audit- " + fname + ".xlsx";
wb.SaveAs(fileName,
Excel.XlFileFormat.xlWorkbookDefault, null, null,
false, false, Excel.XlSaveAsAccessMode.xlNoChange,
null, null, null, null, null);
This code works perfectly fine 8/10 times and throws network error (Network path not found) other 2 times. When the remote path throws this error I open the above remote path using run command on the machine I run this code and I am able to access it as normal. Closing the folder opened manually and re-running the code is solving the issue. What could be the issue? Am I doing something wrong here?
PS: I also tried to save the excel file onto desktop and then use File.Copy and there is no change to this intermittent behaviour.
Check the following things
1) First you have to check whether machine is on or off
2) Then check you have access rights to put the file in that particular folder and dont
put it inside ' C ' Drive because C is not accessible for other users in network put it inside D or E drive.
3) If Folder is Missing You have to Create A Folder first
and what is ' WB '
if(!Directory.Exists("\\\\testing-path\\Audit\\Reports"))
Directory.Create("\\\\testing-path\\Audit\\Reports");
Use
FilePath Byte
File.ReadAllBytes("FilePath/FileName.Extension",byte) // D:\\Test.xls,12878
then in Remote Location
FilePath Byte
File.WriteAllBytes("FilePath/FileName.Extension",byte)// D:\\Test123.xls,12878
Check this Link
Accessing paths in Remote Machine : http://www.codeproject.com/Questions/184633/Connect-to-a-shared-folder-using-ip-address-in-vb6

Access to the path * is denied

I have two WebServices that create files at the same director using the following method:
var schemaDir = _propClass.RepositorySettingRoot + #"\" + webServiceId;
if (!Directory.Exists(schemaDir))
{
Directory.CreateDirectory(schemaDir);
}
var schemaFile = schemaDir + #"\" + webMethodId + ".txt";
File.WriteAllText(schemaFile, webMethodSchema);
When trying to delete the file using File.Delete, if it was created by the 1st service it's deleted properly, but if it was created using the second, the exception Access to the path * is denied is raised.
The deletion code
schemaDir = _propClass.RepositorySettingRoot + #"\" + webServiceId + #"\" + webMethodId + ".txt";
if (File.Exists(schemaDir))
{
File.Delete(schemaDir);
}
I've found the answer ..
It's a security issue.
The file should be deleted by the service created it.
The deletion method was on ws1, so it can delete only the files it created.

Unable to generate file from ASP.NET with inkscape

I have an ASP.NET application on my local machine that works. This application takes an SVG file and creates a PNG from it using inkscape. I have tried to migrate that application to my production server. Oddly, the png creation is not working. The really strange part is, an Exception is not being thrown either. I have taken the command line parameters that are being created and copied and pasted them into the command line environment and they work. For instance, here is the line:
inkscape.exe -f "C:\inetpub\wwwroot\MyTest\sample.svg" -e "C:\inetpub\wwwroot\MyTest\sample.png"
I thought it was something simple, so I extracted the code into a sample web project. This project just converts a .svg to a .png. Once again, it worked in my local environment, but not in the production environment. Here is the code:
protected void executeButton_Click(object sender, EventArgs e)
{
try
{
string sourceFile = Server.MapPath("svg") + "\\" + ConfigurationManager.AppSettings["sourceFile"];
string targetFile = Server.MapPath("png") + "\\" + ConfigurationManager.AppSettings["targetFile"];
string args = "-f \"" + sourceFile + "\" -e \"" + targetFile + "\" -w100 -h40";
string inkscape = ConfigurationManager.AppSettings["inkscapeExe"];
// Generate the png via inkscape
ProcessStartInfo inkscapeInfo = new ProcessStartInfo(inkscape, args);
Process inkscape = Process.Start(inkscapeInfo);
inkscape.WaitForExit(5000);
runLiteral.Text = "Success!<br />" + args;
}
catch (Exception ex)
{
runLiteral.Text = ex.GetType().FullName + "<br />" + ex.Message + "<br />" + ex.StackTrace;
}
}
Can someone tell me what I'm doing wrong?
Thank you!
A couple things to check:
Make sure that the application pool identity for the web application (found in IIS, usually NetworkService) has permissions to execute inkscape.exe
If that is fine, check to make sure that the directory grants Modify permissions to the apppool identity on the directory(ies) you are writing the PNG to ("C:\inetpub\wwwroot\MyTest")
Alternatively, you can use impersonation to run the executable under a specific Windows account.

Creating SQL Server backup file (.bak) with c# to any location

I'm trying to write simple application in C# which will allow me to backup, zip and send over ftp my SQL Server database.
One problem I have encountered is that I'm not able to create the backup file (.bak) if I try to do it in different location than "C:\Program Files\Microsoft SQL Server\MSSQL.3\MSSQL\Backup" or "C:\Program Files\Microsoft SQL Server\MSSQL.3\MSSQL\Data" folder. I understand that this is a premission problem. Could someone point me to the resources or write here a short snippet how to programmatically add such a permission to any folder on my system.
Regards
Kris
i assume you are running your programm as a scheduled task ... did you give writing permissions to the target folder for the executing user of the task??
edit:
with permissions you can have 2 scenarios:
windows authenification
mixed authentification
if you are using windows authentification, the read and write permissions of the windows user are taken. otherwise the permissions for the sql server service account.
and this behaviour makes sense to me and maybe hits the nail in your scenario!
edit 2:
i don't want to encourage you to do so ... some admins may hate you when you mess up their acl's
but this may do the trick
btw: Magnus Johansson already gave you a "try-this" link
no matter for which method you go - be sure to hand in the correct user (as descriped above!)
(for full history)
...
side-note:
i know this is not the exact answer to your question, but i would recommend you smo to generate backups ...
like
using Microsoft.SqlServer.Management.Smo;
var bdi = new BackupDeviceItem(/* your path inlcuding desired file */);
var backup = new Backup
{
Database = /* name of the database */,
Initialize = true
};
backup.Devices.Add(bdi);
var server = new Server(this.SqlServer);
try
{
backup.SqlBackup(server);
}
catch (Exception ex)
{
// * log or sth
}
you only have to care for the .dll's. take assemblies for the desired server version (some params/properties vary through different server versions)
more info here
Ok Guys, Magnus and dittodhole! Thanks a lot for your help. I have combined Magnus'es link to the article on setting up permisions on the folder together with some more research and finally I've got it :).
So reassuming, I'm using Smo, and to create a folder with proper permissions I have to look for the group instead of win32_Users. Here you go a short snippet if someone finds this post he can find it usefull:
string tempPath = Directory.CreateDirectory("C:\\path_to_your_folder").FullName;
//set permissions
SelectQuery sQuery = new SelectQuery("Win32_Group",
"Domain='" +
System.Environment.UserDomainName.ToString() +
"'");
try
{
DirectoryInfo myDirectoryInfo = new DirectoryInfo("C:\\path_to_your_folder");
DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(sQuery);
foreach (ManagementObject mObject in mSearcher.Get())
{
string User = System.Environment.UserDomainName + "\\" + mObject["Name"];
if(User.StartsWith("your-machine-name\\SQL"))
{
myDirectorySecurity.
AddAccessRule(new FileSystemAccessRule(User,
FileSystemRights.FullControl,
AccessControlType.Allow));
}
}
myDirectoryInfo.SetAccessControl(myDirectorySecurity);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
Again thanks everyone for your help! Stackoverflow rocks!
Here is a procedure is use for back up in C#.Hope it helps
public void BackupDatabase (string BackUpLocation, string BackUpFileName, string
DatabaseName, string ServerName )
{
DatabaseName = "[" + DatabaseName + "]";
string fileUNQ = DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString() +"_"+ DateTime.Now.Hour.ToString()+ DateTime.Now .Minute .ToString () + "_" + DateTime .Now .Second .ToString () ;
BackUpFileName = BackUpFileName + fileUNQ + ".bak";
string SQLBackUp = #"BACKUP DATABASE " + DatabaseName + " TO DISK = N'" + BackUpLocation + #"\" + BackUpFileName + #"'";
string svr = "Server=" + ServerName + ";Database=master;Integrated Security=True";
SqlConnection cnBk = new SqlConnection(svr);
SqlCommand cmdBkUp = new SqlCommand(SQLBackUp, cnBk);
try
{
cnBk.Open();
cmdBkUp.ExecuteNonQuery();
Label1.Text = "Done";
Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + #"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString();
}
catch (Exception ex)
{
Label1.Text = ex.ToString();
Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + #"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString();
}
finally
{
if (cnBk.State == ConnectionState.Open)
{
cnBk .Close();
}
}
}
Take a look at this article.
Remember to set the permissions for the account that the SQL Server instance is running with.
Although this may not answer your immediate question, I'd advice you to look into SQL Server Integration Services (SSIS). This looks like the exact thing SSIS was created for, and in the 2008 version there's the possibility to use C# code if needed, should the standard components not do what you need (earlier versions used VB.NET).
MSDN SSIS Info Link 1
SSIS 2005 Tutorial Link 2
Take a look at it.

Categories

Resources