Hej
I am trying to load an (embedded) image in a wpf application, using an Uri but I keep getting an exception.
The code is:
new BitmapImage(new Uri("pack://application:,,,,/Icons/m.png"));
(In case it isn't clear, I am trying to load the m.png file from the Icons folder, which
has been marked as an embedded ressource).
and the exception is
NotSupportetException (the URI prefix is not recognized)
Can anybody tell me what the uri should have been?
Three commas must be instead of four in your string:
new BitmapImage(new Uri("pack://application:,,,/LibName;component/Icons/m.png"));
LibName - points to assembly where resource is hosted.
You may take a look at this blog post. The solution is to register a custom uri parser so that it recognizes the pack protocol:
UriParser.Register(
new GenericUriParser(GenericUriParserOptions.GenericAuthority), "pack", -1
);
Related
i am experimenting with prism and the possibilities it brings to create applications divided into modules.
In one of my modules i want to load data from a XML file but can't get it to work so that
Uri uri = new Uri(resourceFile, UriKind.RelativeOrAbsolute);
StreamResourceInfo info = Application.GetResourceStream(uri);
will look for the file in the "Data" folder of my module project. Instead the file is successfully loaded if i put the "Data" folder with the XMl file inside the Shell project.
What do i miss?
Edit: value of resourceFile: "Data/file.xml"
finally got that to work:
Uri uri = new Uri("MainModule1;component/" + resourceFile, UriKind.Relative);
actually i did try that before but must have made a mistake.
i'm building a wp7 application for a game using silverlight & XNA
i have an mp3 file called "Punch1.mp3" (Build action : resource ) stored inside a folder called "SoundEffects" inside the project folder
and i want to play the file using this code
StreamResourceInfo info;
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
punch is defined in the code here :
public static SoundEffect punch1;
the problem is that it raises a nullreference exception in the third line claiming that info is null
and that's true in the debugging mode , i found that the resource stream info is null
i think this is because the it can't read the file although the uri is correct
You can try two things
- Clean and rebuild the project
- Try appending project name in URI "/PhoneApp1;component/SoundEffects/Punch.mp3"
Since you're using the XNA assembly anyway, you can use TitleContainer.OpenStream instead (with a relative URI) and have the audio file build set as Content.
I agree with Haris Haqsan that your URI string is bad.
Uri myuri = new Uri("/PhoneBoxing;component/SoundEffects/Punch1.mp3", UriKind.Relative);
But you should also consider switching to using content files instead embedding them at resources as it can help your application start up time. Depending on the amount of files we are talking about, it can make a big difference.
Set your Build Action to content and your code should look like:
FileStream stream = new FileStream("/SoundEffects/Punch1.mp3", FileMode.Open, FileAccess.Read);
in the following code :
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
SoundEffect.FromStream() expects a wave file stream not an MP3 as shown here : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.audio.soundeffect.fromstream.aspx .
so solution to find a mp3 > wav convertor or just find another way to load mp3 to WP7
considering the picture this is normal URI in normal cases can't evaluate expression of isfile .
I was experiencing the same issue on my machine, the InvalidOperationException is a little confusing. All I had to do was re-encode the wav file to the specifications listed on MSDN.
After I did that, it worked perfectly.
Here is the task-related part of the VS2010 project (Windows Phone) structure:
The code is being executed from DummyMediaLibProvider.cs:
public class DummyMediaLibProvider: IMediaLibProvider
{
...
StreamResourceInfo albumArtPlaceholder =
Application.GetResourceStream(
new Uri("../Images/artwork.placeholder.png", UriKind.Relative));
artwork.placeholder.png Build Action is set to Content.
Still, whenever I run the code, Application.GetResourceStream returns null.
What may be the reason for the resource not being read to memory?
I have attempted to delete obj directory of the project, did Clean and Rebuild, but so far nothing helped.
Update:
If I apply Build Action: Resource to artwork.placeholder.png, I can get the resource stream ok though.
P.S. This is not the duplicate of Application.GetContentStream returns null for content Uri since the last had the extension (particurarly .xml) related problem.
The path supplied Application.GetResourceStream isn't relative to the position of the class, but relative to the application package.
StreamResourceInfo albumArtPlaceholder =
Application.GetResourceStream(
new Uri("Images/artwork.placeholder.png", UriKind.Relative));
Would be the correct path. You can also try with a full pack URI. (see MSDN)
And finally, Resource would be the correct Build Action for this.
Here's the code snippet
String str= ??????? // I want to assign c:/my/test.html to this string
Uri uri= new Uri (str);
Stream src = Application.GetContentStream(uri).Stream;
What's the correct way to do this? I'm getting "URI not relative" Exception thrown
Your problem is specific to WPF. See the Application.GetContentStream method.
You'll read that this method requires a relative URI. See "WPF Application, Resource, Content and Data files".
You have a file path - if you want to make it a URI add "file:///", ie. "file:///c:/my/test.html"
For local file URIs, you need to prefix it with:
file:///
I think you'll find your problem is that Application.GetContentStream is for a resource stream for a content data file that is located at the specified Uri. That is, deployed alongside an executable assembly.
If you look at: http://msdn.microsoft.com/en-us/library/aa970494(VS.90).aspx#Site_of_Origin_Files
You should find that the file:/// syntax as stated above is correct... But if you're going to open them you'll probably want some kind of switch to work out how to get the stream:
FileInfo fileToSave;
if (!existingFile.IsFile)
throw new ArgumentException("Input URI must represent a local file path", "existingFile");
fileToSave = new FileInfo(existingFile.LocalPath);
return fileToSave.Open(/* Args based on your needs */)
And similarly if it's a web URI:
if (!existingFile.Scheme.StartsWith("http"))
throw new ArgumentException("Input URI must represent a remote URL path", "existingFile");
// Do a WebRequest.Create call and attempt download... (Perhaps to MemoryStream for future use)
Hope that helps.
Andrew.
I have C# code that is trying to get the LocalPath for a executing assembly using the following line of code:
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
This piece of code performs fine for all the variety of paths. It started to fail giving the right AbsolutePath and Localpath because the executing assembly path contained a # in it.
Assembly.GetExecutingAssembly().CodeBase gives "C:\c#\ExcelAddin1.1.0\GSRExcelPlugin\bin\Debug\Common.dll"
But new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath gives "C:\c" while it should have given "C:\c#\ExcelAddin1.1.0\GSRExcelPlugin\bin\Debug\".
Is there something that I need to handle or is there something wrong the way Uri class is used?
If this is a .net framework issue, how should I report this issue to Microsoft?
System.IO.FileInfo logger = new System.IO.FileInfo(Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath), "settings.config"));
Using EscapedCodeBase instead of CodeBase solves the problem. I dint realize that this was already handled until I stumbled on it.:)
The Uri class is behaving as expected. # is not a valid part of a url. Imo this is an issue with CodeBase property. It returns a string unescaping special characters rendering it pretty much unreliable. Your options are:
1) Always use EscapedCodeBase property instead.
var uri = new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath;
2) Or if you really have to deal with CodeBase property (if that is the only option), get the escaped part yourself.
var x = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var uri = x.LocalPath + Uri.UnescapeDataString(x.Fragment).Replace('/', '\\');
3) For file location of the loaded assembly, the easiest is to use Location property.
var uri = Assembly.GetExecutingAssembly().Location;
The issue has been reported several times, but MS insists that is how CodeBase is designed here, here, here and here.
I assume The URI functions are stripping away everything after the sharp # because it thinks its an anchor.
URI are designed for identifying resources on the internet, so your # character would be an illegal character in the middle of any URI.
Take even this question for example, the Title is
System.Uri fails to give correct AbsolutePath and LocalPath if the Path contains “#”
but the end of the URL has the "#" stripped away
system-uri-fails-to-give-correct-absolutepath-and-localpath-if-the-path-contains
Why do you need to convert it into a URI anyway. The only difference between these 3 console.writelines is the fact that the first two are prefixed with File:///
Console.WriteLine(Assembly.GetExecutingAssembly().CodeBase); // 1
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
Console.WriteLine(uri); // 2
Console.WriteLine(uri.LocalPath); // 3