Directory Not Found Exception or FileNotFoundException on VLC.DotNet - c#

Using the VLC library provided by Vlc.DotNet, I have tried to implement it in a simple WPF.
I copied exactly the code from the repository, and got the NuGet online, but can't seem to make it work. I get a Directory Not Found exception straight from the load of the file on the disk.
Here is my code:
public MainWindow()
{
InitializeComponent();
VLCControl.MediaPlayer.VlcLibDirectoryNeeded += OnVlcControlNeedsLibDirectory;
}
private void OnVlcControlNeedsLibDirectory(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
{
var currentAssembly = Assembly.GetEntryAssembly();
var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
if (currentDirectory == null)
return;
if (AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
e.VlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(currentDirectory, #"..\..\..\lib\x86\"));
else
e.VlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(currentDirectory, #"..\..\..\lib\x64\"));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var d = new Microsoft.Win32.OpenFileDialog();
d.Multiselect = false;
if (d.ShowDialog() == true)
{
Uri src = new Uri(d.FileName);
VLCControl.MediaPlayer.Play(src); //Exception here
}
}
VLCControl being the VLC control in the xaml.
By changing the VlcLibDirectory with another path where I put the libraries (for example the root of application), I get this StackTrace :
at Vlc.DotNet.Core.Interops.VlcInteropsManager..ctor(DirectoryInfo dynamicLinkLibrariesPath)
at Vlc.DotNet.Core.Interops.VlcManager..ctor(DirectoryInfo dynamicLinkLibrariesPath)
at Vlc.DotNet.Core.Interops.VlcManager.GetInstance(DirectoryInfo dynamicLinkLibrariesPath)
at Vlc.DotNet.Core.VlcMediaPlayer..ctor(DirectoryInfo vlcLibDirectory)
at Vlc.DotNet.Forms.VlcControl.EndInit()
at Vlc.DotNet.Forms.VlcControl.Play(Uri uri, String[] options)
at VLCTest.MainWindow.Button_Click(Object sender, RoutedEventArgs e) in c:\Users\ME\Documents\Visual Studio 2013\Projects\VLCTest\VLCTest\MainWindow.xaml.cs:ligne 56
The code becomes :
if(AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
e.VlcLibDirectory = new DirectoryInfo(currentDirectory);
else
e.VlcLibDirectory = new DirectoryInfo(currentDirectory);
Thank you for your help.

The problem is definitely with your library path, though you have to debug the problem yourself in order to find the exact discrepancy between provided path and actual path.
The misunderstanding may be, which libraries are missing. You do have the Vlc.DotNet.Core.Interops.dll but your are missing the nativ libraries behind. This is the reason, why the exception occurs inside Vlc.DotNet.Core.Interops.dll when it tries to load the actual libraries.
The OnVlcControlNeedsLibDirectory function is called inside VLCControl.MediaPlayer.Play(src);, so the Path from OpenFileDialog has nothing to do with the problem.
Steps I taken to reproduce / fix:
Downloaded your project
Tested / Debugged
Exception occurred as you describe
Downloaded the libraries from Vlc.DotNet repository
Changed the paths to absolute values
Tested / Debugged again
Successfully played a music file
Another exception occured on closing (different story alltogether)
My folder layout:
Solution path:
D:\Programmierung\VLCTest-VAlphaTesting\VLCTest-VAlphaTesting\
Actual Assembly location on execute
D:\Programmierung\VLCTest-VAlphaTesting\VLCTest-VAlphaTesting\VLCTest\bin\Debug
ProcessorArchitecture: x86
Library Path:
D:\Programmierung\Vlc.DotNet-master\Vlc.DotNet-master\lib\x86
Contents of library path:
plugins (folder)
.keep (file)
libvlc.dll (file)
libvlccore.dll (file)
For testing purposes I hardcoded the library path - you may want to do that as well
if (AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
e.VlcLibDirectory = new DirectoryInfo(#"D:\Programmierung\Vlc.DotNet-master\Vlc.DotNet-master\lib\x86");
else
e.VlcLibDirectory = new DirectoryInfo(#"D:\Programmierung\Vlc.DotNet-master\Vlc.DotNet-master\lib\x64");

Related

VisualStudio Express 2012: StreamReader gives [System.UnauthorizedAccessException] error

I have read a lot of answers on this issue, but none of them helps for me.
Now, it's been 5 years that I had C# and apperantly I've forgotten it all. But I like to get into the language again to use it for automation. So, here is the bit of code I already have:
{
string path = #"C:\Users\decraiec\Documents\Client Automated";
//In this folder I will find all my XML files that I just want to load in a textbox
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//create a way to read and write the files
//go get the files from my harddrive
StreamReader FileReader = new StreamReader(path);
//make something readable for what you have fetched
StreamWriter FileWriter = new StreamWriter(textBox1.ToString());
int c = 0;
while (c == FileReader.Read())
{
string load = FileReader.ReadToEnd();//read every xmlfile up to the end
string stream = FileWriter.ToString();//make something readable
}
try
{
textBox1.Text = FileWriter.ToString();//what you have made readable, show it in the textbox
FileWriter.Close();
}
finally
{
if (FileReader != null)
{ FileReader.Close(); }
}
if (FileWriter != null)
{ FileWriter.Close(); }
}
}
If I run this code like this I'll get:
An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
Additional information: Access to the path 'C:\Users\decraiec\Documents\Atrias Automated' is denied.
While I was hoping to see all the XML files in the textbox listed and clickable ( - although I need to insert the clickable code yet )
I've been looking in my folder and subfolder and files and I do have admin rights on everything. About the [ mscorlib.dll ] I have no clue where to find this.
Now if I wrap the StreamReader in a use ( var....;) VS doesn't recognizes it (red lines under the words) saying that I'm missing an instance of an object or something else of issue (just trying to glue the things together).
Could someone try to get me in the right direction please?
I think your path is a directory, not a file. Almost the exact same issue was addressed here: Question: Using Windows 7, Unauthorized Access Exception when running my application
What you can do is create a DirectoryInfo object on the path and then call GetFiles on it. For example:
DirectoryInfo di = new DirectoryInfo(directoryPath);
Foreach(var file in di.GetFiles())
{
string pathToUseWithStreamReader = file.FullName;
}
You need to use Directory.GetFiles to get any files residing in your "Client Automated" folder, then loop through them and load every single file into the stream.
var files = Directory.GetFiles(path);
foreach (var file in files)
{
var content = File.ReadAllText(file);
}
You can read more on it here:
https://msdn.microsoft.com/en-us/library/07wt70x2(v=vs.110).aspx
Also - in general, when working with files or directories like this, it's a good idea to programmatically check if they exist before working with them. You can do it like so:
if (Directory.Exists(path))
{
...
}
Or with files:
if (File.Exists(path))
{
...
}

Closed Captions resolving error System.UnauthorizedAccessException

So, I'm trying to implement closed captions support to my UWP video player (using MediaElement), I've followed this example to do so.
I'm getting an error when resolving it called "Error resolving track due to error NetworkError System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
I do it like this: I open a file using filepicker and then get the SRT of the video that was picked. After that I show it. Unfortunately, nothing appears.
Here is my OpenButton function:
private async void BtnOpenMedia_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
filePicker.FileTypeFilter.Add(".mp4");
filePicker.FileTypeFilter.Add(".wmv");
filePicker.FileTypeFilter.Add(".mpg");
filePicker.FileTypeFilter.Add(".mpeg");
filePicker.FileTypeFilter.Add("*");
StorageFile storageFile = await filePicker.PickSingleFileAsync();
if (storageFile != null && mElement != null)
{
string strSource = Path.GetDirectoryName(storageFile.Path) + #"\" + storageFile.DisplayName + ".srt";
var mediaSource = MediaSource.CreateFromStorageFile(storageFile);
var ttsStream = TimedTextSource.CreateFromUri(new Uri(strSource));
ttsStream.Resolved += TtsStream_Resolved;
mediaSource.ExternalTimedTextSources.Add(ttsStream);
var mediaPlayback = new MediaPlaybackItem(mediaSource);
mElement.SetPlaybackSource(mediaPlayback);
}
}
Here is my resolve function:
private void TtsStream_Resolved(TimedTextSource sender, TimedTextSourceResolveResultEventArgs args)
{
if (args.Error != null)
{
var ignoreAwaitWarning = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var msg = new MessageDialog("Error resolving track " + " due to error " + args.Error.ErrorCode + " " + args.Error.ExtendedError);
await msg.ShowAsync();
});
return;
}
}
P.S: Also, I don't know if this is duplicated or not, that's why I'm adding it in this but I've done my research and found nothing. How to preview frames of MediaElement ? For example like YouTube you can preview thumbnails in the slider, I don't know how to achieve that, thanks!
You used a FileOpenPicker to select the Video file, but use a Path to access the .srt file. The .srt file is also in the Video file's folder. I reproduced your problem here:
The error message is clear, you have no access to this file, this file indicates the .srt file, so the problem is where did you store this .srt file. Just have a test, seems TimedTextSource.CreateFromUri(Uri) | createFromUri(Uri) method does not support to access the files in the local machine, but you can use TimedTextSource.CreateFromStream(IRandomAccessStream) | createFromStream(IRandomAccessStream) method for example like this:
if (storageFile != null && mElement != null)
{
//string strSource = Path.GetDirectoryName(storageFile.Path) + #"\" + storageFile.DisplayName + ".srt";
var fileSource = await KnownFolders.VideosLibrary.GetFileAsync(storageFile.DisplayName + ".srt");
IRandomAccessStream strSource = await fileSource.OpenReadAsync();
var mediaSource = MediaSource.CreateFromStorageFile(storageFile);
//var ttsStream = TimedTextSource.CreateFromUri(new Uri(strSource));
var ttsStream = TimedTextSource.CreateFromStream(strSource);
ttsStream.Resolved += TtsStream_Resolved;
mediaSource.ExternalTimedTextSources.Add(ttsStream);
var mediaPlayback = new MediaPlaybackItem(mediaSource);
mediaPlayback.TimedMetadataTracksChanged += (sender1, args) =>
{
mediaPlayback.TimedMetadataTracks.SetPresentationMode(0, TimedMetadataTrackPresentationMode.PlatformPresented);
};
mElement.SetPlaybackSource(mediaPlayback);
}
When using this code, the .srt file and video file should in the Video lib and the capability "Videos Library" should be enabled in the manifest.
In an UWP app, you can only access the files in known folder like picture lib, music lib and video lib and doc lib or local folder of your app, if your video is not in these folders, you should also handle the exception when access is denied in this scenario.
How to preview frames of MediaElement ? For example like YouTube you can preview thumbnails in the slider.
For this question, I can't find any ready-made sample for you, but I think the scenario 4 of official Media editing sample can be a direction, it shows a overlay layer on MediaElement, maybe you can set the "baseVideoFile" and the "overlayVideoFile" with the same source. The problem is when and where to show this overlay layer, it's related to the transport control of MediaElement. This is for now just a mind, you can have a try.

Accessing Resources in a C# WPF Application (Same Assembly)

(Before I jump into the nitty-gritty, I want to set the context: I'm trying to load a WPF frame with the contents of an .html file that I'm including in my project as a resource.)
I create a new WPF Application; I add a new folder called 'foofiles' to the project, and I add a couple of files (page1.foo and page2.foo) to that folder.
For each newly added .foo file, I right-click on it, go to "Properties," and set the Build Action to 'Resource,' and the Copy To Output Directory to "Copy always."
I want to be able to access those files both in XAML:
<Frame x:Name="bar" Source="/foofiles/page1.foo"/>
And in procedural code:
private void someFunc()
{
bar.Source = new Uri("/foofiles/page1.foo");
}
But I just can't figure out why this doesn't work -- I get a "Format of the URI could not be determined."
In the code-behind, I tried doing this:
private void someFunc()
{
bar.Source = new Uri("pack://application:,,,/foofiles/page1.foo");
}
which didn't throw an exception, but my main window crashed.
In my thinking, if I add a file of any type to my project, and if I mark it as "Resource" in "Build Action," I should be able to use that file per my examples above. Also, I would like to use that file like this:
private void someOtherFunc()
{
System.IO.StreamReader reader = new System.IO.StreamReader("/foofiles/page1.foo");
string bar = reader.ReadToEnd();
}
Any help would be appreciated... thanks in advance!
Try adding the component-part to your Pack URI like this
pack://application:,,,/AssemblyName;component/ResourceName
where AssemblyName is the name of your assembly. So for your case, the following statement should work:
bar.Source = new Uri("pack://application:,,,/AssemblyName;component/foofiles/page1.foo");
More practically, try the relative pack uri notation:
bar.Source = new Uri("AssemblyName;component/foofiles/page1.foo", UriKind.Relative));
For stream reading resources use
var streamResourceInfo = Application.GetResourceStream(uri);
using (var stream = streamResourceInfo.Stream)
{
// do fancy stuff with stream
}

MEF + Plug-In not updating

I asked this on the MEF Codeplex forum already, but I haven't gotten a response yet, so I figured I'd try StackOverflow. Here's the original post if anyone's interested (this is just a copy from it):
MEF Codeplex
"Let me first say that I'm completely new to MEF (just discovered it today) and am very happy with it so far. However, I've ran in to a problem that is very frustrating. I'm creating an app that will have a plugin architecture and the plugins will only be stored in a single DLL file (or coded into the main app). The DLL file needs to be able to be recompiled during run-time and the app should recognize this and re-load the plugins (I know this is difficult, but it's a requirement). To accomplish this I took the approach covered http://blog.maartenballiauw.be/category/MEF.aspx there (look for WebServerDirectoryCatalog). Basically the idea is to "monitor the plugins folder, copy the new/modified assemblies to the web application’s /bin folder and instruct MEF to load its exports from there." This is my code, which is probably not the correct way to do it but it's what I found in some samples around the net:
main()...
string myExecName = Assembly.GetExecutingAssembly().Location;
string myPath = System.IO.Path.GetDirectoryName(myExecName);
catalog = new AggregateCatalog();
pluginCatalog = new MyDirectoryCatalog(myPath + #"/Plugins");
catalog.Catalogs.Add(pluginCatalog);
exportContainer = new CompositionContainer(catalog);
CompositionBatch compBatch = new CompositionBatch();
compBatch.AddPart(this);
compBatch.AddPart(catalog);
exportContainer.Compose(compBatch);
and
private FileSystemWatcher fileSystemWatcher;
public DirectoryCatalog directoryCatalog;
private string path;
private string extension;
public MyDirectoryCatalog(string path)
{
Initialize(path, "*.dll", "*.dll");
}
private void Initialize(string path, string extension, string modulePattern)
{
this.path = path;
this.extension = extension;
fileSystemWatcher = new FileSystemWatcher(path, modulePattern);
fileSystemWatcher.Changed += new FileSystemEventHandler(fileSystemWatcher_Changed);
fileSystemWatcher.Created += new FileSystemEventHandler(fileSystemWatcher_Created);
fileSystemWatcher.Deleted += new FileSystemEventHandler(fileSystemWatcher_Deleted);
fileSystemWatcher.Renamed += new RenamedEventHandler(fileSystemWatcher_Renamed);
fileSystemWatcher.IncludeSubdirectories = false;
fileSystemWatcher.EnableRaisingEvents = true;
Refresh();
}
void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
{
RemoveFromBin(e.OldName);
Refresh();
}
void fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e)
{
RemoveFromBin(e.Name);
Refresh();
}
void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
Refresh();
}
void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
Refresh();
}
private void Refresh()
{
// Determine /bin path
string binPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
string newPath = "";
// Copy files to /bin
foreach (string file in Directory.GetFiles(path, extension, SearchOption.TopDirectoryOnly))
{
try
{
DirectoryInfo dInfo = new DirectoryInfo(binPath);
DirectoryInfo[] dirs = dInfo.GetDirectories();
int count = dirs.Count() + 1;
newPath = binPath + "/" + count;
DirectoryInfo dInfo2 = new DirectoryInfo(newPath);
if (!dInfo2.Exists)
dInfo2.Create();
File.Copy(file, System.IO.Path.Combine(newPath, System.IO.Path.GetFileName(file)), true);
}
catch
{
// Not that big deal... Blog readers will probably kill me for this bit of code :-)
}
}
// Create new directory catalog
directoryCatalog = new DirectoryCatalog(newPath, extension);
directoryCatalog.Refresh();
}
public override IQueryable<ComposablePartDefinition> Parts
{
get { return directoryCatalog.Parts; }
}
private void RemoveFromBin(string name)
{
string binPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "");
File.Delete(Path.Combine(binPath, name));
}
So all this actually works, and after the end of the code in main my IEnumerable variable is actually filled with all the plugins in the DLL (which if you follow the code is located in Plugins/1 so that I can modify the dll in the plugins folder).
So now at this point I should be able to re-compile the plugins DLL, drop it in to the Plugins folder, my FileWatcher detect that it's changed, and then copy it into folder "2" and directoryCatalog should point to the new folder. All this
actually works! The problem is, even though it seems like every thing is pointed to the right place, my IEnumerable variable is never updated with the new plugins. So close, but yet so far! Any suggestions?
I know the downsides of doing it this way, that no dll is actually getting unloaded and causing a memory leak, but it's a Windows App and will probably be started at least once a day, and the plugins are un-likely to change
that often, but it's still a requirement from the client that it does this without re-loading the app. Thanks!
Thanks for any help you all can provide, it's driving me crazy not being able to figure this out."
There is no trigger for recomposition, because your catalog implementation doesn't provide notifications. Implement INotifyComposablePartCatalogChanged to fix this.
I believe MEF can only load one version of the same assembly (I was trying on Silverlight though)
I was having a similar issue- after copying discovered Plugins to the application's directory, a DirectoryCatalog wouldn't see them, even after calling .refresh() on the DirectoryCatalog.
I found that stepping through the code resolved the issue- my best guess is that the filesystem still needs a moment after the FileSystemWatcher kicks off it's notification before MEF can scan the new assembly (perhaps to finish some obscure copy operation) and see the parts inside.
System.Threading.Thread.Sleep(1000), lame as it is, solved the issue.

