XNA Creators Club Online
Page 1 of 1 (5 items)
Sort Posts: Previous Next

Getting content project information at design time

Last post 7/22/2008 3:43 PM by bp. 4 replies.
  • 7/22/2008 12:40 AM
    • (0)
    • premium membership
    • Posts 86

    Getting content project information at design time

    Hey guys,

    I was inspired by Stephen Styrchak's blog post about creating a designer for winforms. It has gone pretty smooth and should be pretty neat.
    The current snag I'm experiencing right now is that I'm having trouble getting information about the content project during design time. This would be useful to know which images and fonts and such are available.

    The first thing I tried is this:

                Microsoft.Build.BuildEngine.Project project = new Microsoft.Build.BuildEngine.Project();  
     
                TextReader reader = new StreamReader(contentPath);  
     
                project.Load(reader);  
                reader.Close(); 

     

    This works great for getting the information, but causes problems with XNA. Once I start my designer, and then try to save, it says that MSBuild has unloaded the content project, and you can't save, and it causes lots of problems =)
    I tried using project.Load(contentPath) as well but this isn't working, with the same issues.

    My other try was using DTE to get information, like so:

                        DTE dte = (DTE)screenDesigner.GetService(typeof(DTE));  
                        if (dte != null)  
                        {  
                            object[ projects = (object[)dte.ActiveSolutionProjects;  
                            int i = 1;  
                            foreach (Project project in projects)  
                            {  
                                  
                                project.Proj  
                                foreach (ProjectItem items in project.ProjectItems)  
                                {  
                                    //Look at items here  
     
                                }  
    }  
    }  
     

     

    This doesn't cause problems as before, but it doesn't give me the information I need. I don't get any information about the Content project - just about the regular project (ie, i get names like Game1.cs, Game1.ico, etc, but no content stuff!)
    I would appreciate any suggestions =)

    Thanks,
    Bryan

  • 7/22/2008 1:38 AM In reply to
    • (0)
    • premium membership
    • Posts 86

    Re: Getting content project information at design time

    Ok so i investigated this problem and worked more on both routes.

    The DTE route seemed promising at first but it didn't seem straightforward at all to get metadata like processors and importers for the content items. This made it no better than just searching directories in Content.

    I worked more on the MSBuild path and found several problems. The reason it was having issues before was that it was using the GlobalEngine, which I guess is what the projects use. I'm pretty new to MSBuild with my only exposure being the WinFormsContent sample, so I'm learning =)

    Create a new Engine and using that like so fixed the problem:

                if(engine == null)  
                    engine = new Microsoft.Build.BuildEngine.Engine(RuntimeEnvironment.GetRuntimeDirectory());  
     
                Microsoft.Build.BuildEngine.Project project = new Microsoft.Build.BuildEngine.Project(engine); 

    Finally, I was having crashing issues when I try to do this multiple times. The reason I found was that I was constantly loading projects, but never unloading them. A call to engine.UnloadAllProjects() fixed this.

    Alright, I have my fingers crossed that its working now. I'll have a video posted soon showing it

  • 7/22/2008 4:11 AM In reply to
    • (0)
    • premium membership
    • Posts 86

    Re: Getting content project information at design time

    Scratch that, still having problems!

    It works ok if I don't reload the project each time - but it crashes the second time i try to load a project.

    This isn't too big of a problem; but it'd be nice to why it crashes when a second project is loaded.

  • 7/22/2008 5:14 AM In reply to

    Re: Getting content project information at design time

    Hi Bryan,

    Inside Visual Studio, you have to be careful about loading files. The VS shell is super-extensible, so for components from different authors to work well together, there are rules for registering files so that two different components don't clobber each other's state.

    It sounds like what you're trying to do is edit a .contentproj file that is currently loaded in the IDE. That isn't really allowed, if you want to do things correctly. Project files in particular are generally owned by the project implementation (a loaded .csproj file is owned by the C# project implementation, for example). Since they often contain buffered state (changes that are in-memory but not yet saved), you can't just load up your own copy of the file, make changes, and then save it out. At best, you'll end up with lost data. At worst, you'll crash the IDE (possibly what you're experiencing).

    Projects do support automation, though, and that's how you can make changes externally. Using the DTE is the right way to do it -- basically you are invoking methods on the project implementation so that it can update its own in-memory representation of the file.

    In an XNA Game Studio 2.0 game project, there's actually two projects. The .csproj file is the code project, while the .contentproj file is a nested content project. You won't find the content items in the code project's EnvDTE.Project children. Instead, you need to find the EnvDTE.Project for the nested content project. To get this, find the code project, then get its container, then search for a project named "Content".

    In XGS 3.0, we're adding extenders to the automation model to make finding nested projects and parent projects much easier.

    When I get a chance, I'll continue my blog and show a number of interesting things you can do with content at design-time.

    Stephen Styrchak | XNA Game Studio Developer
  • 7/22/2008 3:43 PM In reply to
    • (0)
    • premium membership
    • Posts 86

    Re: Getting content project information at design time

    Hey Stephen!

    Thanks for the info - I know you are really busy right now so thanks for taking the time to reply.

    Haha, ya, I figured going the build engine route was kind of shady because of what you mentioned, that i was loading a project that was in IDE. My "workaround" of loading the project once in a new build engine works for now, but i'll revise it later to use DTE and get the metadata that way.

    I went the DTE route too - which as you said is the right way. I was able to enumerate the nested projects and content items and get all the file names, their build mode, etc. I did this exactly how you mentiond - getting the projects container, then finding all the projects named "Content". The problem is that I couldn't find the meta data specifically supplied by the content pipeline - the Build Importer, Build Processor, and Asset Name.  I'll look forward to your blog post about content at design-time, and look forward to the automation extenders in XGS 3.0 =)

    And thanks again for the really cool idea & help-

    Bryan

Page 1 of 1 (5 items) Previous Next