1

我想知道是否有人可以帮我做点什么。

主要思想是我想要一个 .NET Framework 控制台应用程序,它被构建并打包到单个文件中(存档或类似的东西,如 java 世界中的 jar 文件,包含所有引用的 .dll 文件、源文件和其他项目文件),我可以部署在另一台机器上。

我使用 .NET 4.7.2 构建了一个控制台应用程序,它从远程服务器接收数据并将其推送到 RabbitMQ。我使用 .p12 文件向 RMQ 进行身份验证,我将其保存在我的应用程序中名为“Others”的子文件夹中。

当我从 Visual Studio 2019 运行它时,它可以工作,但是当我尝试释放它并从该文件夹运行它或将它安装在我的 Windows 10 机器上时,它不再工作了。它给了我以下例外:

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.
...

当我通过发布窗口发布应用程序时,我选择了一个输出文件夹,我得到以下文件和文件夹:

  • (文件夹)应用程序文件
  • (文件)设置,文件类型 - Application.exe (.application)
  • (文件)ConsoleApp,文件类型 - 应用程序清单 (.application) 包含 RabbitMQ 客户端的 RabbitMQ .dll 文件位于文件夹“Application Files\ConsoleApp_1_0_0_13”以及其他 .dll 文件和一个子文件夹(“XMLRequest” ) 但不包含我项目的其他子文件夹。我无法在应用程序的发布屏幕中添加我的 .p12 密钥所在的这些子文件夹,即“其他”。

另一种不起作用的情况是,我将整个“Release”子文件夹复制到另一个位置,然后从那里运行 ConsoleApp.exe。我收到相同的错误消息。

有人有想法吗?谢谢 !

4

2 回答 2

2

尝试以下操作:

  1. 在 Visual Studio 中打开项目
  2. 转到解决方案资源管理器->单击项目->单击解决方案资源管理器菜单中的“显示所有文件”菜单
  3. 项目中的所有文件夹都将在项目文件树中以虚线边框出现
  4. 右键单击您的文件夹,然后单击“包含在项目中”
  5. 通过在解决方案资源管理器中展开文件夹导航到您的文件
  6. 右键单击文件,然后单击“属性”
  7. 在“属性”窗口中,为“复制到输出目录”选择“始终复制”

执行上述步骤将导致 Visual Studio 将整个文件夹复制到输出(调试和发布)目录。

还有另一个选项可以在构建和发布过程中发布所需的文件。右键单击所需的文件,然后单击属性。在属性窗口中,将 Build Action 属性的适当值设置为您需要的值。以下文档描述了何时使用哪些构建操作值。

https://docs.microsoft.com/en-us/visualstudio/ide/build-actions?view=vs-2019

于 2021-02-05T16:30:20.287 回答
1

将您的应用程序打包为单个 .exe 文件

如果您希望将 .NET Framework 控制台应用程序打包到单个文件中,那么我会查看 nuget package Costura.Fody。它会为您将所有项目 DLL 打包成一个 .exe。我用它所有的时间。

您需要做的就是将 nuget 包添加到您的项目中,如下所示:

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

并且out会弹出一个.exe

嵌入资源文件 - 选项 #1

如果您想在部署中包含文件,我过去所做的是将它们嵌入到 exe 本身中,然后在应用程序运行时提取它们。

为此,请照常将文件添加到您的项目中:

在此处输入图像描述

然后右键单击该文件并选择“属性”并将构建操作设置为“嵌入式资源”。

在此处输入图像描述

这将允许您稍后在程序运行时提取文件。通过此设置,您可以在应用程序中设置任意数量的资源文件。

然后在应用程序启动时,您可以使用如下函数将嵌入的资源提取到磁盘上的文件中:

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;
}

使用上面的函数看起来像这样:

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

然后您可以将文件写入磁盘上您需要的任何位置。

嵌入资源文件 - 选项 #2

另一种选择是将嵌入的资源复制到输出文件夹,但这意味着如果您手动将其从一台机器复制到另一台机器,您将不会拥有一个 .exe 文件。

在此处输入图像描述

嵌入资源文件 - 选项 #3

如果您使用 ClickOnce 技术来部署您的应用程序,看起来就像您一样,那么当您转到发布选项卡时,如果您选择“应用程序文件”

在此处输入图像描述

然后,您可以选择要包含在部署中的文件,如此处所示。

在此处输入图像描述

于 2021-02-05T16:24:14.800 回答