Google Drive V3 Api get File Name, C# - c#

How do I get a single files name from a get request using the drive api?
I have made a request but there is not metadata about the file there, I can only download it.
var fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
var request = driveService.Files.Get(fileId);
Apparently this return a files.get in the response according to this doc
I just want to download a file and have its name displayed, not just its id

For Google Drive V3:
C#:
string f = driveService.Files.Get(fileId).Execute().Name;
VB:
Dim f As String = driveService.Files.Get(fileId).Execute().Name

You can get the file name from the Title property in the File class:
string FileName = service.Files.Get(FileId).Execute().Title;
and for downloading,
// DriveService _service: a valid Authendicated DriveService
// Google.Apis.Drive.v2.Data.File _fileResource: Resource of the file to download. (from service.Files.Get(FileId).Execute();)
// string _saveTo: Full file path to save the file
public static void downloadFile(DriveService _service, File _fileResource, string _saveTo)
{
if (!String.IsNullOrEmpty(_fileResource.DownloadUrl))
{
try
{
var x = _service.HttpClient.GetByteArrayAsync(_fileResource.DownloadUrl);
byte[] arrBytes = x.Result;
System.IO.File.WriteAllBytes(_saveTo, arrBytes);
}
catch(Exception e)
{
MessageBox.Show(e.Message, "Error Occured", MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(0);
}
}
}

Try this
///
/// Download a file
/// Documentation: https://developers.google.com/drive/v2/reference/files/get
///
/// a Valid authenticated DriveService
/// File resource of the file to download
/// location of where to save the file including the file name to save it as.
///
public static Boolean downloadFile(DriveService _service, File _fileResource, string _saveTo)
{
if (!String.IsNullOrEmpty(_fileResource.DownloadUrl))
{
try
{
var x = _service.HttpClient.GetByteArrayAsync(_fileResource.DownloadUrl );
byte[] arrBytes = x.Result;
System.IO.File.WriteAllBytes(_saveTo, arrBytes);
return true;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
return false;
}
}
else
{
// The file doesn't have any content stored on Drive.
return false;
}
}
Code ripped from my Google drive api C# download tutorial. Which I haven't updated in ages so if there are any issues let me know and I will fix them.

Related

Failed to upload files to google drive intermittently

Using the Google Drive API to upload files. Multiple same console app is running at the same time to upload different parts of files in the folder and their files don't overlap. This hits the quota limit. Then a while-try-catch is implemented to re-execute the query whenever it throws the exception because of the quota limit. The list and create directory method works well but not the upload (i.e. create) method. Some files are missing when i checked from the Google Drive site
Tried using FileStream instead of MemoryStream but it seems not related.
public static Google.Apis.Drive.v3.Data.File uploadFile(DriveService _service, string _uploadFile)
{
bool again = true;
string[] p = _uploadFile.Split('/');
if (System.IO.File.Exists("C:/"+_uploadFile))
{
Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File();
body.Name = System.IO.Path.GetFileName(p[p.Length-1]);
body.Description = "";
body.MimeType = GetMimeType("C:/"+_uploadFile);
body.Parents = new List<string>() { ID };
// File's content.
System.IO.FileStream stream = new System.IO.FileStream("C:/" + _uploadFile, FileMode.Open);
try
{
FilesResource.CreateMediaUpload request = _service.Files.Create(body, stream, GetMimeType("C:/" + _uploadFile));
while (again)
{
try
{
request.Upload();
again = false;
}
catch (Exception e)
{
Console.WriteLine("uploadFile: "+p[p.Length-1]);
}
}
return body;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
return null;
}
}
else
{
Console.WriteLine("File does not exist: " + _uploadFile);
return null;
}
}

Error on delete file at Windows Mobile 6.5

I'm working on a project for windows mobile 6.5. I am using C # with compact framework 3.5 (CF 3.5) and SDK for Windows Mobile 6.5.
My routine writes files to a temporary directory for further processing. After a few days the file is renamed and directed to a purge.
When trying to delete the file the following error occurs: Access to the path '\Application Data\Volatile\Temp\20170822-97703.Nf.env' is denied.
Where:
\Application Data\Volatile is the default temporary directory Path.GetTempPath()
\Temp is my temporary directory
20170822-97703.Nf.env is my file.
Code:
const string dirTemp= "Temp";
public void PurgeFiles()
{
DateTime datePurge= new DateTime();
datePurge= DateTime.Now.AddDays(-7);
var files= FindFiles();
foreach (string file in files)
{
var dateAlt = Directory.GetLastWriteTime(file);
if (dateAlt< datePurge)
{
Directory.Delete(file);
}
}
}
private string[] FindFiles()
{
string searchPattern;
string dirLocal;
dirLocal= Path.GetTempPath();
dirLocal= Path.Combine(dirLocal, dirTemp);
if (Directory.Exists(dirLocal))
{
searchPattern = "*.Env";
var files = Directory.GetFiles(dirLocal, searchPattern);
return files;
}
else
return new string[0];
}
Save file
public bool SaveFile(string dir, string fileName, string content)
{
try
{
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
string pathFile = Path.Combine(dir, fileName);
if (File.Exists(pathFile))
return true;
//Salva os dados
StreamWriter fileConf = new StreamWriter(pathFile);
fileConf.Write(content);
fileConf.Flush();
fileConf.Close();
return true;
}
catch (Exception ex)
{
return false;
}
}
Mark the file as processed
public void MarkFile(string fileName)
{
try
{
string newFileName= fileName + ".env";
if (File.Exists(newFileName))
return;
File.Move(fileName , newFileName);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
To can delete the file I changed the name of file and the line below
Directory.Delete(file);
for
File.Delete(file);

Sharepoint uploaded file name was changed by server event. How to retrieve it?

I'm uploading file to Sharepoint server using this code:
ClientOM.File uploadFile = null;
try {
string fileRef = serverRelativeURL + msg.Message.FileName;
FileCreationInformation fileCreationInformation = new FileCreationInformation() {
Content = msg.Content,
Url = fileRef,
Overwrite = true
};
uploadFile = _currentList.RootFolder.Files.Add(fileCreationInformation);
_currentContext.ExecuteQuery();
And file uploaded. But on server we have event that adds some random string to the file title. So fileRef is not relevant after upload.
And we need to set the Author of the file. For this we have to retrieve file and update this propery. I do it with this sample:
string fileName = serverRelativeURL + msg.Message.FileName;
uploadFile = _currentContext.Web.GetFileByServerRelativeUrl(fileName);
_currentContext.Load(uploadFile);
uploadFile.ListItemAllFields["Author"] = _currentUser;
uploadFile.ListItemAllFields["Editor"] = _currentUser;
uploadFile.ListItemAllFields.Update();
_currentContext.ExecuteQuery();
And on ExecuteQuery() I get an Exception "File not found". But if I copy path from Sharepoint (with that random string) everything works Ok.
So the question is: Is there other way to retrieve file? By id for example? because when we uploading file, instance "uploadFile" does not have much of useful information.
Method 1:
Keep track of the filename, and then use this code to retrieve it directly.
public FileInformation GetFileFromAttachment(int itemId, string filename)
{
FileInformation file = null;
//continue here
if (new FileInfo(filename).Name != null)
{
CSOMUtils.ExecuteInNewContext(QueryConfig.siteUrl, delegate(ClientContext clientContext)
{
clientContext.Credentials = QueryConfig.credentials;
clientContext.Load(clientContext.Web, l => l.ServerRelativeUrl);
clientContext.ExecuteQuery();
List oList = clientContext.Web.Lists.GetByTitle(ListName);
clientContext.ExecuteQuery();
string url = string.Format("{0}/Lists/{1}/Attachments/{2}/{3}",
clientContext.Web.ServerRelativeUrl,
ListName,
itemId,
filename);
var f = clientContext.Web.GetFileByServerRelativeUrl(url);
clientContext.Load(f);
clientContext.ExecuteQuery();
file = File.OpenBinaryDirect(clientContext, f.ServerRelativeUrl);
});
}
return file;
}
Method 2:
You can use ServerRelativeUrl to get the folder containing all the attachments.
https://msdn.microsoft.com/library/office/microsoft.sharepoint.client.folder.serverrelativeurl.aspx
https://sharepoint.stackexchange.com/questions/132008/reliably-get-attachments-for-list-item

Delete a folder whose items are open in browser

sdel = Server.MapPath("~/Media_Extracted_Content" + "/" + sfolder);
Directory.Delete(sdel,true);
'sfolder' contains different sub folder and all sub folder have contains different items. All items like image file, audio file, video file opened in browser .I am copying that items from this existing location to new location and after that I have to delete this directory from my system. Whenever I am trying to to this it shows error that Directory is not empty. Also, when I am trying to delete individual items from sub folder it is showing error that this file is being used by another process. Please help me.
I think at Server or at Hosting you have not given the permision to the folder which are, allow READ and WRITE to the Folder.
Please Try This Two FUNCTION/Method.
You only have to do is paste both function in class file(eg class1.cs).
In (aspx.cs)Assign Value to source and destination
For Example source = Server.MapPath("~/Media_Extracted_Content/" + sourcefolder);
destination = Server.MapPath("~/Media_Extracted_Content/" + destinationfolder);
And Call classobject.MoveFiles(source, destination,true);
public void createfolder(string directorypath)
{
// CREATE folder
try
{
Directory.CreateDirectory(directorypath);
}
catch (Exception ex)
{ }
}
public void MoveFiles(string source, string destination, bool overwrite)
{
System.IO.DirectoryInfo inputDir = new System.IO.DirectoryInfo(source);
System.IO.DirectoryInfo outputDir = new System.IO.DirectoryInfo(destination);
try
{
if ((inputDir.Exists))
{
if (!(outputDir.Exists))
{
createfolder(destination);
// outputDir.Create();
}
//Get Each files and copy
System.IO.FileInfo file = null;
foreach (System.IO.FileInfo eachfile in inputDir.GetFiles())
{
file = eachfile;
if ((overwrite))
{
file.CopyTo(System.IO.Path.Combine(outputDir.FullName, file.Name), true);
}
else
{
if (((System.IO.File.Exists(System.IO.Path.Combine(outputDir.FullName, file.Name))) == false))
{
file.CopyTo(System.IO.Path.Combine(outputDir.FullName, file.Name), false);
}
}
System.IO.File.Delete(file.FullName);
}
//Sub folder access code
System.IO.DirectoryInfo dir = null;
foreach (System.IO.DirectoryInfo subfolderFile in inputDir.GetDirectories())
{
dir = subfolderFile;
//Destination path
if ((dir.FullName != outputDir.ToString()))
{
MoveFiles(dir.FullName, System.IO.Path.Combine(outputDir.FullName, dir.Name), overwrite);
}
System.IO.Directory.Delete(dir.FullName);
}
}
}
catch (Exception ex)
{
}
}

Creating a file under nested folder in Sharepoint

What's the best way to create a file under a nested folder in Sharepoint ?
My current method
public string CreateSPFile(string spServerURL, string spDocumentLibraryURL, string folder, string fileName, Stream fileStream, bool overwrite)
{
if (SPSite.Exists(new Uri(spServerURL)))
{
SPSite site = new SPSite(spServerURL);
SPWeb oWebsite = site.OpenWeb();
oWebsite.AllowUnsafeUpdates = true;
SPFolder spFolder = oWebsite.Folders[spDocumentLibraryURL];
if (!string.IsNullOrEmpty(folder))
{
spFolder.SubFolders[folder].Files.Add(fileName, fileStream, overwrite);
}
else
{
SPFileCollection files = spFolder.Files;
spFolder.Files.Add(fileName, fileStream, overwrite);
}
oWebsite.AllowUnsafeUpdates = false;
site.Close();
}
}
As you can see, if I want to create a file under nested folder, i need to modified my codes.
What will be better way to handle this kind of saving nested folder situation?
According to my project structure, the file can be like /DocumentLibrary/Folder1/Folder2/Folder3/File.txt.
You can load a folder by its server relative URL:
SPFolder folder = web.GetFolder("/DocumentLibrary/Folder1/Folder2/Folder3/");
With this approach you do not have to load folder by folder and your code works with n folder levels.
I've updated your code sample and added some comments regarding SharePoint best practices:
public string CreateSPFile(string spServerURL, string spDocumenttargetUrl, string folder, string fileName, Stream fileStream, bool overwrite)
{
// I suggest skip this pre check since it internally opens a new site object
// If you have to silenlty ignore non-existant SPSite you should catch a FileNotFoundException.
if (SPSite.Exists(new Uri(spServerURL)))
{
// use the using construct to safely dispose the opened SPSite object
using (SPSite site = new SPSite(spServerURL))
{
// SPWeb object opened with SPSite.OpenWeb() have to be disposed as well
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
string targetUrl = SPUrlUtility.CombineUrl(web.ServerRelativeUrl, spDocumenttargetUrl);
if (!String.IsNullOrEmpty(folder))
{
targetUrl = SPUrlUtility.CombineUrl(targetUrl, folder);
}
SPFolder target = web.GetFolder(target);
SPFileCollection files = target.Files;
target.Files.Add(fileName, fileStream, overwrite);
// no need to revert AllowUnsafeUpdates for newly opened webs
// web.AllowUnsafeUpdates = false;
}
}
}
}
For uploading a file into a nested folder you could consider the following approach:
ensure the target folder exist using the method EnsureFolder provided below
upload a file using SPFileCollection.Add method
How to ensure a nested Folder exist using SharePoint SSOM
internal static class SPWebExtensions
{
/// <summary>
/// Ensure SPFolder
/// </summary>
/// <param name="web"></param>
/// <param name="listTitle"></param>
/// <param name="folderUrl"></param>
/// <returns></returns>
public static SPFolder EnsureFolder(this SPWeb web, string listTitle, string folderUrl)
{
if (string.IsNullOrEmpty(folderUrl))
throw new ArgumentNullException("folderUrl");
var list = web.Lists.TryGetList(listTitle);
return CreateFolderInternal(list, list.RootFolder, folderUrl);
}
private static SPFolder CreateFolderInternal(SPList list, SPFolder parentFolder, string folderUrl)
{
var folderNames = folderUrl.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
var folderName = folderNames[0];
var curFolder =
parentFolder.SubFolders.Cast<SPFolder>().FirstOrDefault( f => System.String.Compare(f.Name, folderName, System.StringComparison.OrdinalIgnoreCase) == 0);
if (curFolder == null)
{
var folderItem = list.Items.Add(parentFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder,
folderName);
folderItem.SystemUpdate();
curFolder = folderItem.Folder;
}
if (folderNames.Length > 1)
{
var subFolderUrl = string.Join("/", folderNames, 1, folderNames.Length - 1);
return CreateFolderInternal(list, curFolder, subFolderUrl);
}
return curFolder;
}
}
Gist: EnsureFolder.cs
The following example demonstrates how to ensure the following folder structure exist under Documents library and upload a file into it:
Orders
|
A --
|
A1
Example:
var targetFolder = web.EnsureFolder("Documents", "Orders3/A/A1");
var fileContent = System.IO.File.ReadAllBytes(fileName);
var fileUrl = Path.GetFileName(fileName);
targetFolder.Files.Add(fileUrl, fileContent);

Categories