Why would GetFilesAsync return no files? - c#

Why would GetFilesAsync return no files? I have a folder that contains images, no subfolders, and no other files. FolderPicker shows the expected folder content. However, GetFilesAsync(OrderByName) returns no items.
(The folder is not part of any library and is not indexed).
Edit - Add Code
Getting the folder:
var folder = await folderPicker.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
Accessing folder content:
var foldersFiles = await folder.GetFilesAsync(CommonFileQuery.OrderByName);
foldersFiles is empty. However, Windows Explorer and the folder picker show that it has content.
Edit - More info
This returns files. The only difference is the CommonFileQuery is removed.
var foldersFiles = await folder.GetFilesAsync();
Edit - More info
This also does not work:
var queryOptions = new QueryOptions(CommonFileQuery.OrderByName, null)
{
FolderDepth = FolderDepth.Deep
};
var query = folder.CreateFileQueryWithOptions(queryOptions);
var foldersFiles = await query.GetFilesAsync();
Remove CommonFileQuery.OrderByName, and it works.
My current work around is to avoid CommonFileQuery.OrderByName (...and maybe the other OrderBy's too).

Related

C# - CSOM - Upload a file to a subdirectory in Sharepoint Online

I'm trying to upload a file to SharePoint Online and I got this sample code:
var uploadFile = list
.RootFolder
.Folders
.GetByPath(ResourcePath.FromDecodedUrl("A"))
.Files
.Add(newFile);
ctx.Load(uploadFile);
await ctx.ExecuteQueryAsync();
Which works perfectly fine, so everything around it works. But apparently this snippet
var uploadFile = list
.RootFolder
.Folders
.GetByPath(ResourcePath.FromDecodedUrl("A/B"))
.Files
.Add(newFile);
ctx.Load(uploadFile);
await ctx.ExecuteQueryAsync();
Throws System.IO.DirectoryNotFoundException even though both directories exist. So how can I upload a file to the subdirectory "B"?
Try to upload file like this:
public static void UploadFile(ClientContext context,string uploadFolderUrl, string uploadFilePath)
{
var fileCreationInfo = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(uploadFilePath),
Overwrite = true,
Url = Path.GetFileName(uploadFilePath)
};
var targetFolder = context.Web.GetFolderByServerRelativeUrl(uploadFolderUrl);
var uploadFile = targetFolder.Files.Add(fileCreationInfo);
context.Load(uploadFile);
context.ExecuteQuery();
}
using (var ctx = new ClientContext(webUri))
{
ctx.Credentials = credentials;
UploadFile(ctx,"LibName/FolderName/Sub Folder Name/Sub Sub Folder Name/Sub Sub Sub Folder Name",filePath);
}
Please check out another similiar thread here:
Alternative Save/OpenBinaryDirect methods for CSOM for SharePoint Online

Open multiple files by selecting single file in a sequence - Generate file name from multiple files

