Windows 8 Metro check if file exists [duplicate] - c#

This question already has answers here:
How to check if file exists in a Windows Store App?
(10 answers)
Closed 9 years ago.
I am trying to write a routine to check if a file exists in a application package. After reading a lot on the subject it's obvious that MS forgot to put a FileExists function in the API (deliberate or not) but here is where I am at so far...
public async Task<bool> CheckFile(string filePath)
{
bool found = false;
try
{
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
StorageFile file = await installedLocation.GetFileAsync("Assets\\" + filePath);
found = true;
}
catch (System.IO.FileNotFoundException ex)
{
found = false;
}
return found;
}
and then called from:
private ImageSource _image = null;
private String _imagePath = null;
public ImageSource Image
{
get
{
if (this._image == null && this._imagePath != null)
{
Task<bool> fileExists = CheckFile(this._imagePath);
bool filefound = fileExists.Result;
string realPath = string.Empty;
if (filefound)
{
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
realPath = installedLocation + "Assets\\" + this._imagePath;
}
else
{
realPath = "http://<<my url>>/images/" + this._imagePath;
}
this._image = new BitmapImage(new Uri(realPath));
}
return this._image;
}
set
{
this._imagePath = null;
this.SetProperty(ref this._image, value);
}
}
SO basically it's a check to see if an image exists locally and if not then go get it from my website.
It all seems to work fine for the first image but then when it gets to "return this._image;" for the second image everything just freezes...
I'm just not sure what's going on here really..
Any help?
Cheers
Dean

Checking for a file and then trying to open that file is a race condition. That is, the file can be removed between the check for existence and the open. So, you shouldn't do it that way. You're right to catch the exception from GetFileAsync from your GetFile, but you should catch a FileNotFoundException and then you know the file did not exist.
Your code for CheckFile does something funny, however. You have an internal try-catch block that will swallow up all exceptions, show a message box and then set found = true no matter what happened in the try block. I don't think that's what you intend. Also, the surrounding try-catch block is not necessary as it will only be hit if creating a new MessageDialog or ShowAsync throw an exception -- that is when you set found to false -- which is not what I think you want.

Related

Unity Firebase Storage - Check if file exists Async

After some advise around calls to firebase storage primarily how (from a sync POV) I should be checking to see if a file exists.
To set the context I am reading in a state file as json using the DownloadCoroutine function below and passing this into a JsonTextReader, this is working fine as long as the file exists in the first place (which as a new user it will not).
So then I wrote the below checkIfFile exists function which also works in a standalone capacity (Grabs the URL to prove that this file does in fact exist). Once this function has completed I then set a bool (SaveFileExists) to say this is/is not an existing file then go create one dependent on the state.
Where my problem lies is the order in which these functions are executed, I need the check to happen before any other methods are executed, they are both called in the LoadScene function currently. What I think I need to do is make the check an Async method returning a task? If so how would this look and where should I be calling it from, I have tried this but I think it keeps locking the main thread.
So the state right now is that because that bool doesnt change in time, the download of the storage file doesnt happen and the Json is never read in and throws an error, at the end of the console output the checkfile URL is outputted, any help would be great ,thanks.
private IEnumerator DownloadCoroutine(string path)
{
var storage = FirebaseStorage.DefaultInstance;
var storageReference = storage.GetReference(path);
if (SaveFileExists == true)
{
var DownloadTask = storageReference.GetBytesAsync(long.MaxValue);
yield return new WaitUntil(predicate: () => DownloadTask.IsCompleted);
byte[] fileContents = DownloadTask.Result;
retrievedSaveFile = Encoding.Default.GetString(fileContents);
Debug.Log("Downloading the save file");
}
else
{
createNewSaveFile(path);
}
}
Check to see if the Json file exists
private void CheckIfFileExists(string path)
{
var storage = FirebaseStorage.DefaultInstance;
var storageReference = storage.GetReference(path);
storageReference.GetDownloadUrlAsync().ContinueWith(task => {
if (!task.IsFaulted && !task.IsCanceled) {
Debug.Log("Download URL: " + task.Result);
SaveFileExists = true;
}
else{
Debug.Log("file doesnt exist so we create one");
}
});
}
Load scene
public IEnumerator LoadLastScene()
{
var User = FirebaseAuth.DefaultInstance.CurrentUser;
Debug.Log("USERID IS " + User.UserId.ToString());
CheckIfFileExists("Saves://" + User.UserId.ToString() + "saveFile.json");
yield return DownloadCoroutine("Saves://" + User.UserId.ToString() +
"saveFile.json");
}
The things you have to do is that
User authentication
Everything must be inside an async task function
check if the file exists
await storageRef.Root.Child(fUser.UserId).Child("Data").GetDownloadUrlAsync().ContinueWith(async task2 =>
{
if (task2.IsFaulted || task2.IsCanceled)
{
Debug.Log("<color=Red>File Not Exists</color>");
}
else
{
Debug.Log("<color=green>File Exists</color>");
await DownloadData();
}
});

