在 VS 2022 中打开 .net framework 4.5 项目。有什么解决方法吗?

Open .net framework 4.5 project in VS 2022. Is there any workaround?

是否可以在 visual studio 2022 中打开并处理 .net framework 4.5 项目。

问题可能不是 VS2022,而是 .net framework 4.5 开发包不再可用。我的项目无法更改目标版本。有什么解决方法吗?

更多详情:Building a project that target .NET Framework 4.5 in Visual Studio 2022

这是一个自动化的解决方案。它遵循此答案中的步骤: 当它复制文件时,可能会出现一个对话框,您必须单击该对话框才能替换已存在的文件

(注意:如果有较新的 NuGet package)[=16=,您可能需要将“版本”"1.0.2" 更新为最新版本]

运行 await DevHelpers.Download();

using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace j.Dev
{
    public class DevHelpers
    {
        public static async Task Download()
        {
            var version = "1.0.2";
            var name = "Framework45-" + DateTimeToFileString(DateTime.Now);
            var fileName = $"{name}.zip";
            var url = $"https://www.nuget.org/api/v2/package/Microsoft.NETFramework.ReferenceAssemblies.net45/{version}";
            await DownloadFile(fileName, url);
            ZipFile.ExtractToDirectory(fileName, name);
            var from = Path.Join(name, @"build\.NETFramework\v4.5\");
            var to = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5";
            FileSystem.CopyDirectory(from, to, UIOption.AllDialogs);
        }

        private static string DateTimeToFileString(DateTime d)
        {
            return d.ToString("yyyy-dd-M--HH-mm-ss");
        }

        private static async Task DownloadFile(string fileName, string url)
        {
            var uri = new Uri(url);
            HttpClient client = new HttpClient();
            var response = await client.GetAsync(uri);
            using (var fs = new FileStream(
                fileName,
                FileMode.CreateNew))
            {
                await response.Content.CopyToAsync(fs);
            }
        }
    }
}

在我的例子中,我需要下载 4.0 和 4.5,所以这里是同时下载 4.0 和 4.5 的代码:

using Microsoft.VisualBasic.FileIO;
using System.IO.Compression;

namespace j.Dev
{
    /// <summary>
    /// Example Usage: await DevHelpers.DownloadAndCopyFramework4_0And4_5();
    /// </summary>
    public class DevHelpers
    {
        public static async Task DownloadAndCopyFramework4_0And4_5()
        {
            await DownloadAndCopyFramework4_0();
            await DownloadAndCopyFramework4_5();
        }

        public static async Task DownloadAndCopyFramework4_5()
        {
            await DownloadAndCopyFrameworkGeneric("net45", "v4.5", "1.0.2");
        }

        public static async Task DownloadAndCopyFramework4_0()
        {
            await DownloadAndCopyFrameworkGeneric("net40", "v4.0", "1.0.2");
        }

        public static async Task DownloadAndCopyFrameworkGeneric(string netVersion, string folder, string nugetVersion)
        {
            var name = netVersion + "-" + DateTimeToFileString(DateTime.Now);
            var fileName = $"{name}.zip";
            var url = $"https://www.nuget.org/api/v2/package/Microsoft.NETFramework.ReferenceAssemblies.{netVersion}/{nugetVersion}";
            await DownloadFile(fileName, url);
            ZipFile.ExtractToDirectory(fileName, name);
            var from = Path.Join(name, @"build\.NETFramework\" + folder);
            var to = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\" + folder;
            FileSystem.CopyDirectory(from, to, UIOption.AllDialogs);
        }

        private static string DateTimeToFileString(DateTime d)
        {
            return d.ToString("yyyy-dd-M--HH-mm-ss");
        }

        private static async Task DownloadFile(string fileName, string url)
        {
            var uri = new Uri(url);
            HttpClient client = new HttpClient();
            var response = await client.GetAsync(uri);
            using (var fs = new FileStream(
                fileName,
                FileMode.CreateNew))
            {
                await response.Content.CopyToAsync(fs);
            }
        }
    }
}

对于 .NET 4.0,如果您缓存了 Visual Studio 2019 文件,此命令将为您安装它:

msiexec.exe /i "%ALLUSERSPROFILE%\Microsoft\VisualStudio\Packages\Microsoft.Net.4.TargetingPack,version=4.0.30319.1\netfx_dtp.msi" EXTUI=1

对于 .NET 4.5,这可能有效,但我还没有尝试过:

msiexec.exe /i "%ALLUSERSPROFILE%\Microsoft\VisualStudio\Packages\Microsoft.Net.4.5.2.TargetingPack,version=4.5.51651.1\netfx_452mtpack.msi" EXTUI=1

虽然所有提议的、甚至被接受的解决方案都可行,但其中 none 是首选 方法。

您唯一需要做的就是添加对 NuGet 包的引用,如下所示:

<ItemGroup>
 <PackageReference Include="microsoft.netframework.referenceassemblies.net45"
                   Version="1.0.2" PrivateAssets="All" />
</ItemGroup>

您可以直接在 *.csproj 中或通过 包管理器 UI 在 Visual Studio 中进行此更改。包中的 MSBuild 扩展将负责 magic 的其余部分。无需编写脚本、复制文件或 g运行t 权限。这将在没有提升的情况下工作,这将需要在 %PROGRAMFILES%.

下编写

设置 PrivateAssets="All" 将使包引用仅 design-time。如果您的目标还构建了 NuGet 程序包,它将不会被拾取或包含为 t运行sitive 依赖项。

Roslyn Issue 56161: Remove .NET 4.5 Targeting Pack Requirement 进一步证实了在未安装目标包时您如何使用参考程序集。任何时候您不想安装目标包或它不可用时,这种方法都很有用 - 比如在没有 Visual Studio.

的构建服务器上

我 运行 在卸载 Visual Studio 2019 后遇到了同样的问题。在添加此包引用后,Visual Studio 和 CLI 的构建按预期工作。

安装 多个 旧目标包的另一种方法是安装 Visual Studio 2019。

注意:如果你卸载VS2019,它会再次删除它们,所以把你想要的复制下来,然后再粘贴回来。

来自关于复制文件的答案链接的文章的评论:“安装”Windows 8 SDK”。它可以只安装“.Net Framework 4.5 软件开发工具包”。没有其他包袱."

这个选项对我来说是最快的,因为我可以运行提升的安装程序比切换到提升的安装程序更容易写入程序文件文件夹。