5
votes

I have a WinForms, C# solution that uses ClickOnce deployment that is causing some trouble with resource files. In short, files marked as Content in class library project do not get copied to the output bin/ folders after I deploy with ClickOnce.

Here is the basic structure of the solution (it contains a lot more projects then the ones I list below)

Solution 
 |--Gui 1 Project
 |  |--References
 |  |  |--ClassLibrary
 |--Gui 2 Project
 |  |--References
 |  |  |--ClassLibrary
 |--Main Gui Project  (StartUp Project)
 |  |--References
 |  |  |--Gui 1 Project
 |  |  |--Gui 2 Project
 |  |  |--ClassLibrary
 |  |--Datafile.wav    (Build Action: Content, Copy-if-newer)
 |  |--Mods.xml        (Build Action: Content, Copy-if-newer)
 |  |--VariousSourceFiles.cs
 |--ClassLibrary
 |  |--Resources
 |  |  |--Elements.xml     (Build Action: Content, Copy-if-newer)
 |  |  |--AminoAcids.xml   (Build Action: Content, Copy-if-newer)
 |  |--VariousSourceFiles.cs

The Main Gui project is the StartUp project for this program and is a simple MDI container that launches the other GUI applications within it. When I build in either Debug/Release mode on my development machine, everything works as expected. The GUI programs are compiled, the Datafile.wav and Mods.xml files are copied to the bin/ folder and the Elements.xml and AminoAcids.xml files are copied to the bin/Resources/ folder. The program functions as expected with no hiccups.

Here is where the problem begins, I use the Click-Once publishing feature in VS2010 to release the program internally to my co-workers on our server. They are able to install the program just fine and even start it up. But as soon as they click on a button that uses one of the resource files (Elements.xml or AminoAcids.xml) it throws an exception that the file cannot be found. This doesn't happen for the other two content files (Datafile.wav and Mods.xml) in other words, those are correctly copied to the final directory.

So I go to Main Gui Project -> Properties -> Publish -> Application Files.. and I see that the Datafile.wav and Mods.xml are included in this list. However, the other two content files (Elements.xml and AminoAcids.xml) are not. I believe this is the problem, because when I publish the program to our server, it doesn't know to copy the resources over. How would I inform ClickOnce that they need to include these files? The ClassLibrary.dll shows up in this list, but none of the .xml files.

I then tried to go to ClassLibrary -> Properties -> Publish but there is no tab for Publish because it is a Class Library. So I am unable to specify that I want those two resource files to be copied to the final bin/Resources file on any client computer. Does any have any idea how to overcome this?

I would like to keep the resource files (.xml) as Build Action: Content and not Embedded Resources since the users of the program might change/update/expand the contents of the files.

2
I wish this would be answered some day... I have approximately the same problem with Visual Studio 2005, not being able to include an XSD file into the ClickOnce deployment scheme - hello_earth

2 Answers

2
votes

I know this is not pretty but it will get the job done. Microsoft has an article that shows you how to add a data file to your Click Once deployment AFTER it has been published. You could fairly easily automate these steps

The link to the article is: http://msdn.microsoft.com/en-us/library/6fehc36e(v=vs.110).aspx

Here are the steps in case the link changes: To include a data file by using Mage.exe

1. Add the data file to your application directory with the rest of your application's files.

Typically, your application directory will be a directory labeled with the deployment's current version—for example, v1.0.0.0.

2. Update your application manifest to list the data file.

mage -u v1.0.0.0\Application.manifest -FromDirectory v1.0.0.0

Performing this task re-creates the list of files in your application manifest and also automatically generates the hash signatures.

3. Open the application manifest in your preferred text or XML editor and find the file element for your recently added file.

If you added an XML file named Data.xml, the file will look similar to the following code example.

<file name="Data.xml" hash="23454C18A2DC1D23E5B391FEE299B1F235067C59" hashalg="SHA1" asmv2:size="39500" /> 

1. Add the attribute type to this element, and supply it with a value of data.

<file name="Data.xml" writeableType="applicationData" hash="23454C18A2DC1D23E5B391FEE299B1F235067C59" hashalg="SHA1" asmv2:size="39500" /> 

1. Re-sign your application manifest by using your key pair or certificate, and then re-sign your deployment manifest.

You must re-sign your deployment manifest because its hash of the application manifest has changed.

mage -s app manifest -cf cert_file -pwd password

mage -u deployment manifest -appm app manifest

mage -s deployment manifest -cf certfile -pwd password

0
votes

This seems simpler.

  1. In the class library project directory that needs the data file(s), locate the data file(s) there.
  2. In the class library project, go to the project properties tab, click Build Events tab and update the Post-build event command line and add script code, using copy or xcopy, to copy the data file(s) relatively to the executable assembly, that uses the class library file as a dependency, as indicated by a project reference, project's folder.
  3. In the executable assembly's project, setup the copied file(s) as Included with properties of "Build Action" "Content" and "Copy to Output Directory" "Copy Always."
  4. In the executable assembly project properties, goto Publish tab, click the "Applications Files..." button. Make sure to check "Show all files." Find the data file(s), make sure "Publish Status" is "Included" and Download Group is "Required."

ClickOnce will deploy the data file(s) with the class library and the the class library code will be able to find the data file(s) at runtime.

Please correct me if I'm wrong somewhere.