Edit Music metadata with Windows Runtime API with .net 6 - c#

After some research, I found out how to have my project access the Windows Runtime API.
Now I can happily read the Music properties of my file (Albums, Title etc):
StorageFile sf = await StorageFile.GetFileFromPathAsync(filename);
var props = await sf.Properties.GetMusicPropertiesAsync();
I can read and edit them, but I didn't find a way to persist.
I tried like this:
props.Album = "TEST";
await sf.Properties.SavePropertiesAsync();
Nothing breaks, but nothing changes, and my album is still what it was before.
Am I doing something silly and wrong?

Related

UIAutomation throws AccessViolationException on Windows 11

The issue:
We have an application written in C# that uses UIAutomation to get the current text (either selected or the word behind the carret) in other applications (Word, OpenOffice, Notepad, etc.).
All is working great on Windows 10, even up to 21H2, last update check done today.
But we had several clients informing us that the application is closing abruptly on Windows 11.
After some debugging I've seen some System.AccessViolationException thrown when trying to use the TextPatternRange.GetText() method:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
What we've tried so far:
Setting uiaccess=true in manifest and signing the app : as mentionned here https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/350ceab8-436b-4ef1-8512-3fee4b470c0a/problem-with-manifest-and-uiaccess-set-to-true?forum=windowsgeneraldevelopmentissues => no changes (app is in C:\Program Files\
In addition to the above, I did try to set the level to "requireAdministrator" in the manifest, no changes either
As I've seen that it may come from a bug in Windows 11 (https://forum.emclient.com/t/emclient-9-0-1317-0-up-to-9-0-1361-0-password-correction-crashes-the-app/79904), I tried to install the 22H2 Preview release, still no changes.
Reproductible example
In order to be able to isolate the issue (and check it was not something else in our app that was causing the exception) I quickly made the following test (based on : How to get selected text of currently focused window? validated answer)
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
var p = Process.GetProcessesByName("notepad").FirstOrDefault();
var root = AutomationElement.FromHandle(p.MainWindowHandle);
var documentControl = new
PropertyCondition(AutomationElement.ControlTypeProperty,
ControlType.Document);
var textPatternAvailable = new PropertyCondition(AutomationElement.IsTextPatternAvailableProperty, true);
var findControl = new AndCondition(documentControl, textPatternAvailable);
var targetDocument = root.FindFirst(TreeScope.Descendants, findControl);
var textPattern = targetDocument.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
string text = "";
foreach (var selection in textPattern.GetSelection())
{
text += selection.GetText(255);
Console.WriteLine($"Selection: \"{selection.GetText(255)}\"");
}
lblFocusedProcess.Content = p.ProcessName;
lblSelectedText.Content = text;
}
When pressing a button, this method is called and the results displayed in labels.
The method uses UIAutomation to get the notepad process and extract the selected text.
This works well in Windows 10 with latest update, crashes immediately on Windows 11 with the AccessViolationException.
On Windows 10 it works even without the uiaccess=true setting in the manifest.
Questions/Next steps
Do anyone know/has a clue about what can cause this?
Is Windows 11 way more regarding towards UIAutomation?
On my side I'll probably open an issue by Microsoft.
And one track we might follow is getting an EV and sign the app itself and the installer as it'll also enhance the installation process, removing the big red warnings. But as this is an app distributed for free we had not done it as it was working without it.
I'll also continue testing with the reproductible code and update this question should anything new appear.
I posted the same question on MSDN forums and got this answer:
https://learn.microsoft.com/en-us/answers/questions/915789/uiautomation-throws-accessviolationexception-on-wi.html
Using IUIautomation instead of System.Windows.Automation works on Windows 11.
So I'm marking this as solved but if anyone has another idea or knows what happens you're welcome to comment!

Is there any documentation for the WebView2 DevToolsProtocolHelper

Has anyone seen any documentation on the WebView2 DevToolsProtocolHelper?
In another question I asked (How do I programmatically add a file to a fileupload control from a windows form to a webpage) it was suggested that I download and use the Microsoft.Web.WebView2.DevToolsProtocolExtensions. At first it seemed like it was going to be very straight forward to use but not so much.
Win forms App using c# and webview2
DevToolsProtocolHelper helper = webView21.CoreWebView2.GetDevToolsProtocolHelper()
Task<DOM.Node> t = helper.DOM.GetDocumentAsync();
Task<int> querySelectorResponse = helper.DOM.QuerySelectorAsync(t.Result.NodeId, "#fileupload");
_ = helper.DOM.SetFileInputFilesAsync(new string[] { filename }, querySelectorResponse.Result);
These 4 lines of code should get the document and search for the node fileupload. I get nothing but errors and I have not seen any real examples or documentation on this.
Any help would be greatly appreciated.
**** UPDATE *****
DevToolsProtocolHelper helper = webView21.CoreWebView2.GetDevToolsProtocolHelper();
DOM dom = helper.DOM;
DOM.Node t = await dom.GetDocumentAsync(-1,true);
int querySelectorResponse = await dom.QuerySelectorAsync(t.NodeId, "#fileupload");
_ = helper.DOM.SetFileInputFilesAsync(new string[] { filename }, t.NodeId);
Here is the latest version of my code and it seems I have made progress. When I used CEFSHARP, the IDs I got back from Document and the #fileUpload were always the same and it worked in uploading the file.
With this code above, I am getting IDs but they are always different and I am not getting the file to upload.
Another update, when I run this code (from a button click on the winform) a second time, I do get the proper ID (504) for the int querySelectorResponse = await dom.QuerySelectorAsync(t.NodeId, "#fileupload") line of code. Again, still not getting the file to upload to the page.
Again, any help would be greatly appreciated
The GetDevToolsProtocolHelper documentation is the 'How to' article on Using Chromium DevTools Protocol in WebView2.
Separately, you cannot use Task.Result with WebView2 tasks which I see you doing in the above code. WebView2 can only be used from the UI thread its created on and requires that UI thread to communicate task completions. You should be able to use await instead.