I have a UWP app that has an option to open an Image Sequence. Typically image sequences are named as follows:
MyImageSequence_00001.png,
MyImageSequence_00002.png,
...
MyImageSequence_01024.png,
MyImageSequence_01025.png,
Generally, these image sequences will be named something like "UniqueFileName_v06" with a frame number like "_0004" following. In a lot of cases you could have multiple image sequences in the same folder but they will have different leading names such as "UniqueFileName_v04_Reflections" or "UniqueFileName_v04_Depth". The starting frame number could be any number and the frame number will increase sequentially to the last frame of the sequence.
I'm currently having the user select all of the files manually as follows:
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.ViewMode = PickerViewMode.List:
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.FileTypeFilter.Add(".tif");
files = await filePicker.PickMultipleFilesAsync();
What I am hoping to do is allow a user to open their image sequence by selecting a single image from the sequence in a file picker. So if they were to select "MyImageSequence_00003.png" the app will find and select the rest of the files in the sequence (MyImageSequence 00001-01025) and add them to the filePickerSelectedFilesArray variable files.
Secondly, I'd like to generate a composite string name from the list of files. So, generate a name like "MyImageSequence_00001-01025" to identify the image sequence.
Any thoughts on the best way to go about this? Seems like I should use something like the StorageItemsQuery class but unsure if that is the best method nor how to go about it.
Thanks for any help you can provide!
I'm using the following to get the Image sequence name without frame numbers:
File path to input C:\Users\Me\Desktop\MyImageSequenceFolder\MyImageSequence_00001.png
string input = Path.GetFileNameWithoutExtension(fileFromImageSequence.Path);
string pattern = #"\d+$";
string replacement = "";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);
sequenceName = result.TrimEnd('_');
sequenceName output is "MyImageSequence"
At present, native UWP applications cannot access files through paths (permission restrictions).
According to your description, the picture sequences are all placed in the one folder. Then before selecting a file through FileOpenPicker, we can first obtain access to the folder and add it to the future access list.
public async Task<StorageFolder> GetImageFolderAsync(string token = "")
{
StorageFolder folder;
if (string.IsNullOrEmpty(token))
{
var folderPicker = new FolderPicker();
folderPicker.SuggestedStartLocation = PickerLocationId.Desktop;
folderPicker.FileTypeFilter.Add("*");
folder = await folderPicker.PickSingleFolderAsync();
if (folder != null)
{
string folderToken = StorageApplicationPermissions.FutureAccessList.Add(folder);
// save token to LocalSettings or other location.
// ...
}
}
else
{
folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(token);
}
return folder;
}
After adding the folder to FutureAccessList, we will get a Token. In the future, we can get the folder directly through Token without opening FolderPicker. This is equivalent to the user authorizing the application to access the folder.
Then, when the user selects the file through FileOpenPicker, you can obtain the folder by the above method, and find the same type of image sequence in the folder according to the rules you set (like StorageItemsQuery).
public async Task<IReadOnlyList<StorageFile>> SearchSameImages(StorageFile fileFromImageSequence)
{
string input = Path.GetFileNameWithoutExtension(fileFromImageSequence.Path);
string pattern = #"\d+$";
string replacement = "";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);
sequenceName = result.TrimEnd('_');
var queryOptions = new QueryOptions();
queryOptions.ApplicationSearchFilter = $"\"{sequenceName}\"";
string token = GetToken(); // From LocalSettings or other place.
var folder = await GetImageFolderAsync(token);
var queryResult = folder.CreateFileQueryWithOptions(queryOptions);
var files = await queryResult.GetFilesAsync();
return files;
}
In this way, you can ask the user to specify a folder to store the sequence of pictures when the application first starts, and retain access to the folder after that. Use the method provided above to query the sequence of pictures in a folder based on a single file.
Thanks.

Downloading images from publicly shared folders and sub-folders on Dropbox

This is similar to my previous question:
Downloading images from publicly shared folder on Dropbox
I have this piece of code (simplified version) that needs to download all images from publicly shared folder and all sub-folders.
using Dropbox.Api;
using Dropbox.Api.Files;
...
// AccessToken - get it from app console
// FolderToDownload - https://www.dropbox.com/sh/{unicorn_string}?dl=0
using (var dbx = new DropboxClient(_dropboxSettings.AccessToken))
{
var sharedLink = new SharedLink(_dropboxSettings.FolderToDownload);
var sharedFiles = await dbx.Files.ListFolderAsync(path: "", sharedLink: sharedLink);
// var sharedFiles = await dbx.Files.ListFolderAsync(path: "", sharedLink: sharedLink, recursive: true);
// "recursive: true" throws: Error in call to API function "files/list_folder": Recursive list folder is not supported for shared link.
foreach (var entry in sharedFiles.Entries)
{
if (entry.IsFile)
{
var link = await dbx.Sharing.GetSharedLinkFileAsync(url: _dropboxSettings.FolderToDownload, path: "/" + entry.Name);
var byteArray = await link.GetContentAsByteArrayAsync();
}
if (entry.IsFolder)
{
var subFolder = entry.AsFolder;
// var folderContent = await dbx.Files.ListFolderAsync(path: subFolder.Id);
// var subFolderSharedLink = new SharedLink(???);
}
}
}
How do I list entries of all sub-folders?
For any given subfolder, to list its contents, you'll need to call back to ListFolderAsync again, using the same sharedLink value, but supplying a path value for the subfolder, relative to the root folder for the shared link.
For example, if you list the contents of the folder shared link, and one of the entries is a folder with the name "SomeFolder", to then list the contents of "SomeFolder", you would need to make a call like:
await dbx.Files.ListFolderAsync(path: "/SomeFolder", sharedLink: sharedLink);

