Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
96 views
in Technique[技术] by (71.8m points)

c# - How to copy .NET Framework Console Application subfolders to the release folder?

I was wondering if someone could please help me with something.

The main idea is that I want to have a .NET Framework Console App, which is build and packaged into a single file (an archive or something similar, like a jar file in the java world, containing all the referenced .dll files, sources files and additional project files) that i can deploy on another machine.

I've build an Console app using .NET 4.7.2 which is receiving data from a remote server and it pushes it to RabbitMQ. I use a .p12 file to authenticate to RMQ, which i keep stored in a sub-folder in my app called "Others".

When I run it from Visual Studio 2019 it works, but when I try either to release it and run it from that folder or to install it on my windows 10 machine it does not work anymore. It gives me the following exception :

RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.AggregateException: One or more errors occurred. ---> System.Security.Cryptography.CryptographicException: The system cannot find the path specified.
...

When I publish the app, via the publish window, I select an output folder and I get the following files and folders :

  • (folder) Application Files
  • (file) setup, type of file - Application.exe (.application)
  • (file) ConsoleApp, type of file - Application Manifest (.application) The RabbitMQ .dll file, which contains the RabbitMQ Client is located inside the folder "Application FilesConsoleApp_1_0_0_13" together with other .dll files and a subfolder ("XMLRequest") but does not contain the other subfolders of my project. I don't have the possibility to add these subfolders, where my .p12 key is located, i.e. "Others", in the publish screen of the application.

The other case when it does not work is when I to copy the whole "Release" subfolder into another location and just run the ConsoleApp.exe from there. I get the same error message.

Does anyone have an idea ? Thanks !

question from:https://stackoverflow.com/questions/66065601/how-to-copy-net-framework-console-application-subfolders-to-the-release-folder

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Packaging your app as a single .exe file

If you want your .NET Framework Console App, to be packaged into a single file, then I would take a look at the nuget package Costura.Fody. It will package up all the projects DLLs into a single .exe for you. I use it all the time.

All you need to do is add the nuget package to your project like this:

PM> Install-Package Fody
PM> Install-Package Costura.Fody

and out will pop a single .exe

Embedding Resource Files - Option #1

If you want to include files in your deployment, what I have done in the past is embed them in the exe themselves and then extract them when the app runs.

To do this, add the files to your project as normal:

enter image description here

Then right-click the file and select "properties" and set the build action to be an "embedded resource".

enter image description here

This will alow you extract the file later on, when the program is running. With this setup you could have any number of resource files setup in the app.

Then on startup of the app, you can extract the embedded resource to a file on disk using a function like this:

public static string GetEmbeddedResource(string resourceName)
{
    string resourceContents = "";

    try
    {
        string[] names = Assembly.GetEntryAssembly().GetManifestResourceNames();

        string resource = "";
        foreach (string str in names)
        {
            if (str.ToLower().Contains(resourceName.ToLower()) == true)
            {
                resource = str;
                break;
            }
        }

        if (string.IsNullOrEmpty(resource) == false)
        {
            using (StreamReader sreader = new StreamReader(Assembly.GetEntryAssembly().GetManifestResourceStream(resource), Encoding.Default))
            {
                resourceContents = sreader.ReadToEnd();
            }
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return resourceContents;
}

with the usage of the above function looking like this:

var resource = GetEmbeddedResource("SomeFile.txt");

and then you can write the file to anywhere you need it on disk.

Embedding Resource Files - Option #2

The other option would be to copy the embedded resource to the output folder but then that means you wont have a single .exe file if you are manually copying this from machine to machine.

enter image description here

Embedding Resource Files - Option #3

If you are using ClickOnce technology to deploy your app, which it looks like you are, then when you go to the publish tab, if you select the "Application Files"

enter image description here

you can then choose which files to include in the deployment as seen here.

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...