await FileIO.ReadTextAsync giving error (edited: now using IStorageFile.OpenReadAsync) - c#

I have this method in my project. This is what it is supposed to do:
It accepts a string which is the name of a file in a folder, AV, in the Assets folder of my project. It opens this file and performs some operations on it (not all of the required operations are in the code, yet).
public async static Task<Book> ParseFile(string bookN)
{
string bookName = bookN.Replace(" ", "");
StorageFile bookFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AV/" + bookName + ".txt"));
string content = await FileIO.ReadTextAsync(bookFile);
string chapterStr = "CHAPTER";
int numOfChapters = Utilities.NumOfTimesStringOccurs(content, chapterStr);
Book book = new Book(bookName, numOfChapters);
//book.Chapters = new List<Chapter>(numOfChapters);
return book;
}
The problem is this line:
string content = await FileIO.ReadTextAsync(bookFile);
I know this because I set a breakpoint at the first line of the method. After stepping into the code, that particular line broke and opened the .g.cs file and was highlighting a line that apparently implied the compiler could not trace it. The line had to do with diagnostics.debugger or something like that.
The next step I tried was to put in a try and display the error in a MessageDialog. The error from this was:
Object reference was not found
or something similar.
I am thinking it could be that the line
StorageFile bookFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AV/" + bookName + ".txt"));
is causing this since it has await so maybe the operation was not complete before the next line could be executed. But I don't expect it to be slow since the files in the folder are just 5 - 6 kB each on average.
I don't know what's wrong as this is my first time of using the Storage namespace classes as I'm new to Windows Store programming.
EDIT
After going through this MSDN Forum, I changed the code to this:
StorageFile bookFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AV/" + bookName + ".txt"));
Windows.Storage.Streams.IRandomAccessStream ras = await bookFile.OpenReadAsync();
Windows.Storage.Streams.DataReader reader = new Windows.Storage.Streams.DataReader(ras.GetInputStreamAt(0));
int numOfBytes = (int)ras.Size;
Byte[] bytes = new Byte[numOfBytes - 1];
await reader.LoadAsync((uint)numOfBytes);
reader.ReadBytes(bytes);
string content = Convert.ToBase64String(bytes);
This code should have actually worked because when I stepped through it during breakpoint, there was no error. But for some reason I can't fathom, the app doesn't react. When I set a breakpoint and I step into the code, it works (I mean it doesn't break; it does not give me the expected output) but when there is none, it "freezes".
I initially thought it was the size of the file (201 kB) that was taking too long so I changed it to another with a much lesser size (~3 kb) but it was the same. Now I'm thinking it has to do with async and await. I wish there was a way to do this without using them.
EDIT:
I'm not posting this an answer because I realized the it solved the issue but the question did not contain enough info to get an answer.
The solution was that I didn't use await on the method that was calling this method. I would have deleted it but I thought maybe it could be help someone. Thanks to everyone that attempted to solve it.

First You can check the property of your file(Assets/AV/someone.txt).
The Build Action should be Content. But not Embedded Resource or others.
If it still error. Then check if the file is existed.

Related

Octokit API Exception: "is at xx but expected yy"

Im working on a small school project where i need to update an file from my github repo.
Everything worked fine until i got an error out of nowhere.
I am using Octokit .net with a C# WPF Application. Here the Exception:
Octokit.ApiException: "is at 1ce907108c4582d5a0986d3a37b2777e271a0105 but expected 47fa57debd39ee6a63f24d39e9513f87814a5ed6"
I dont know why this error shows up, because i didn't change anything before the error happend and now nothing works anymore. Can someone help me with this?
Here the code:
private static async void UpdateFile(string fileName, string fileContent)
{
var ghClient = new GitHubClient(new ProductHeaderValue(HEADER));
ghClient.Credentials = new Credentials(API_KEY);
// github variables
var owner = OWNER;
var repo = REPO;
var branch = "main";
var targetFile = fileName;
try
{
// try to get the file (and with the file the last commit sha)
var existingFile = await ghClient.Repository.Content.GetAllContentsByRef(owner, repo, targetFile, branch);
// update the file
var updateChangeSet = await ghClient.Repository.Content.UpdateFile(owner, repo, targetFile,
new UpdateFileRequest("API Config Updated", fileContent, existingFile.First().Sha, branch));
}
catch (Octokit.NotFoundException)
{
// if file is not found, create it
var createChangeSet = await ghClient.Repository.Content.CreateFile(owner, repo, targetFile, new CreateFileRequest("API Config Created", fileContent, branch));
}
}
I found the issue after a bit of experimenting.
I updated 3 files at the same time, it turns out Octokit can't handle more than 1 request at the same time...
If you're stuck on this problem too, just add a delay of ~2 seconds before posting a new request.

Xamarin Media Plugin Crashes when second photo is taken

I am using the Plugin.Media (jamesmontemagno/MediaPlugin) plugin for Xamarin and I am having an issue with accepting a picture. When I take the second picture (the first picture works fine) and I click to accept the image the whole app crashes with no output as to the error. I have tried trapping the error but cannot find where it is occurring. I have as suggested removing the min SDK from Android manifest, but the crash still happens.
I have tried looking through the output in visual studio but it is always different. I am assuming the code works as it takes the image and gives me data back, to be clear, it only happens when trying to accept the second image.
private string GetTimestamp(DateTime value)
{
string timestamp = value.ToString("yyyyMMddHHmmssfff");
string filename = timestamp + ".jpg";
return filename;
}
public Command CaptureImage => new Command(TakePicture);
private async void TakePicture()
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
//Some message
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "FoodSnap",
Name = GetTimestamp(DateTime.Now) //Gets a unique file name,
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Custom,
CustomPhotoSize = 50
});
if (file == null)
return;
FilePath = file.Path;
}
I am completely stumped as to why this is happening. I am also having trouble refreshing my ViewModel when data changes in the page I am using to take the image. I can't help wondering if this has something to do with it.
I solved the problem by testing each line of code. Once I removed PhotoSize = Plugin.Media.Abstractions.PhotoSize.Custom I could take as many pictures as I need. I did use the Github information for the plugin.
I would be interested to know what I did wrong to cause the error. I would suggest that I have misunderstood the tutorial on Github.

