Saving System.Comment or System.Subject file properties in uwp - c#

I would like to associate a GUID with my StorageFile, to make it easier to test whether or not two files are derived from the same source.
I'm trying to save the GUID in a file property:
private static string GuidProperty = "System.Comment"; // also tried "System.Subject".
static public async Task<Guid> GetGuidAsync( StorageFile file)
{
var properties = await file.Properties.RetrievePropertiesAsync(new string[] { GuidProperty });
if (!(properties[GuidProperty] is string guidString)) {
throw new InvalidOperationException("Missing GUID on file.");
}
return new Guid(guidString);
}
static public async Task InitializeGuidAsync( StorageFile file)
{
var properties = await file.Properties.RetrievePropertiesAsync(new string[] { GuidProperty });
properties[GuidProperty] = Guid.NewGuid().ToString();
await file.Properties.SavePropertiesAsync(properties);
}
This doesn't work. When it gets to SavePropertiesAsync it throws a COMException saying "Error HRESULT E_FAIL as been returned from a call to a COM component."
The file is an SQLite database in the app directory, with a custom file extension.
How can I tag this file with a GUID?
P.S. After some poking around ... maybe the problem is that I have not registered the file property handlers for the custom file type. Not sure how to do that yet.

The problem is that the custom file type does not support storing of properties.
Properties are stored inside the file and are written and read by Windows 10 using property handlers that you implement.
The following page discusses properties in Windows 10: https://msdn.microsoft.com/en-us/library/windows/desktop/bb776859(v=vs.85).aspx
With respect to using SQLite as a document format, unfortunately, the SQLite file can only be accessed when it is in the app dir. Consequently it is highly inefficient to support file properties because reading or writing the property requires copying the file to the app dir and back.

Related

Handle files from OnFileActivated()