Problems with removable storage Hololens 2, unity and xamarin uwp

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.

C# How to get current Powerpoint Presentation File Name?

As you see I have some object in my hand but I couldn't figure out how to get current file name. I am getting _currentSlideName from an xml file and compare to open new slide.
Do you have any suggestion to get current power point presentation file name?
ppt.Application _pptApplication = new ppt.Application();
private void Open(string fileName)
{
_presentation = _pptApplication.Presentations.Open(fileName, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);
}
private void CheckSlide()
{
if (_oSlideShowView == null)
{
try
{
Open( _settingObj.Path + _currentSlideName);
}
catch (Exception)
{
Open(_settingObj.Path+ "Test.pptx" );
}
}
else if (_currentSlideName != _presentation.Path)
{
try
{
Open( _settingObj.Path + _currentSlideName);
}
catch (Exception)
{
Open(_settingObj.Path+ "Test.pptx" );
}
}
}
Getting the full filename of the open presentation is simply Presentation.FullName. In your case, this would be:
_pptApplication.ActivePresentation.FullName
Note that this only returns the presentation's name if the file is not currently saved. If it is not saved, the presentation's Path is an empty string.
EDIT: The example above returns the full filename. If you want only the name, use the following. Just to clarify that this only makes sense with saved presentations, I've added a check on Path.
if(!_pptApplication.ActivePresentation.Path.Equals("")) {
var name = _pptApplication.ActivePresentation.Name
... do processing...
}
else {
... error ...
}

How to Use IsolatedStorage to Set Lock Screen Background in Windows Phone 8

