locked
Recursively build file resources into the app package, preserving the directory tree structure?

    Question

  • My app uses a lot of resources such as texture files, audio samples, font files etc.  On my local disk, these are arranged along these lines:

    + Resources
       + Fonts
          - Font1.ttf
          - Font2.ttf
          - ...
       + Textures
          - Texture1.png
          - Texture2.png
          - ...
       + Samples
          - Sample1.wav
          - Sample2.wav
          - ...
       
         

    Is there a simple way to build these files (recursively) into my app package, preserving the directory structure?

    ie. In the app I'd like to then obtain the root of my resource tree like this:

    // Get the base path for my resource files

    Windows::ApplicationModel::Package^ package = Windows::ApplicationModel::Package::Current; Windows::Storage::StorageFolder^ folder = package->InstalledLocation; Platform::String^ ResourceBasePath = installedLocation->Path + "\Resource\"; // Would like to now access resources along these lines (ie. with the preserved directory structure) Platform::String^ Font1Path = ResourceBasePath + "Fonts/Font1.ttf"; Platform::String^ Font2Path = ResourceBasePath + "Fonts/Font2.ttf"; Platform::String^ Sample2Path = ResourceBasePath + "Samples/Sample1.wav";

    I'm coming from a iOS background where this is achieved by just dragging my entire Resource folder into the project in the IDE.  I've tried adding some files to the solution in this way, but they all just seem to end up in the package root.

    I feel I must be missing something obvious.

    Tuesday, November 6, 2012 4:58 PM

