More on resource loading in WPF
Andrey Skvortsov commented on that post: Could you elaborate more last variant with pack:// uri syntax for local windows app?You were speaking about win apps and suddenly jump to web based deployment model though it's completly different things IMHO.
I had touched ever so briefly on the Pack URI syntax but didn't give details because I figured that was a whole different topic on it's own, and was much better addressed by the XPS (a.k.a Metro) specification. However, I will try to clarify the issues he's raised.
Pack URIs
The Metro package is a logical entity comprised of a number of parts. The Pack URI scheme defines a way to use URIs to refer to part resources inside a Metro package. It uses RFC 2396's (Uniform Resource Identifiers: Generic Syntax) extensibility mechanism for defining new kinds of URIs based on new schemes. You're probably aware that the scheme is the prefix in a URI, e.g. http, ftp. So Metro defines
pack as a new scheme. The URI format is so:
pack://<authority><absolute_path>
The authority component in a Pack URI is itself an embedded URI pointing to a package. This must be a legal URI per RFC 2396. Of course, since it is embedded in the Pack URI, you must escape reserved characters. In our case, slashes ("/") are replaced by commas (","). Other characters like "%", "?" etc. must be escaped. See the spec for complete details. Windows Presentation Foundation provides an application with two built-in authorities:
application and siteoforigin.The
application authority abstracts the deployed application itself. Any resources embedded in that application assembly, one of it's satellite resource assemblies or even loose files accompanying that application may be referenced using this authority. Of course, your project must define these files as Resource and Content, respectively. I should add though, that you need not use the Pack URI syntax for application files such as these. You can just use regular relative URIs.The
siteoforigin authority abstracts the conceptual site of origin of the deployed application. So if you had a file test.jpg at the location where the application binaries and manifests reside, say C:\myfiles\, then you need not hardcode the URL file:///C:/myfiles/test.jpg. You can instead use the abstraction pack://siteoforigin:,,/test.jpg. Notice that I said need not: in a full-trust application (Window-based installed application), you can do pretty much what you want. But in a web-browser application, you cannot access files on disk so adding a reference such file:///C:/myfiles/test.jpg pretty much binds you to a full trust app, and moreover you have to worry about how to get that image into that location for everyone that uses your app.So, to go back to Andrey's question, if he were prototyping a WPF app, it would be prudent to use these abstractions and make the app portable, no matter if the prototype started out an installed or browser-hosted app flavor. Remember that with WPF, you use the same programming model for an installed app and a browser-hosted app. You can switch between these two flavors merely by changing the
HostInBrowser and Install properties in your project, and pretty much nothing else. Besides, ClickOnce does the heavy lifting of downloading all loose content files for your application during deployment, so you don't have to.Is there an easier way to construct Pack URIs?
Yes, look at the
System.IO.Packaging.PackUriHelper class and try experimenting with the Create method by passing it different types of URIs as parameters.You don't really need Pack URIs
That's right. The novice WPF programmer can survive without knowing how Pack URIs work. I've talked about how you can use simple relative URI references instead of the pack://application notations. Further, if you're looking for a package part or better still, the stream for an embedded resource you can use
Application.GetResourcePart(Uri relativeUri). To get a stream for an XML file embedded in your application:
Stream stream = Application.GetResourcePart(
new Uri("RssFeed.xml")).GetStream();
To get the stream for a loose content file you can use
Application.GetContentPart(Uri relativeUri). For e.g. here's how to get a stream for a declared loose image file with your application:
Stream stream = Application.GetContentPart(
new Uri("MyImage.jpg")).GetStream();
To get the stream for a file at the location from where the application was launched, you can use
Application.GetRemotePart(Uri relativeUri). For e.g. here's how to get a stream for an undeclared text file at the site of origin:
Stream stream = Application.GetRemotePart(
new Uri("Contacts.txt")).GetStream();
Update [Apr 2009]: If you came here looking for resources and URIs in Silverlight, then you will find this post helpful. Note that Silverlight does not support pack URIs.
Tags: WinFX
Labels: Resource, Windows Presentation Foundation, WPF

