Clickonce 不包括用于部署的 NuGet System.Runtime DLL,因为 GAC 中存在不同的版本
Clickonce not including NuGet System.Runtime DLL for deployment because a different version exists in GAC
- 我们有一个使用 nuget 包 X 的应用程序。
- Nuget 包 X 使用 nuget 包 System.Runtime 4.1.1.0
- 我们的应用程序引用了 System.Runtime 4.1.1.0,CopyLocal=true
- System.Runtime 4.0.0.0 作为 .NET Framework 的一部分存在于 GAC 中
对我们来说很不幸,因为 Sys.Runtime 4.0.0.0 在 GAC 中,ClickOnce 因此不会在我们的部署包中包含 System.Runtime 4.1.1.0。
因此,我们的应用程序抛出异常,提示 System.Runtime 4.1.1.0 在启动时未找到。
有什么方法可以强制将 System.Runtime 4.1.1.0 包含在包中?我尝试手动编辑项目文件,但无济于事。
- 在 'Publish' 选项卡的 'application files' 按钮下,System.Runtime 不可用。
谢谢
在应用项目中添加参考截图:
进入你的项目并确保有对 Sys.Runtime 4.1.1.0.
的引用
在解决方案资源管理器中右键单击引用并选择属性
上属性sheet供参考,设置"Specific Version"为真。
Clean/build全部.
重建您的 ClickOnce 安装程序并进行测试。
在没有官方 clickonce 修复的情况下,这里有一个解决方法:
- 将以下 class 粘贴到您的应用程序中
- 创建一个名为 'ClickOnceSucks'
的文件夹
- 将遇到问题的 DLL 放在该文件夹中。
将 DLL 设置为嵌入式资源类型
将您的应用程序入口点设置为 'AppStartupHook'
public class AppStartupHook
{
[STA线程]
public static void Main(字符串[] args)
{
ClickOnceSucks();
App.Main();
}
/// <summary>
/// Copies the embedded resources into the application path before startup.
/// </summary>
private static void ClickOnceSucks()
{
const string folderName = "ClickOnceSucks";
const string structureFormat = "{0}.{1}.";
var assembly = Assembly.GetExecutingAssembly();
var resourceFolder = structureFormat.FormatCurrent(assembly.GetName().Name, folderName);
//Find all resources in the clickoncesucks folder and copy them to our path.
assembly
.GetManifestResourceNames()
.Where(each => each.StartsWith(resourceFolder, StringComparison.Ordinal))
.Select(each => new
{
Name = each.Replace(resourceFolder, string.Empty),
Data = assembly.GetManifestResourceStream(each)
})
.Where(each => !File.Exists(each.Name))
.ForEach(each =>
{
using (var fileStream = new FileStream(each.Name, FileMode.Create, FileAccess.Write))
each.Data.CopyTo(fileStream);
});
}
}
看看我的回答
有和你一样的问题。你只需要做我为这个问题写的第二种方式。
- 我们有一个使用 nuget 包 X 的应用程序。
- Nuget 包 X 使用 nuget 包 System.Runtime 4.1.1.0
- 我们的应用程序引用了 System.Runtime 4.1.1.0,CopyLocal=true
- System.Runtime 4.0.0.0 作为 .NET Framework 的一部分存在于 GAC 中
对我们来说很不幸,因为 Sys.Runtime 4.0.0.0 在 GAC 中,ClickOnce 因此不会在我们的部署包中包含 System.Runtime 4.1.1.0。
因此,我们的应用程序抛出异常,提示 System.Runtime 4.1.1.0 在启动时未找到。
有什么方法可以强制将 System.Runtime 4.1.1.0 包含在包中?我尝试手动编辑项目文件,但无济于事。
- 在 'Publish' 选项卡的 'application files' 按钮下,System.Runtime 不可用。
谢谢
在应用项目中添加参考截图:
进入你的项目并确保有对 Sys.Runtime 4.1.1.0.
的引用
在解决方案资源管理器中右键单击引用并选择属性
上属性sheet供参考,设置"Specific Version"为真。
Clean/build全部.
重建您的 ClickOnce 安装程序并进行测试。
在没有官方 clickonce 修复的情况下,这里有一个解决方法:
- 将以下 class 粘贴到您的应用程序中
- 创建一个名为 'ClickOnceSucks' 的文件夹
- 将遇到问题的 DLL 放在该文件夹中。
将 DLL 设置为嵌入式资源类型
将您的应用程序入口点设置为 'AppStartupHook'
public class AppStartupHook { [STA线程] public static void Main(字符串[] args) { ClickOnceSucks();
App.Main(); } /// <summary> /// Copies the embedded resources into the application path before startup. /// </summary> private static void ClickOnceSucks() { const string folderName = "ClickOnceSucks"; const string structureFormat = "{0}.{1}."; var assembly = Assembly.GetExecutingAssembly(); var resourceFolder = structureFormat.FormatCurrent(assembly.GetName().Name, folderName); //Find all resources in the clickoncesucks folder and copy them to our path. assembly .GetManifestResourceNames() .Where(each => each.StartsWith(resourceFolder, StringComparison.Ordinal)) .Select(each => new { Name = each.Replace(resourceFolder, string.Empty), Data = assembly.GetManifestResourceStream(each) }) .Where(each => !File.Exists(each.Name)) .ForEach(each => { using (var fileStream = new FileStream(each.Name, FileMode.Create, FileAccess.Write)) each.Data.CopyTo(fileStream); }); }
}
看看我的回答
有和你一样的问题。你只需要做我为这个问题写的第二种方式。