The Problem
My solution is made up of a handful of projects. The main one for the UI we'll call Assistant, and the backend we'll call AssistantLib.
Here is the structure:
In AssistantLib I have included PDFs as resources in a Resources folder with a Build Action
of Content and Copy to Output Directory
as Copy Always. I am able to locate them when debugging by using a combo of these:
private string GetArtifactPath(string artifactName)
{
return Path.Combine(GetResourcePath(), artifactName);
}
public static string GetResourcePath()
{
return Path.Combine(Directory.GetCurrentDirectory(), "Resources");
}
This works. Once I return the string from GetArtifactPath, I open the File with a Process
object and AcroRd32.exe
.
Note that I need to reference these files by their file paths. They're not simple txts to read or stream. I also need to be able to open them with certain flag provided by AcroRd32.exe
. That means I must have the file path.
The problem I'm having as that once I publish the ClickOnce app, I receive an error that the file couldn't be found:
Error: Could not find a part of the path 'C:\Users\EL-C\AppData\Local\Apps\2.0\3JCPDD49.7G5\9122AMZE.NZL\azte..tion_edea8654ffceff97_0001.0000_447ed0da08290357\Resources\Guidelines\3.2'.. Stacktrace: at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
And of course, when I go to that location, the resources aren't there.
What I've Tried
Build Action
to Embedded Resource & None - same resultCopy Output Directory
to Do Not CopyMyNamespace.Properties.Resources.My_Zip_File;
doesn't work in my situation. I don't know the name of the resource ahead of time.Update
I am looking into post-build events. In doing so, I found that these resources are already in the output directory following a build:
But for some reason they don't show up when I publish:
Update 2
To illustrate how the folder structure affects this, here are before and afters.
When a Resource is in AssistantLib
(e.g. EVMSBP), this is the structure:
And here is what the ClickOnce publish folder looks like after installing with the resource in AssistantLib
:
Alternatively, when a Resource is in Assistant
(again EVMSBP), this is the structure:
And here's what the ClickOnce publish folder looks like after installing with the resource in Assistant
:
From what I can tell, the Resource MUST be a part of the Startup project. That sounds like insanity?
What am I missing?
With more details from the edit, this is how I replicated it
In AssistLib project
Build Action
as Embedded Resources
. Output Type:
Class Library
(AssistLib.dll)
AssistLib.dll
AzTech.cs
var nameOfTheFile = "test.pdf";
ResourceManager.GetResourceInfo(nameOfTheFile);
if (ResourceManager.resourceExists == false)
{ Console.WriteLine("Specified PDF file not found"); return; }
Console.WriteLine("Resouce found in DLL");
ResourceManager.LoadResource(nameOfTheFile);//Will load the pdf in your main project
Process.Start(nameOfTheFile);
class ResourceManager
{
public static bool resourceExists { get; set; } = false;
private static Stream resourceStream { get; set; }
public static void GetResourceInfo(string fileNameWithExtension)
{
const string pathToResource = "AssistantLib.Resources.Guidelines";
var assembly = Assembly.Load("AssistantLib");
//var names = assembly.GetManifestResourceNames();
var stream = assembly.GetManifestResourceStream($"{pathToResource}.{fileNameWithExtension}");
if (stream == null)
return;
resourceExists = true;
resourceStream = stream;
}
public static void LoadResource(string newFileNameWithExtension)
{
if(File.Exists(newFileNameWithExtension))
{
Console.WriteLine("File already exists");
return;
}
using (Stream s = File.Create(newFileNameWithExtension))
{
Console.WriteLine("Loading file");
resourceStream.CopyTo(s);
}
}
}