title: Getting Content Files and Primary Output programmatically
body: <p>For some reason, we have a script that creates batch files to XCOPY our compiled assemblies, config files, and various other files to a network share for our beta testers. We do have an installer, but some don't have the permissions required to run the installer, or they're running over Citrix.</p>
  
  <p>If you vomited all over your desk at the mentions of XCOPY and Citrix, use it as an excuse to go home early. You're welcome.</p>
  
  <p>The code currently has hundreds of lines like:</p>
  
  <pre><code>CreateScripts(basePath, "Client", outputDir, FileType.EXE | FileType.DLL | FileType.XML | FileType.CONFIG);
  </code></pre>
  
  <p>It used to be worse, with 20 int parameters (one per file type) representing whether or not to copy that file type to the output directory.</p>
  
  <p>These hundreds of lines create upload/download batch files with thousands of XCOPY lines. In our setup projects, we can reference things like "Primary output from Client" and "Content Files from Client". I'd love to be able to do that programmatically from a non-setup project, but I'm at a loss.</p>
  
  <p>Obviously MS does it, either using an API or by parsing the .csproj files. How would I go about doing this? I'm just looking for a way to get a list of files for any of the setup categories, i.e.:</p>
  
  <ul>
  <li>Primary Output</li>
  <li>Localized Resources</li>
  <li>Content Files</li>
  <li>Documentation Files</li>
  </ul>
  
  <p><strong>EDIT</strong>: 
  I have a setup project like Hath suggested, and it's halfway to what I'm looking for. The only problem keeping that from being a perfect solution is that multiple projects depend on the same assemblies being in their own folder, and the setup will only copy the file once.</p>
  
  <p>Example:</p>
  
  <p>Projects Admin, Client, and Server all rely on ExceptionHandler.dll, and Admin and Client both rely on Util.dll, while Server does not. This is what I'm looking for:</p>
  
  <ul>
  <li>Admin
  
  <ul>
  <li>Admin.exe</li>
  <li>Admin.exe.config</li>
  <li>ExceptionHandler.dll</li>
  <li>Util.dll</li>
  </ul></li>
  <li>Client
  
  <ul>
  <li>Client.exe</li>
  <li>Client.exe.config</li>
  <li>ExceptionHandler.dll</li>
  <li>Util.dll</li>
  </ul></li>
  <li>Server
  
  <ul>
  <li>Server.exe</li>
  <li>Server.exe.config</li>
  <li>ExceptionHandler.dll</li>
  </ul></li>
  </ul>
  
  <p>Since the referenced assemblies are all the same, what I get is this:</p>
  
  <ul>
  <li>Admin
  
  <ul>
  <li>Admin.exe</li>
  <li>Admin.exe.config</li>
  <li>ExceptionHandler.dll</li>
  <li>Util.dll</li>
  </ul></li>
  <li>Client
  
  <ul>
  <li>Client.exe</li>
  <li>Client.exe.config</li>
  </ul></li>
  <li>Server
  
  <ul>
  <li>Server.exe</li>
  <li>Server.exe.config</li>
  </ul></li>
  </ul>
  
  <p>This causes a FileNotFoundException when either Client or Server can't find one of the two DLLs it's expecting.</p>
  
  <p>Is there a setup property I'm missing to make it always copy the output, even if it's duplicated elsewhere in another project's output?</p>
  
  <p><strong>EDIT AGAIN</strong>: All referenced DLLs are set to "Copy Local", and always have been. I found a decent article on <a href="http://pwigle.wordpress.com/tag/continuous-integration/" rel="nofollow noreferrer">using NAnt and XSLT to grab the list of files</a>, so that may be a possible solution as well, as neouser99 suggested.</p>
  
  <p><strong>ACCEPTED SOLUTION</strong>: I'm pretty much back where I started. All .exe and .dll outputs are put into a "bin" directory in the setup project, loosely packed. The other per-application folders contain shortcuts to the executable in that directory. </p>
  
  <p>The difference now is, I'm going to add a custom action to the installer to use reflection, enumerate the dependencies for each executable output, and copy the .exe and .dll files to the separate directories. Bit of a pain, as I just assumed there was a way to programmatically detect what files would be included via some setup library.</p>