13 Comments:
I've linked to original post from http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=156545&SiteID=1.
Documentation/specs are good but simple,human language is better.And...I can't comment/ask questions on the metro spec you refer.It's always better to discuss tricky problems online.
Thank you.
By
Andrey Skvortsov, at December 4, 2005 4:09 AM
By the way,as I can see WPF dosen't have Application.GetRemotePart() counterpart for local win apps,to reference content not existent at compile time,so we have less options for offline local apps.Right?
P.S.
Metro is too wide context to clarify things in concrete implementation-WPF.
By
Andrey Skvortsov, at December 4, 2005 4:27 AM
The site of origin points to the location from where your app was launched. It applies uniformly to .application and .xbap WPF apps. For instance if you were to launch your app from a CD, it would point to that location on CD. If you were to launch it from a network share, again it points to that location. So being 'online' in these situations would mean having access to that CD or that network share.
By
Ashish, at December 4, 2005 8:33 AM
Sorry,
BamlParseException:
Error at element 'ResourceDictionary' in markup file 'myapp.xaml' : Cannot assign value 'pack://siteoforigin:,,/test.xaml' to property 'System.Windows.ResourceDictionary.Source'..
as you can see "local" version for pack:// syntax dosen't work-both executable and "test.xaml" located in the same dir.
Thanks.
By
Andrey Skvortsov, at December 5, 2005 3:49 AM
What the...second launch from VS and it found,found "test.xaml" at last!!!Very strange behavior on VS side I suppose.
So,'pack://siteoforigin:,,/test.xaml' works from second attempt;-)
By
Andrey Skvortsov, at December 5, 2005 3:57 AM
What is the reasoning for a URL being ",,/name.xaml"? That looks like an escaped version of "///name.xaml", which doesn't make any sense to me. I'm simply trying to to merge a resourcedictionary from a dependent assembly such that from App.exe, how would I reference a resource located at Source/Resources/MyResources.xaml from Library.dll?
By
Keith Patrick, at January 21, 2006 1:57 AM
Think of the Pack Uri as a recursive Uri format where the inner Uri's reserved characters are escaped. For simplicity: pack://<inner uri>/foo.xaml
Now, the inner Uri points to a Uri for a package. In its unescaped form it can be a regular http Uri like http://www.somesite.com. WPF registers a couple of its own i.e. application:/// and siteoforigin:///
When these are used in a Pack Uri, the resultant Uri is pack://application:,,,/foo.xaml and pack://siteoforigin:,,,/foo.xaml
This may seem contrived but its the only way you can get the required behavior *and* be compliant with the Uri spec.
By
Ashish, at January 21, 2006 4:42 PM
That's where I was getting confused: didn't realize that the authority ends in :/// (I haven't found the documentation that talks about authorities yet)
After battling with the IDE crashing whenever I tried to save my xaml file while still debugging, I managed to try storing my resource as Content, Resource, and EmbeddedResource, and referencing the directory as /Resource.xaml and /Source/Resources/Resource.xaml, it can't seem to find the thing. Is there something I need to do to nudge it in the direction of the correct satellite assembly? I've looked at the manifest, and the resource is there, but I haven't hit the right setting.
By
Keith Patrick, at January 23, 2006 5:03 PM
I fixed it. The WPF wizard creates resource dictionaries as Page content, and in that manner, the format hasn't really changed from September except for the pack URI prefix, so it wound up being:
pack://application:,,,/Library;component/Source/Resources/Resource.xaml
By
Keith Patrick, at January 23, 2006 5:22 PM
Thanks for the article though making it clear that authority ends with ":///" or (actually "://"?) right from the start would have saved time.
I searched through all WPF SDK sample code and found out, some guys are using 2 commas others use 3:
Uri(@"pack://application:,,,/images/help.bmp");
Uri(@"pack://application:,,/images/help.bmp");
Both versions work - which one's better? Again - such commonly needed stuff should better be communicated well...
By
Anonymous, at April 24, 2006 8:28 PM
totally agree w/ anonymous post above. I'm reading the WPF book by Charles Petzold: Application=Code + Markups. On page 72, the example has 2 commas, while on page 465, another example has 3.
By
Anonymous, at October 13, 2006 10:00 PM
I am having troubles with loading a htm resource in a Frame, the resource is called "introduccion.htm" and is in the same folder than my WPF Page, the code i am using to loade it is:
Uri location = new Uri(@"pack://application:,,,/noticia/introduccion.htm");
this.Contenido.Source=location;
and i already saw that my introduccion.htm file is a resource inside the VS 2008 project.
Any idea???
By
Charlymoon, at June 3, 2008 11:17 AM
網頁設計,情趣用品,情趣用品,情趣用品,情趣用品
色情遊戲,寄情築園小遊戲,情色文學,一葉情貼圖片區,情惑用品性易購,情人視訊網,辣妹視訊,情色交友,成人論壇,情色論壇,愛情公寓,情色,舊情人,情色貼圖,色情聊天室,色情小說,做愛,做愛影片,性愛
免費視訊聊天室,aio交友愛情館,愛情公寓,一葉情貼圖片區,情色貼圖,情色文學,色情聊天室,情色小說,情色電影,情色論壇,成人論壇,辣妹視訊,視訊聊天室,情色視訊,免費視訊,免費視訊聊天,視訊交友網,視訊聊天室,視訊美女,視訊交友,視訊交友90739,UT聊天室,聊天室,豆豆聊天室,尋夢園聊天室,聊天室尋夢園,080聊天室,080苗栗人聊天室,女同志聊天室,上班族聊天室,小高聊天室
AV,AV女優
視訊,影音視訊聊天室,視訊交友
視訊,影音視訊聊天室,視訊聊天室,視訊交友,視訊聊天,視訊美女
By
J&D, at May 2, 2009 4:33 AM
Post a Comment | Home | Inference: my personal blog