Shawn Hargreaves Blog
The simple answer is that the file you are trying to load must not actually exist in the location you are trying to load it from!
And yet people sometimes get stuck on this error, unable to open their file and with no idea how to figure out why this is failing. I suspect this is a side effect of the Content Pipeline being so automated in XNA. When the usual experience is to just drop an image into Visual Studio, then ContentManager.Load it into your game, there is no need to learn the details of what happens to the file in between. But if you do not know this, you will not have the tools to debug when things go wrong, or to understand the differences between files built by the Content Pipeline versus deployed some other way.
In fact, the Content Pipeline is just an optional layer over the top of a simple file deployment mechanism. In order to load a file, exactly three things must take place:
Your Visual Studio Solution Explorer contains source files, not build outputs. These source files are not directly available to your game at runtime. To make them available, we must copy them to the build output folder.
The build output folder is located inside whatever directory contains your project. This will typically be called something like bin\x86\Debug. There is a separate output folder for each target platform and build configuration (x86 vs. Xbox 360, Debug vs. Release, etc.)
There are three main ways to arrange for files to end up in this folder:
To make sure all your files have been correctly copied, just open up the build output folder in Windows Explorer and take a look at what is there.
When you debug a game on Windows, it runs directly from the build output folder, so no additional deployment is necessary.
When you run on Xbox or package as a .ccgame, the packaging tool gathers all the files from your build output folder (skipping only a few known-to-be-irrelevant formats such as .pdb), so all the same files are sure to be available even though the game actually runs elsewhere.
But on Windows Phone, or if you distribute a Windows game using ClickOnce, the deployment process only includes files that were declared as outputs by MSBuild. This includes all files created by the Content Pipeline or the Copy to Output Directory property, but will leave out anything you manually copied to the output folder, or if you incorrectly customized your MSBuild XML to copy files without also declaring them as build outputs (which is a topic for another day).
To make sure all your files have been correctly packaged for Windows Phone, rename the output .xap package to a .zip extension, so you can open it in Windows Explorer and see what it contains.
TitleContainer.OpenStream paths are relative to the game executable. If the build output folder is bin\x86\Debug:
ContentManager.Load internally calls TitleContainer.OpenStream, but first it modifies the path in two ways:
So you should not include the .xnb extension when using ContentManager.Load (and also do not include the extension of whatever source file was used to create this .xnb - remember you are loading the compiled output file, not the source asset that was added to Visual Studio Solution Explorer).
The default game template sets ContentManager.RootDirectory to "Content", so:
You can create multiple ContentManager instances with whatever RootDirectory you like. For instance, to load bin\x86\Debug\Foo\Bar\cat.xnb, you could:
Note: this article is about immutable content which is deployed as part of your game package. If you are looking to save and load data at runtime, you want Isolated Storage or StorageContainer instead.
"When you run on Xbox or package as a .ccgame, the packaging tool gathers all the files from your build output folder (skipping only a few known-to-be-irrelevant formats such as .pdb)"
I wish it could be told not to package directories named ".svn"! If these accidentally make it into a .ccgame it will be rejected from AppHub submission form.
Why do you have .snv info in your build output directories? It's not usually considered a good idea to check these generated output files into source control...
I know it's a borderline questionable thing to do... it's just copies of DLLs in the Bin directories that we have checked in. It's not a big deal, but it would be nice to be able to setup a custom filter to list extensions that should be ignored.
@Evan: A filter to filter out something that is not supposed to be happening in the first place is not warranted. The general rule is that a repository should only contain source code, assets and dependencies (such as other DLLs). If you own build output is in the repository, you should reconsider the repository layout.
How do I know what path is currently used?!?!?!?!??!?!?!?!?!?!?!?!?!?!!?!?!?!?!
djhenrya: I don't understand your question. Used by what?