All replies

  • Hi,

    I think this issue caused by you create a filter, not the folder in the project.

    General speaking, if we right click to add a something like folder in  C++ project, the default behavior is creating a filter, which only work in solution windows not app file path.

    You should switch to the folder view, so that we can create folder directly. You can follow blow image.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, November 7, 2012 7:36 AM
  • Firstly, thanks!  As a long term user of Visual Studio I had absolutely no idea you could do this, and now feel foolish at the time I've wasted manually creating 'Filters' to match my codebase and wondering if the next version of VS will ever do this for me automatically.

    Although perfect for code, there seem to be a couple of significant hurdles (and huge potential for mistakes) when using this method for resources.  When I add a new resource to the file system, it won't appear in the app package unless:

    1. I mark that file resource as 'Include In Project'

    2. I go the properties for the file resource and change 'Item Type' from 'Does not participate in build' to 'Media'

    Frustratingly, it seems that these properties cannot be applied recursively to the top level resource folder so I need to manually descend into each subfolder to perform it on the files within it.  I'm likely to have more than 1000 files and 30-40 folders so this isn't viable.

    I can think of a couple of workarounds:

    1. Build all my resources into one big archive file which is the one and only 'resource' as far as the app package is concerned.  I might like to do this in future anyway, but I'm not sure I have the time at the moment.

    2. Write some sort of VS script which crawls my resource directory on disk and automatically adds all the files it finds to the project, marking them as 'Include in Project' and 'Media'.  This script would ideally be called as part of the build, but could be invoked as a command if that's too slow or not possible.

    Is the second workaround viable, or can this be done in VS using existing functionality?

    Wednesday, November 7, 2012 2:55 PM
  • I'm still struggling with this problem. 

    It seems that there's no way to get the IDE to recursively include a whole directory tree in the package without manually flagging every file as 'Include in project' and 'Media' which is both time consuming and massively error prone.

    Is it viable to add a post build step to just manually copy my entire resource file structure into the AppX directory?

    Friday, November 9, 2012 1:36 AM
  • As far as I know, we can edit the vcproject file directly to add lots of file into project.

    Right Click your project->Unload Project->Right Click again->Edit your project name.vcxproj

    You can find that
     <ItemGroup>
        <Image Include="Assets\Logo.png" />
        <Image Include="Assets\SmallLogo.png" />
        <Image Include="Assets\StoreLogo.png" />
        <Image Include="Assets\SplashScreen.png" />

      </ItemGroup>

    You can do the same thing with other files.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Friday, November 9, 2012 7:25 AM
  • I'd still class that method as adding files manually, although I agree it's slightly quicker than doing it via the IDE. 

    To give you an idea of the problem, the app includes more than 500 HTML files and images as help content.  This help content is authored in Word (as a Word Doc) and then exported using Word's HTML exporter.  Every time the help document is changed (eg. adding an image), Word can subtly re-number all the output. This means carefully checking and editing 500 lines in the vcproj every time a single image is added to the help documentation.  It would be much more sensible to tell VS to just include all files it finds in a particular directory.

    Interestingly, I have found out that it is possible to use wildcards such as this:

    <ItemGroup>

        <Image Include="Assets\**\*.*" />

    </ItemGroup>

    Where '**' means recurse through directories.  This seems to have two drawbacks though.  Firstly, it seems necessary to make a similar entry in the vcxproj.filters file before it will work in the IDE (although I'm not sure if this affects the build).  Secondly (and more importantly), touching or editing the project in the IDE seems to make VS expand this expression back out into individual entries again so I'm back to square one. To avoid the expansion, this link:

    http://stackoverflow.com/questions/2551107/is-there-a-way-to-automatically-include-content-files-into-asp-net-project-file

    .. seems to suggest that I can wrap it in a "BeforeBuild" target, but I can't get this to work.

    I'm still thinking that the best route is to add a post build script to copy my resource tree to the AppX folder.  However, I don't know much about the Windows Store packaging/verification process to know if this 'manual' fiddling with the package is a good idea!

    Friday, November 9, 2012 11:53 AM
  • I've managed to get closer to an automated solution by performing this as a post-build event:

    xcopy "$(SolutionDir)Resource" "$(OutDir)AppX\Resource\" /D /E /Y

    This copies all files recursively from my resource directory to the AppX package. 

    However, the next problem is that when the Deployment step runs and finds it has some work to do, it cleans out the AppX directory before copying in its files - thereby ruining the work of my post-build event.

    Is there a way of triggering a script during deploy, or somewhere to put these files where the deploy step will copy them?

    Friday, November 9, 2012 3:34 PM
  • Is there really no way to automatically and recursively build a directory tree into the app resources?

    Although the forum has been of some use, is there any contact point I can use for further help for this and a few other questions?  I tried enlisting on the '30 day app' programme but I'm UK based and it's only open to US participants.

    Tuesday, November 13, 2012 4:22 PM
  • I also have to bump this. There must be a solution to copy additional files to the package that is being deployed.

    We are developing games and it is ridiculous that there is no feature in VS2013 in the UI to add a folder as a reference. We have hundreds of files that need to be copied.

    Right now we have been using the pre-build event and xcopy to copy our files, same as @MattBlip, but that doesn't help with remote deployments. 

    Edit: This seems to work, however it pollutes the solution.

      <!-- Copy Resources/Base to output folder --> 
      <ItemGroup>
        <Image Include="..\..\..\..\Resources\Base\**">
          <Link>Base\%(RecursiveDir)%(Filename)%(Extension)</Link>
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Image>
      <!-- Copy ../drahtkern/Resources/Core to output folder -->
        <Image Include="..\..\..\..\..\drahtkern\Resources\Core\**">
          <Link>Core\%(RecursiveDir)%(Filename)%(Extension)</Link>
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Image>
      </ItemGroup> 

    How can we hide those Items in the project view?

    • Edited by its_manny Monday, July 8, 2013 6:12 PM badfix
    Monday, July 8, 2013 3:25 PM
  • Forgive me but I need to bump this thread.

    I am having exactly the same problem. The solution above (with wildcards) does not work for me (It did, untill it stopped...) we have so many resources files that Visual Studio just started to hang on loading. Not even talking about the utter mess in the Solution Explorer.

    I honestly feel the burning hatred of a thousand suns in my guts as I cannot comprehend WHY on earth such a basic thing that is meant to be simple is so freaking impossible to get right in Visual Studio... Does anyone have any guidance?!

    Friday, October 17, 2014 3:23 PM