I have problem with handling files passed to my application in OnFileActivated(). First, I've registred specific file extention in Package.appminifest of my application, so after tap into specific file my application starts and run OnFileActivated function.
In my case file is archive zipped with System.IO.Compression.ZipArchive, but I think it's not crutial here. Beggining of my function looks as follow:
protected override async void OnFileActivated(FileActivatedEventArgs args) {
base.OnFileActivated(args);
var file = args.Files[0];
using (var archive = ZipFile.OpenRead(file.Path)) {
...
As some of you can expect I get an error when I'm trying to access file in last line. I also tried different solutions as copying file into local folder and then access it, but also without luck.
Question
Is there any way to do such thing? Or maybe I'm doing it completely wrong way?
Using the Path property will not be useful for a brokered file (such as you get from Activation). Use the constructor that takes a Stream instead.
Here is the correct answer:
protected override async void OnFileActivated(FileActivatedEventArgs args) {
base.OnFileActivated(args);
var file = (StorageFile)args.Files[0];
using (var archive = new ZipArchive(await file.OpenStreamForReadAsync())) {
...
I haven't noticed before that ZipArchive have constructor which takes stream as a parameter.

how to get file extension (not from its name or from contentType)

i just want to know the posted file extension type,
public static void UploadFile(HttpPostedFile file)
{
....
if (file != null && file.ContentLength > 0)
{
string fileName = file.FileName;
string contentType = file.ContentType;
file.SaveAs(path);
}
}
the above code gives us the contentType
but if we change the extension by hand for example if i change untitled.exe to untitled.txt contentType becomes text. but i want to know it is an exe.
is it possible?
or the other way is safe? (i think no)
It is not possible to determine original extension of a file if user has manually changed it before uploading. However some file types have headers that can be used to terminate what type of file it is. Example may be office docs, pdfs... You simply must be carefully when excepting arbitrary file from unknown sources. Extensions are for the most part a Windows feature some other os types do not use or rely on them.
What you are asking about is file identification based on it's signature. This is not 100% guaranteed to work but there are utilities that can help you with this.
For instance TrID has a database of signatures that it can attempt to match the file for you and can optionally rename it as well.
File Identifier is another one.
If you are saving the file and want to keep users from getting you to save files with specific extensions on your system then you can of course check the extension using the FileInfo class. Something like this...
var invalidExtensions = new List<string>() { ".exe", ".dll" };
...
var fileInfo = new FileInfo(file.FileName);
if (invalidExtensions.Contains(fileInfo.Extension.ToLower()))
{
// Do your cleanup on the filename because it's an extension you don't want
// to save...
}

Argument Null Exception error when trying to create a Text File

Problem:
I am trying to create a text file from a web service (local host), but on creation it gets the null argument error for path location. Now I am still using 2012 and was under the impression the code I gave would return the path name, but just returns null.
Aim:
Create a new file if one doesn't exist.
Get the path of the file for future use.
Question:
What are the visual studio 2012 C# methods for creating a text file? I find allot of sources but the code doesn't seem to work with 2012.
My Code:
//Create a file name for the path
string path = System.IO.Path.Combine(CurrentDirectory, "textFile.txt");
//Check if it exist, if not then create the File
//This is the recommended code by Microsoft
if (!System.IO.File.Exists(path))
{
System.IO.File.Create(path);
}
Get the file path using Server.Map path
string FolderPath = Server.MapPath("~/App_Data");
string file = Path.Combine(FolderPath, "textFile.txt");
//Check if it exist, if not then create the File
//This is the recommended code by Microsoft
if (!System.IO.File.Exists(file))
{
System.IO.File.Create(file);
}
Also check if the IIS user have permission to write on that folder (Add permission to the application pool user)
If you are trying to write something on a txt file, these piece of code does. No need to create a file if it is not exist. These code will create a file automatically if it not exists.
public static void LogMessage(string sFilePath, string sMsg)
{
using (StreamWriter sw = File.AppendText(sFilePath))
{
sw.WriteLine(string.Format(#"{0} : {1}", DateTime.Now.ToLongTimeString(), sMsg));
}
}
Are you sure CurrentDirectory value is right?
If you want visit current Web Service root dir can use like AppDomain.CurrentDomain.BaseDirectory.

How to download and upload file to SkyDrive via Live Connect SDK

I have an app that I want to download & upload a simple .txt file with a URL inside. I have downloaded Live Connect SDK V5.4, referenced the documentation, but it appears that the documentation is incorrect. The sample code uses event handlers for when a download/upload is complete, but that no longer can be used in V5.4.
I have two methods, downURL & upURL. I have started working on downURL:
private async void downURL()
{
try
{
LiveDownloadOperationResult download = await client.DownloadAsync("URL.txt");
}
catch { }
}
I am not sure what I am suppose to use for the path, I put "URL.txt" for now, I've seen some examples with "/me/". Do I need this? The file does not need to be visible to the user, as the user can't really do anything with it, but it is vital for the app to work.
My question is how do I use the LiveDownloadOperationResult download to save the file to Isolated Storage Settings, get the text contents, and put that in a string? Also, if you know how to upload the file back up, the upload event handler looks the same (but without the Result variable).
This code help you download content a file which you want. It get content have format OpenXML
Here, "item.id" is Id of "URL.txt".
private async void downURL()
{
try
{
LiveDownloadOperationResult operationResult = await client.DownloadAsync(item.id + "/Content?type=notebook");
StreamReader reader = new StreamReader(operationResult.Stream);
string Content = await reader.ReadToEndAsync();
}
catch { }
}

Deploy an application's xml file with installer or create it on the fly if it does not exist

I am having an xml file like:
<CurrentProject>
// Elements like
// last opened project file to reopen it when app starts
// and more global project independend settings
</CurrentProject>
Now I asked myself wether I should deliver this xml file with above empty elements with the installer for my app or should I create this file on the fly on application start if it does not exist else read the values from it.
Consider also that the user could delete this file and that should my application not prevent from working anymore.
What is better and why?
UPDATE:
What I did felt ok for me so I post my code here :) It just creates the xml + structure on the fly with some security checks...
public ProjectService(IProjectDataProvider provider)
{
_provider = provider;
string applicationPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
_projectPath = Path.Combine(applicationPath,#"TBM\Settings.XML");
if (!File.Exists(_projectPath))
{
string dirPath = Path.Combine(applicationPath, #"TBM");
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
using (var stream = File.Create(_projectPath))
{
XElement projectElement = new XElement("Project");
projectElement.Add(new XElement("DatabasePath"));
projectElement.Save(stream, SaveOptions.DisableFormatting);
}
}
}
In a similar scenario, I recently went for creating the initial file on the fly. The main reason I chose this was the fact that I wasn't depending on this file being there and being valid. As this was a file that's often read from/written to, there's a chance that it could get corrupted (e.g. if the power is lost while the file is being written).
In my code I attempted to open this file for reading and then read the data. If anywhere during these steps I encountered an error, I simply recreated the file with default values and displayed a corresponding message to the user.

Categories