Tfs Check-in using PendAdd: The array must contain at least one element

So I'm having a problem with automating my code to check-in files to TFS, and it's been driving me up the wall! Here is my code:
string location = AppDomain.CurrentDomain.BaseDirectory;
TfsTeamProjectCollection baseUserTpcConnection = new TfsTeamProjectCollection(uriToTeamProjectCollection);
IIdentityManagementService ims = baseUserTpcConnection.GetService<IIdentityManagementService>();
TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName, #"PROD1\JR", MembershipQuery.None, ReadIdentityOptions.None);
TfsTeamProjectCollection impersonatedTpcConnection = new TfsTeamProjectCollection(uriToTeamProjectCollection, identity.Descriptor);
VersionControlServer sourceControl = impersonatedTpcConnection.GetService<VersionControlServer>();
Workspace workspace = sourceControl.CreateWorkspace("MyTempWorkspace", sourceControl.AuthorizedUser);
String topDir = null;
try
{
Directory.CreateDirectory(location + "TFS");
String localDir = location + "TFS";
workspace.Map("$/Automation/", localDir);
workspace.Get();
destinationFile = Path.Combine(localDir, Name + ".xml");
string SeconddestinationFile = Path.Combine(localDir, Name + ".ial");
bool check = sourceControl.ServerItemExists(destinationFile, ItemType.Any);
PendingChange[] pendingChanges;
File.Move(sourceFile, destinationFile);
File.Copy(destinationFile, sourceFile, true);
File.Move(SecondsourceFile, SeconddestinationFile);
File.Copy(SeconddestinationFile, SecondsourceFile, true);
if (check == false)
{
workspace.PendAdd(localDir,true);
pendingChanges = workspace.GetPendingChanges();
workspace.CheckIn(pendingChanges, Comments);
}
else
{
workspace.PendEdit(destinationFile);
pendingChanges = workspace.GetPendingChanges();
workspace.CheckIn(pendingChanges, Comments);
}
and the problem is that whenever it's NEW files (PendEdit works correctly when the files already exist in TFS) that my code is attempting to check in, and it runs through this code:
if (check == false)
{
workspace.PendAdd(localDir,true);
pendingChanges = workspace.GetPendingChanges();
workspace.CheckIn(pendingChanges, Comments);
}
The files, instead of being in the included changes in pending changes, are instead in the excluded changes like so:
and when the line that actually does the check-in runs, I'll get a "The array must contain at least one element" error, and the only way to fix it is to manually add those detected changes, and promote them to included changes, and I simply can't for the life of me figure out how to do that programatically though C#. If anyone has any guidance on what direction I should take for this, I would really appreciate it! Thank you!
Edit: I've also discovered another way to solve this by reconciling the folder, which also promotes the detected changes, but again the problem is I can't seem to figure out how to program that to do it automatically.
I know that running the visual studio developer command prompt, redirecting to the folder that this mapping is in, and the running "tf reconcile /promote" is one way, but I can only automate that as far as the /promote part, because that brings up a toolbox that a user would have to input into, which defeats the purpose of the automation. I'm at a loss.
Next Edit in response to TToni:
Next Edit in response to TToni:
I'm not entirely sure if I did this CreateWorkspaceParameters correctly (see picture 1), but this time it gave the same error, but the files were not even in the excluded portions. They just didn't show up anywhere in the pending changes (see picture 2).
Check this blog:
The workspace has a method GetPendingChangesWithCandidates, which actually gets all the “Excluded” changes. Code snippet is as below:
private void PendChangesAndCheckIn(string pathToWorkspace)
{
//Get Version Control Server object
VersionControlServer vs = collection.GetService(typeof
(VersionControlServer)) as VersionControlServer;
Workspace ws = vs.TryGetWorkspace(pathToWorkspace);
//Do Delete and Copy Actions to local path
//Create a item spec from the server Path
PendingChange[] candidateChanges = null;
string serverPath = ws.GetServerItemForLocalItem(pathToWorkspace);
List<ItemSpec> its = new List<ItemSpec>();
its.Add(new ItemSpec(serverPath, RecursionType.Full));
//get all candidate changes and promote them to included changes
ws.GetPendingChangesWithCandidates(its.ToArray(), true,
out candidateChanges);
foreach (var change in candidateChanges)
{
if (change.IsAdd)
{
ws.PendAdd(change.LocalItem);
}
else if (change.IsDelete)
{
ws.PendDelete(change.LocalItem);
}
}
//Check In all pending changes
ws.CheckIn(ws.GetPendingChanges(), "This is a comment");
}

get the file owner information using c#

I would like to get the file owner information but are having some trouble with this line:
const string fileOwner = Delimon.Win32.IO.File.GetAccessControl(fi.Name).GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
Specifically, it doesn't like fi.name. My error is
An object reference is required for the non-static field, method, or property 'Delimon.Win32.IO.File.GetAccessControl(string)'
Here is the larger chuck of code where it sits:
// check if file exists. if so dont overwrite...
if(Delimon.Win32.IO.File.Exists(targetPath+fi.Name)) {
// Console.WriteLine(fileName + " already exists, nothing written");
}
else {
// Console.WriteLine(fileName + " is new so written to dir");
string fileOwner=Delimon.Win32.IO.File.GetAccessControl(fi.Name).GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
Delimon.Win32.IO.File.Copy(fileName, destFile, true);
// convert extension to number
switch(fileExt) {
case ".doc":
fileType=1;
break;
case ".xls":
fileType=2;
break;
case ".mdb":
fileType=3;
break;
default:
fileType=1;
break;
}
// I want tot use fileOwner here in an SQL statement
}
Please note fi.Name holds the file name only. I also have a variable called fileName which holds the full absolute path including the file name. This gives me the same issue.
The method File.GetAccessControl() is 'implemented' as an instance methods and not a static method (not like the one on MSDN)
Try to create a file of type Delimon.Win32.IO.File then call the methode using the created instance:
Delimon.Win32.IO.File file = new Delimon.Win32.IO.File(...); // Check constructor
FileSecurity fs = myFile.GetAccessControl();
You may want to check the documentation regards the Delimon.Win32.IO.File.Exists method which could be an instance methode either.
From the error, it sounds like fi.Name is unable to be found because fi is null when calling GetAccessControl. Take a look at it in the debugger.
Sorry for a couple of answers I placed in the wrong spot. Am new to this site (and c#/.net if you cant tell) I believe I have found a solution here Getting / setting file owner in C# Based on that this is how I have it working:
using System.Security.AccessControl;
using System.Security.Principal;
var fs = System.IO.File.GetAccessControl(fileName);
var sid = fs.GetOwner(typeof(SecurityIdentifier));
Console.WriteLine(sid);
var ntAccount = sid.Translate(typeof(NTAccount));
Console.WriteLine(ntAccount);
so ntAccount is may variable which I will use in the SQL for the document owners name. Thanks for every ones time helping me here. This solution does seem to be working. Quick question since im new here. Should I have posted this as a reply and should I accept it?

WUA IUpdate2.CopyToCache throws WU_E_INVALID_UPDATE_TYPE

I have some problems getting the WUA API to run as expected.
I want to manually copy a update file to a machine and then feed it to the WUA.
The call IUpdate2.CopyToCache causes an error that confuses me slightly. The update is definitively correct. Using a file name that does not even exist also results in the same error!
There is another strange thing I noticed: I searched for an update and found it in the API, but writing it to disk does not work at all. The code executes and there is no error reported, but the directory stays empty.
IUpdateSearcher updateSearcher = new UpdateSearcher();
updateSearcher.Online = true;
ISearchResult searchResult = updateSearcher.Search("UpdateID='" + wsusID + "'");
if (searchResult.ResultCode == OperationResultCode.orcSucceeded && searchResult.Updates.Count == 1)
{
IUpdate update = searchResult.Updates[0];
Console.WriteLine(update.KBArticleIDs[0]);
Console.WriteLine(update.Title);
Console.WriteLine(update.Identity.UpdateID);
Console.WriteLine("IsInstalled=" + update.IsInstalled);
Console.WriteLine("IsDownloaded=" + update.IsDownloaded);
// this line does nothing
update.CopyFromCache("C:\\Test\\", true);
// this returns error code 0
int errorCode = Marshal.GetLastWin32Error();
var update2 = (IUpdate2)update;
var s = new StringCollection();
// this file has been manually downloaded and exists!
s.Add(#"C:\test\Windows6.1-KB2518869-x64.msu");
// this throws the exception (0x80240026 - WU_E_INVALID_UPDATE_TYPE)
update2.CopyToCache(s);
}
Why is the CopyFromCache not doing anything and why is CopyToCache throwing this weird Exception, even if the file does not exist?
API reference: http://msdn.microsoft.com/en-us/library/windows/desktop/aa386101(v=VS.85).aspx
The problem with your code is that the specified update is not a real update.
It is a container for a bundle of updates. Try to copy the file to the cache for the bundled update.
// Example
Console.WriteLine("Bundled update=" + update.BundledUpdates[0].Title);
var s = new StringCollection();
s.Add(#"C:\test\Windows6.1-KB2518869-x64.msu");
((IUpdate2)update.BundledUpdates[0]).CopyToCache(s);

Categories