Playing an HDHomeRun stream on a Tizen.NET Xamarin App

I'm trying to play a HDHomeRun Connect Video source from a url in the following format: http://x.x.x.x:xxxx/auto/v4.1. This video source is an MPEG2 video encoding and AC3 audio encoding.
I've tried using the Samsung Tizen.TV .NET sample with the following source but the video never plays.
_player = new Tizen.Multimedia.Player();
var mediaSource = new Multimedia.MediaUriSource(uri);
_player.SetSource(mediaSource);
var display = new Multimedia.Display(Window.Instance);
_player.Display = display;
await _player.PrepareAsync();
The player state gets stuck in preparing, and the await _player.PrepareAsync() call never finishes. It is worth noting that I'm using the Tizen Samsung TV Emulator. Do I need to transcode the stream from the HDHomeRun to be playable? Are there any other measures I might be missing for the Video to play?
Ultimately, the Display property of the player wasn't being set correctly. The property that worked for me (found from investigating the JuvoPlayer code was this:
var display = new Multimedia.Display(((FormsApplication)Forms.Context).MainWindow);
_player.Display = display;
When you are to develop a Tizen .NET application, please be aware of which UI framework your project is targetted for among 3 different types: Xamarin.Forms, (pure) ElmSharp, and Tizen.NUI.
Unless your project is based on the Tizen.NUI framework, you shouldn't use Tizen.NUI.Window.Instance and types in Tizen.NUI namespace in any case. Instead, you will have to use types of ElmSharp or Xamarin.Forms.Platform.Tizen namespace for platform-specific code in your application.
Since the internal implementation of Xamarin.Forms for Tizen is based on ElmSharp, FormsApplication.MainWindow will return a ElmSharp.Window instance which can be used to instantiate a Tizen.Multimedia.Display object. That's why the code in your answer worked.

Retrieving AVPlayerItem from Gallery Asset

I'm trying to play a video using the AVPlayer and an AVPlayerItem.
Im using following code:
asset = AVAsset.FromUrl(new NSUrl(GalleryURL));
playerItem = new AVPlayerItem(asset);
playerItem.AddObserver(this, (NSString)"status", NSKeyValueObservingOptions.OldNew, IntPtr.Zero);
player = new AVPlayer(playerItem);
the property GalleryURL is one of the following:
1.) When saving a video to the gallery, i get this url from the ALAssetsLibrary instance call: WriteVideoToSavedPhotosAlbum(url, (galleryPath, error) => { ... });
where "galleryPath" is something like this:
file:///var/mobile/Containers/Data/Application/0D510365-4A63-425B-840C-A4E18BD870A8/Documents/...
this works fine, I can create the AVAsset and retrieve the AVPlayerItemStatus, especially the status "ReadyToPlay", via the added Observer.
2.) However when I retrieve a Video from the gallery, the url looks different:
assets-library://asset/asset.MOV?id=EB9FC214...
and in this case I'm not able to retrieve a working AVAsset
How can I get part 2 to create a working AVAsset, which I can use for video playback? I believe this works in iOS versions prior to iOS 11.
Landu Lu - MSFT helped me to find the answer:
He told me that there are 2 paths that I receive from the UIImagePickerController:
The asset-library path could not be used, maybe I have to remove the "assets-library:" part? but the path beginning with "file://" could be used. The problem of the plugin was, that the start of the url was cut off, there was no "file://" at the beginning. I manually added this string and it works! Thanks alot!

How do you check if a storagefolder is null c#

I'm surprised this has not come up before and im thinking im just not using the right search terms but been stuck on this for an hour now.
heres the issue, when some one presses the roll button on my app i want a folder picker to appear and allow the person to pick a folder, then the files are saved in that folder. I only want it to run once.
heres what i have
FolderPicker folder =new FolderPicker();
folder.FileTypeFilter.Add(".html");
folder.ViewMode = PickerViewMode.List;
folder.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
folder.SettingsIdentifier = "folder";
theFolder = await folder.PickSingleFolderAsync();
StorageFile file = await theFolder.CreateFileAsync(name + ".html", CreationCollisionOption.ReplaceExisting);
this works but ofcourse the picker appears every time i run the method (as its setup to do at the moment.
StorageFolder theFolder set up at the start of the programs run simply as
public StorageFolder theFolder;
i have tried changing
theFolder = await folder.PickSingleFolderAsync();
to
while (theFolder.Equals(null))
{
theFolder = await folder.PickSingleFolderAsync();
}
but that just causes a crash
"Object reference not set to an instance of an Object."
i also tried getting the display name of the folder and if it was blank then getting the folderpicker to show...same error
I can not even just have the folder picker show every time the person clicks run as a click of cancel will crash it (and it would be very annoying to the user)
any ideas ?
my app is a universal app in c# for windows phone and store, it is the windows store version im currently working on
If variable is null you can't call method on it.
while (theFolder == null)
{
theFolder = await folder.PickSingleFolderAsync();
}

Categories