Simple silverlight open-file-dialog errors

A while back I wrote a silverlight user control which had a csv import/export feature. This has been working fine, until recently I discovered it erroring in one scenario. This may have been due to moving to Silverlight 3.
The Error:
Message: Unhandled Error in Silverlight 2 Application
Code: 4004
Category: ManagedRuntimeError
Message: System.Security.SecurityException: Dialogs must be user-initiated.
at System.Windows.Controls.OpenFileDialog.ShowDialog()
at MyControl.OpenImportFileDialog()
at ...
The Code:
private void BrowseFileButton_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(lblFileName.Text))
{
if (MessageBox.Show("Are you sure you want to change the Import file?", "Import", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
return;
}
}
EnableDisableImportButtons(false);
var fileName = OpenImportFileDialog();
lblFileName.Text = fileName ?? string.Empty;
EnableDisableImportButtons(true);
}
private string OpenImportFileDialog()
{
var dlg = new OpenFileDialog { Filter = "CSV Files (*.csv)|*.csv" };
if (dlg.ShowDialog() ?? false)
{
using (var reader = dlg.File.OpenText())
{
string fileName;
//process the file here and store fileName in variable
return fileName;
}
}
}
I can open an import file, but if i want to change the import file, and re-open the file dialog, it errors. Does anyone know why this is the case?
Also, I am having trouble debugging because placing a breakpoint on the same line (or prior) to the dlg.ShowDialog() call seems to cause this error to appear as well.
Any help would be appreciated?
You do two actions on one user click.
You show a messagebox which effectively uses your permission to show a dialog on user action.
You then try to show the dialog, since this is a second dialog on user action it's not allowed.
Get rid of the confirmation dialog and you'll be fine.
Remove Break Points before if (dlg.ShowDialog() ?? false) code will run its work for me.

Categories