如何在多项目中链接resx文件 无需每次构建前运行自定义工具
该问题的最优解决方案
方案1:自定义资源类,脱离自动生成的Designer文件依赖(最优选择)
完全摒弃VS自动生成的LibStrings.Designer.vb,从根源避免硬编码项目名的问题:
- 删除所有项目中链接的
LibStrings.Designer.vb文件,不再依赖VS自定义工具生成的代码 - 在类库项目中编写自定义的
LibStrings静态类,动态适配当前运行项目的命名空间,示例代码如下:
Public Class LibStrings Private Shared _resourceManager As Global.System.Resources.ResourceManager Public Shared ReadOnly Property ResourceManager As Global.System.Resources.ResourceManager Get If _resourceManager Is Nothing Then ' 自动获取当前LibStrings类所在的命名空间 Dim currentNamespace = GetType(LibStrings).Namespace ' 自动获取当前类所在的程序集 Dim currentAssembly = GetType(LibStrings).Assembly _resourceManager = New Global.System.Resources.ResourceManager($"{currentNamespace}.LibStrings", currentAssembly) End If Return _resourceManager End Get End Property ' 按照你实际的资源项添加对应属性即可,示例: Public Shared ReadOnly Property SuccessTip As String Get Return ResourceManager.GetString("SuccessTip") End Get End Property End Class
- 三个项目仅保留对类库项目的
LibStrings.resx和上述自定义LibStrings类的链接即可,后续无需手动运行自定义工具,编译任意项目都会自动适配当前项目的资源路径。
方案2:统一配置resx的自定义工具命名空间
如果不想手动编写资源类,可以通过统一命名空间的方式解决硬编码问题:
- 分别选中A、B、C三个项目下链接的
LibStrings.resx文件,右键打开属性面板 - 将每个项目下该文件的
Custom Tool Namespace属性统一设置为固定值,比如GlobalSharedResources - 随便选择任意一个项目运行一次「Run Custom Tool」,生成的
LibStrings.Designer.vb中资源路径就会固定为GlobalSharedResources.LibStrings,不再携带项目名前缀,三个项目可以通用该生成文件 - 注意要确保三个项目的resx文件的生成操作都设置为「嵌入的资源」,保证资源会被编译到对应程序集中。
方案3:添加预构建事件自动替换硬编码(次优选择)
如果要保留原有自动生成Designer文件的逻辑,可以通过构建脚本自动修正资源路径:
- 分别打开A、B、C三个项目的属性页,进入「生成事件」配置
- 在预生成事件命令行中输入如下脚本,构建时会自动替换Designer文件中的硬编码项目名:
powershell -Command "(Get-Content '$(ProjectDir)LibStrings.Designer.vb') -replace 'ResourceManager\(\"[^\"]+\.LibStrings\"', 'ResourceManager(\"$(RootNamespace).LibStrings\"') | Out-File '$(ProjectDir)LibStrings.Designer.vb' -Encoding utf8"
- 后续构建任意项目都会自动适配当前项目的根命名空间,无需手动运行自定义工具。
三个方案均不需要重复拷贝resx文件到各个项目,也不需要依赖第三方VS扩展。优先选择方案1,完全脱离VS自定义工具的限制,后续维护成本最低。
内容的提问来源于stack exchange,提问作者MatthewNYC
相关产品推荐
相关产品推荐

