Now I'm trying to make UWP application with VS2017 using C#. I use CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists) to create two files at the initial time, to open them afterwards. However it stopped during opening the second file(F5, F10, F11 buttons doesn't work during debugging). It runs cool during Creating files or opening the first file. Here is my code.
public static StorageFile GetDataFileFromLocalFolder(string fileName)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException("fileName missing");
}
return GetDataFileFromLocalFolderAsync(fileName).Result;
}
private static async Task<StorageFile> GetDataFileFromLocalFolderAsync(string fileName)
{
var sFolder = ApplicationData.Current.LocalFolder;
var sFile = await sFolder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
return sFile;
}
Is there any problem? Shouldn't use OpenIfExist option?
I solve this problem as avoiding await keyword.
public static async Task<StorageFile> GetDataFileFromLocalFolderAsync(string fileName)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException("fileName missing"); //remove hard coded string here
}
var sFolder = ApplicationData.Current.LocalFolder;
var sFileTask = sFolder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
var sFile = sFileTask.AsTask().Result;
return sFile;
}
Now it works fine. but never knows why....
Related
I am currently working on a program on WinForms on Visual Studio Community 2022. The program has to check if a file exists on the install directory using File.Exists(), but there is a really weird behaviour that I cannot seem to solve: when debugging (and even running it in the Release mode) the application on VS2022, the value the method returns is false (which is right, because the file doesn't exist at the moment of running the method), but when installing the application, it says the file exists, even when it doesn't, and it can even read the content of that file. Here's the code:
private static string AppPath = $#"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\eMA\eMA";
public async Task<JArray> GetVersionsJArrayFromComputer()
{
JArray versionsJArray = new JArray();
await Task.Run(async () =>
{
string path = AppPath;
if (!await CheckIfVersionJSONFileExists())
{
if (!await IsRunningAsAdmin())
{
await RunAsAdmin();
Environment.Exit(0);
}
else
{
await SaveVersionJSONFile(await SetVersionsJArrayFromComputer());
}
}
string versionFilePath = $#"{path}\version.json";
string versionFile = File.ReadAllText(versionFilePath);
versionsJArray = (JArray)JsonConvert.DeserializeObject(versionFile);
});
return versionsJArray;
}
private static async Task<bool> CheckIfVersionJSONFileExists()
{
bool fileExists = false;
await Task.Run(() =>
{
string path = AppPath;
string fileName = $#"{path}\version.json";
fileExists = File.Exists(fileName);
});
return fileExists;
}
I created some MessageBoxes to try to debug the application when it is already installed, and this is what it says:
This is the content that it reads from the file (and, in theory, if the file doesn't exist, it shouldn't have any content):
And I don't really know why would it say the file doesn't exist when debugging and then it exists when installed. Any help would be really appreciated.
I'm relatively new to software development for the Hololens 2 and have a pretty big problem I've been messing around with for a long time and I'm slowly running out of ideas.
My project looks like this. I've written a Unity application to capture data and store it in a database (sqlite). A Xamarin.Forms UWP application is supposed to take the data from the database and use it to paint charts for better visualisation. The big problem is, both apps need to be able to access the same database on the Hololens 2. I thought that I could be the database on a usb stick and both apps could access the usb stick. In the Xamarin app and in the Unity app "removable storage" is enabled. In the Xamarin App I have made the file extension known under Appmanifest declaration. I am trying to get the connection with the following commands:
namespace ARScoliosis.XamarinApp.UWP.Services
{
public class DatabasePath : IDatabasePath
{
public async Task<string> GetLocalFilePath()
{
var messageDialog = new MessageDialog("No Usb connection has been found.");
StorageFolder externalDevices = KnownFolders.RemovableDevices;
if(externalDevices == null)
{
messageDialog.Commands.Add(new UICommand("No Devices", null));
}
StorageFolder usbStick = (await externalDevices.GetFoldersAsync()).FirstOrDefault(); <---According to debugging it stops here and jumps to optionsBuilder.UseSqlite($"Filename={databasePath}");
if (usbStick == null)
{
messageDialog.Commands.Add(new UICommand("No UsbStick", null));
}
var usbStickFolder = await usbStick.CreateFolderAsync("DB", CreationCollisionOption.OpenIfExists);
if (usbStickFolder == null)
{
messageDialog.Commands.Add(new UICommand("No Folder", null));
}
var file = await usbStickFolder.CreateFileAsync("Database.db", CreationCollisionOption.OpenIfExists);
if(file == null)
{
messageDialog.Commands.Add(new UICommand("No File", null));
}
//var success = await Launcher.LaunchFileAsync(file);
return file.ToString();
}
My dbcontext file looks something like this:
namespace XamarinApp.Authentication
{
public partial class DBContext : DbContext
{
public DBContext()
{
this.Database.EnsureCreated(); <--- Microsoft.Data.Sqlite.SqliteException: "SQLite Error 14: 'unable to open database file'."
this.Database.Migrate();
}
public virtual DbSet<ItemData> ItemDatas { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
var databasePath = DependencyService.Get<IDatabasePath>().GetLocalFilePath();
optionsBuilder.UseSqlite($"Filename={databasePath}");
}
}
namespace XamarinApp.Helpers
{
public interface IDatabasePath
{
Task<string> GetLocalFilePath();
}
}
Unfortunately this code does not find the Usb stick on the Hololens, i think. When I look in file explorer, I see the stick with all its data. In the Unity App, the stick is also not found, although I use the same code here, only slightly modified.
Does anyone know where my error lies, why I can't access the USB stick with either of the two apps? Has anyone tried something similar and knows how to do it?
i would like to thank you in advance for your help.
Thank you very much.
****Hi Hernando - MSFT,
Please excuse my late reply. i had somehow forgotten. I have found a way where I can find my database on the usb stick.
public static async Task<string> GetUsbStick()
{
StorageFolder UsbDrive = (await Windows.Storage.KnownFolders.RemovableDevices.GetFoldersAsync()).FirstOrDefault();
if (UsbDrive == null)
{
throw new InvalidOperationException("Usb Drive Not Found");
}
else
{
IReadOnlyList<StorageFile> FileList = await UsbDrive.GetFilesAsync();
var Path = UsbDrive.Path.Replace('\\','/');
foreach (StorageFile File in FileList)
{
var DBFound = File.Name.Contains("test.db");
if (DBFound == true)
{
return Path + File.Name;
}
}
throw new InvalidOperationException("DataBaseNotFound");
}
}
There I get the exact path for the database output. Only that somehow brings nothing. I cannot open it in the next step. "Sqlite cant open database" it says.
public static async Task<int> Init()
{
try
{
DatabasePath = await GetUsbStick();
StrConnDatabase = "Data Source" + "=" + DatabasePath + ";Mode=ReadWrite;";
}
catch (Exception io)
{
IsInit = false;
throw new InvalidOperationException(io.Message);
}
finally
{
//Try to Open Database to Read
using (var db = new Microsoft.Data.Sqlite.SqliteConnection(StrConnDatabase))
{
try
{
db.Open(); //<- here it breaks off
db.Close();
IsInit = true;
}
catch (Exception io)
{
throw new InvalidOperationException(io.Message);
}
}
}
return 1; // Succes
}
What could be the reason that this does not work?
is there a way to create a working copy within the app, which is then written back to the usb stick?
KnownFolders.RemovableDevices doesn't be supported on the HoloLens, for more information please see:Known folders. It is recommended to take a try at File pickers to pick one file manually.
I'm writing my first Windows Phone 8 app, and I'm just trying something simple. Read / Write file. Here's my two methods:
public static async Task<Week> Load()
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
try
{
StorageFile mealsFile = await folder.GetFileAsync("file.txt");
if (mealsFile != null)
{
using (var stream = await mealsFile.OpenAsync(FileAccessMode.Read))
{
var serializer = new DataContractSerializer(typeof(List<MyTypeHere>));
var w = (List<MyTypeHere>)serializer.ReadObject(stream.AsStreamForRead());
if (w != null)
MyWeek.WeekList = new ObservableCollection<MyTypeHere>(w);
}
}
}
catch(FileNotFoundException fEx)
{
MyWeek = new Week();
}
return MyWeek;
}
public static async Task<bool> Save()
{
try
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile mealsFile = await folder.CreateFileAsync("file.txt", CreationCollisionOption.ReplaceExisting);
using (var stream = await mealsFile.OpenAsync(FileAccessMode.ReadWrite))
{
using (var sw = stream.GetOutputStreamAt(0))
{
var serializer = new DataContractSerializer(typeof(List<MyTypeHere>));
serializer.WriteObject(sw.AsStreamForWrite(), MyWeek.WeekList.ToList());
await sw.FlushAsync();
}
}
MyWeek = null;
return true;
}
catch(Exception ex)
{
return false;
}
}
I'm calling the Save (with breakpoint it works fiine), then call Load (with breakpoint) which load the file, the file exists and it populate my object graph.
When I close the app and restart it, the catch of the FileNotFoundException is caught. Why?
From what I can see the Local Folder is supposed to be persisting the file. What I'm missing that obviously should be obvious...
Thanks
Edit:
I'm using the Windows Phone emulator, and when I close it and hit F5 on Visual Studio, the file is not there anymore.
Apparently by closing the emulator, the files in Local Storage are lost, thanks to #cdndevs via Twitter. I was closing the emulator each time I was stopping debugging instead of letting the emulator simply "stay" there between restart.
By stopping debugging and restarting the app without closing the emulator, the files are there. Well, not super intuitive I must admit, or it might just be me. Hope that help other people like me ;).
I'm trying to share an image through my app, everything works just fine when I run the app on my phone through visual studio, but when I try to run it from my phone, it crashes everytime I click the share button
private async void dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
args.Request.Data.Properties.Title = "Let's Celebrate";
args.Request.Data.Properties.Description = "It's time to celebrate!";
DataRequestDeferral deferral = args.Request.GetDeferral();
try
{
var finalImg = await GenerateImage();
var folder = Package.Current.InstalledLocation;
const CreationCollisionOption option = CreationCollisionOption.ReplaceExisting;
var file = await folder.CreateFileAsync("letscelebrateshare.png", option);
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
var pixelBuffer = await finalImg.GetPixelsAsync();
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)finalImg.PixelWidth,
(uint)finalImg.PixelHeight,
logicalDpi,
logicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
StorageFile logoFile =
await Package.Current.InstalledLocation.GetFileAsync("letscelebrateshare.png");
List<IStorageItem> storageItems = new List<IStorageItem>();
storageItems.Add(logoFile);
args.Request.Data.SetStorageItems(storageItems);
}
}
finally
{
deferral.Complete();
}
}
private async void bla... [..]
{
Exception exc= null;
try
{
//All your stuff
}
catch(Exception ex)
{
exc = ex;
}
if(exc!=null)
await msg.ShowAsync();
}
Edit: Since I don't use WP in C#. I guess you could try this. Hope this helps ^^
I had the same issue while opening a file open picker. I found a weird solution. When I removed the navigation parameters in every pages and used static variables instead, worked fine for me. I guess this will help you
If the App is there crashing without debugger, try while debugging and the share targets are visible to "suspend and shutdown" ("Lifecycle Events" in visual studio). In most cases you app will then crash because it is suspended and serialize the data.
I am trying to figure out how to port some .Net code that parsed an xml file to WinRT. So far, with the help of The given System.Uri cannot be converted into a Windows.Foundation.Uri, I have the below code. Still, I get stuck immediately after I create the Uri:
static readonly Uri ResourcesBase = new Uri(#"ms-resource://MyAssembly/");
public override async void Load()
{
Uri uri = new Uri(ResourcesBase, filePath); // filePath = "Data//world.xml";
XmlLoadSettings settings = new XmlLoadSettings() { ValidateOnParse = false };
XmlDocument xmlDoc = await XmlDocument.LoadFromUriAsync(uri, settings);
foreach (IXmlNode xmlNode in xmlDoc.ChildNodes)
{
ProcessNode(xmlNode);
}
}
I get an unhandled exception when I try to call XmlDocument.LoadFromUriAsyn(uri):
ArgumentException was unhandled by the user code - Value does not fall within the expected range.
Anyone else feel like everything is 10 times harder with WinRT?
EDIT:
I have tried all the following strings, and get the exact same error:
Uri uri = new Uri("ms-resource://MyAssembly//" + filePath);
Uri uri = new Uri("ms-resource://MyAssembly/" + filePath);
Uri uri = new Uri("d:\\projects\\crystal\\" + filePath); // A valid absolute path
Project Set Up:
Project
Properties
References
Assets
Data
world.xml
Source code...
In Code:
filePath = "Data\\world.xml";
I have also tried putting the xml file under assset\data, and just assets. Nothing seems to make a difference.
Another thing, I have the Build Action of the xml set to "Content". Is that correct? The only other thing I could imagine that it would be is "Embedded Resource" but I doubt it.
Full Exception details:
System.ArgumentException was unhandled by user code
HResult=-2147024809
Message=Value does not fall within the expected range.
Source=Windows.Data.Xml.Dom
StackTrace:
at Windows.Data.Xml.Dom.XmlDocument.LoadFromUriAsync(Uri uri, XmlLoadSettings loadSettings)
at Crystal.IO.File.XmlFileSerializer.d__1.MoveNext() in d:\Projects\Crystal\library\IO\File\XmlFileSerializer.cs:line 32
InnerException:
Download the smallest example possible to repro the issue: test_xml.zip
I finally figured it out after I looked at Windows Runtime Xml data API sample.
public override async Load()
{
var file = await GetPackagedFile("assets", "world.xml");
LoadXml(file);
}
private async void LoadXml(StorageFile file)
{
XmlLoadSettings settings = new XmlLoadSettings() { ValidateOnParse = false };
XmlDocument xmlDoc = await XmlDocument.LoadFromFileAsync(file, settings);
foreach (IXmlNode xmlNode in xmlDoc.ChildNodes)
{
//ProcessNode(xmlNode);
}
}
private async Task<StorageFile> GetPackagedFile(string folderName, string fileName)
{
StorageFolder installFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
if (folderName != null)
{
StorageFolder subFolder = await installFolder.GetFolderAsync(folderName);
return await subFolder.GetFileAsync(fileName);
}
else
{
return await installFolder.GetFileAsync(fileName);
}
}
}