I would like to be able to use an image from my IsolatedStorage to modify the lock screen background, but I am having trouble getting the correct syntax of the IsolatedStorage file path to set the lock screen background.
In following http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206968(v=vs.105).aspx , I am calling the LockHelper method in a button click event once an image has been selected from a List named Recent (which has been populated from PictureRepository.cs which loads images from IsolatedStorage)
private void recent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
capturedPicture = (sender as LongListSelector).SelectedItem as CapturedPicture;
if (capturedPicture != null)
{
//filename is the name of the image in IsolatedStorage
fileName = capturedPicture.FileName;
}
}
void setAsLockScreenMenuItem_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(fileName))
{
//PictureRepository.IsolatedStoragePath is a string = "Pictures"
LockHelper("isostore:/" + PictureRepository.IsolatedStoragePath + "/" + fileName, false); //results in FileNotFoundException
LockHelper(PictureRepository.IsolatedStoragePath + "/" + fileName, false); //results in ArgumentException
}
else
{
MessageBoxResult result = MessageBox.Show("You must select an image to set it as your lock screen.", "Notice", MessageBoxButton.OK);
if (result == MessageBoxResult.OK)
{
return;
}
}
}
Once LockHelper is called, the event proceeds
private async void LockHelper(string filePathOfTheImage, bool isAppResource)
{
try
{
var isProvider = Windows.Phone.System.UserProfile.LockScreenManager.IsProvidedByCurrentApplication;
if (!isProvider)
{
// If you're not the provider, this call will prompt the user for permission.
// Calling RequestAccessAsync from a background agent is not allowed.
var op = await Windows.Phone.System.UserProfile.LockScreenManager.RequestAccessAsync();
// Only do further work if the access was granted.
isProvider = op == Windows.Phone.System.UserProfile.LockScreenRequestResult.Granted;
}
if (isProvider)
{
// At this stage, the app is the active lock screen background provider.
// The following code example shows the new URI schema.
// ms-appdata points to the root of the local app data folder.
// ms-appx points to the Local app install folder, to reference resources bundled in the XAP package.
var schema = isAppResource ? "ms-appx:///" : "ms-appdata:///Local/";
var uri = new Uri(schema + filePathOfTheImage, UriKind.Absolute);
//The Error Occurs Here!
// Set the lock screen background image.
Windows.Phone.System.UserProfile.LockScreen.SetImageUri(uri);
// Get the URI of the lock screen background image.
var currentImage = Windows.Phone.System.UserProfile.LockScreen.GetImageUri();
System.Diagnostics.Debug.WriteLine("The new lock screen background image is set to {0}", currentImage.ToString());
}
else
{
MessageBoxResult result = MessageBox.Show("Cannot update your lock screen background at this time.", "Notice", MessageBoxButton.OK);
if (result == MessageBoxResult.OK)
{
return;
}
}
}
catch (System.Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
The error occurs on Windows.Phone.System.UserProfile.LockScreen.SetImageUri(uri); within the LockHelper method. It is either a FileNotFoundException mentioning The filename, directory name, or volume label syntax is incorrect. (Exception from HRESULT: 0x8007007B) or an ArgumentException. Everywhere I've referenced says for using IsolatedStorage the Uri should be ms-appdata:///local/ and then the IsolatedStorage file path (in my case Pictures/imagename.jpg), and I believe my error lies with the Uri path, but I am unsure of the correct syntax? If it is not this, any other ideas?
This is what worked for me:
const string filePathOfTheImage = "/Shared/ShellContent/shot2.jpg"; //This is where my image is in isostore
var uri = new Uri("ms-appdata:///local" + filePathOfTheImage, UriKind.Absolute);
Also, I use WP Power Tools for tracking my app storage space. Hope this helps.
Try this at nokia developer. Hope you'll get the way to the solution.

FileUpload watin

I need to upload a file in a website using watin. The problem is that setting the direction of the file, like this:
browser.FileUpload(Find.ById("ctl00_cpContent_FileUpload1")).Set(DIRECCION_XML + "plantilla.txt");
doesnt work. Because this, I need to handle the windows popup that appear and fill the direction of the file to upload. I dont know how to do it... I were searching info of FileUploadHandler, but i cant get it.
There is more option than that? Pls, help me with a possible code to do it.
Really thanks
The FileUploadHandler works great. I have it running in production mode with thousands of files being uploaded every day and I haven't had any issues with it so far.
This is the way it needs to be implemented:
EDIT: (I forgot to include the uploadDialog object)
IntPtr hwndTmp = (IntPtr)FindWindow("#32770","Select file(s) to upload"); // or whatever the window text says when you are opening that upload window)
Window uploadDialog = new Window(hwndTmp);
UploadFileDialogHandler uploadFile = new UploadFileDialogHandler(_toBeSent.FileToSent);
_browser.AddDialogHandler(uploadFile);
uploadFile.HandleDialog(uploadDialog);
uploadFile = null;
That will take care of the upload process. when you need to upload the file just those lines will take care of everything (loop thru all open dialogs, find the right one, find the text field, enter the name for you and click the Ok button. On top of that you need to create another class that will be the UploadFileDialogHandler:
public class UploadFileDialogHandler : BaseDialogHandler
{
private const int WmSettext = 0x000C;
private string fileName;
private bool _processed = false;
public override bool HandleDialog(Window window)
{
var button = GetOpenButton(window);
if (button != null)
{
if (_processed == false)
{
var fileNameHandle = NativeMethods.GetChildWindowHwnd(window.Hwnd, "Edit");
var fileNameHwnd = new Hwnd(fileNameHandle);
fileNameHwnd.SetFocus();
_processed = true;
//MessageBox.Show("About to send " + fileName);
fileNameHwnd.SendString(fileName);
button.Click();
}
return true;
}
else
{
return false;
}
}
public UploadFileDialogHandler(string file)
{
fileName = "";
fileName = file;
//MessageBox.Show("Setting filename: " + fileName);
}
public override bool CanHandleDialog(Window window)
{
return GetOpenButton(window) != null;
}
private WinButton GetOpenButton(Window window)
{
var windowButton = new WindowsEnumerator().GetChildWindows(window.Hwnd, w => w.ClassName == "Button" && new WinButton(w.Hwnd).Title == "&Open").FirstOrDefault();
if (windowButton == null)
return null;
else
return new WinButton(windowButton.Hwnd);
}
}
}
You can just copy and paste that class inside your program and with the 4 lines of code above it will take care of the rest for you. In case you need more information there's a good amount of information on the WatIn file source code but it could be a little bit challenging to follow if you don't understand the Windows API.
Hope this helps.
This command work for me fine: browser.FileUpload(Find.ById("FormImage")).Set("C:\\Pictures\\11.PNG");
Try it

Categories

Resources