Get all files inside a specific folder in a library with UWP

I'm trying to get all the videos in a specific folder inside the Videos library using UWP, right now I can get all videos inside the Videos library, but I'd like to reduce my results to only those inside the specified folder. My code is this:
Windows.Storage.Search.QueryOptions queryOption = new QueryOptions(CommonFileQuery.OrderByTitle, new string[] {".mp4"});
queryOption.FolderDepth = FolderDepth.Deep;
var files = await KnownFolders.VideosLibrary.CreateFileQueryWithOptions(queryOption).GetFilesAsync();
StorageFile videoToPlay = (files[new Random().Next(0, files.Count)] as StorageFile);
var stream = await videoToPlay.OpenAsync(Windows.Storage.FileAccessMode.Read);
Player.SetSource(stream, videoToPlay.ContentType);
Debug.WriteLine(Player.Source);
How could I access a subfolder named "Videos to Play" and then get all the videos inside that folder? I tried accesing it by using a path like:
string localfolder = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
var array = localfolder.Split('\\');
var username = array[2];
string[] allVideos = System.IO.Directory.GetFiles("C:/Users/" + username + "/Videos/Videos to Play");
But I get access denied even though I already requested access to the Videos library (and the fact that the first example works shows that I actually have access to it).
try
{
var folder = await KnownFolders.VideosLibrary.GetFolderAsync("Videos to Play");
}
catch (FileNotFoundException exc)
{
// TODO: Handle the case when the folder wasn't found on the user's machine.
}
In the folder variable you'll have the reference to the desired folder. Then it's the very same stuff that you already do, but instead of KnownFolders.VideosLibrary folder use this one!

Copying/over-writing one source to another in TFS?

Question Background:
Within my TF Server I have two folders, one is a simple 'HelloWorld.sln' in a folder called 'HelloWorldDev' and the other is a 'HelloWorld.sln' in a folder called 'HelloWorldQA'. Each folder contains its respective .cs files etc.
I want to checkout a file from the HelloWorld QA folder, replace - or update it - with a version from the HelloWorldDev folder with the same file name, then check this file back into the HelloWorldQA folder with the relevant changes.
Question:
I am very new to the TFS API so I'm not 100% if what I'm trying to ask is the correct way to proceed, or if its even possible. Can someone give me an example of achieving this?
Code so far:
string fileName = #"C:\Users\Me\Documents\TfsServer\HelloWorldQA\IHelloWorld.cs";
string fileNameQA = #"C:\Users\Me\Documents\TfsServer\HelloWorld\IHelloWorld.cs";
string uri = #"https://tfsServer.visualstudio.com/";
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
FileInfo fi = new FileInfo(fileName);
var workspaceInfoQA = Workstation.Current.GetLocalWorkspaceInfo(fileNameQA);
var serverQA = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspaceQA = workspaceInfo.GetWorkspace(serverQA);
workspace.PendEdit(fileNameQA);
FileInfo fiQA = new FileInfo(fileNameQA);
First, instead of using 2 workspaces, you can simply map both folders in the same workspace.
Then you're looking for a merge operation:
var sourcePath = workspace.GetServerItemForLocalItem(fileName);
var targetPath = workspace.GetServerItemForLocalItem(fileNameQA);
var getStatus = workspace.Merge(sourcePath, targetPath, null, null);
if (getStatus.NumUpdated > 0)
{
//OK
}

Categories