60

如何在 .resx 文件中查找可能已“孤立”且不再需要的未使用图标、图像、字符串?

4

10 回答 10

51

最近ResXManager 1.0.0.41添加了一个功能来显示对字符串资源的引用数。

显示新参考列的屏幕截图

于 2014-09-04T13:12:17.753 回答
20

我找不到任何可以在 XAML 文件中搜索字符串资源引用并批量删除未使用的资源引用的现有解决方案。

所以我写了这个:https ://github.com/Microsoft/RESX-Unused-Finder

RESX 未使用的 Finder 屏幕截图

它在项目目录中搜索对字符串资源的引用,然后显示找不到匹配项的列表。您可以指定要搜索的模板,以便它可以在 XAML 文件中找到引用。

于 2014-10-27T23:41:15.147 回答
11

我创建了一个免费的开源 VS 扩展,用于查找项目中未使用的图像,刚刚发布了第一个版本:https ://marketplace.visualstudio.com/items?itemName=Jitbit1.VSUnusedImagesFinder

于 2012-03-23T07:40:25.727 回答
8

这不是算法可以可靠计算的信息。被检查的程序可以获取所有资源的列表并对它们做一些事情,比如让用户从几个图标中进行选择。

您最好的选择可能是搜索对您选择的资源访问 API 的所有引用并手动检查这些引用。使用grep/sed您可以通过处理所有使用简单字符串的“简单”站点来减少必须手动检查的站点。

于 2008-10-29T07:13:39.513 回答
7

由于我还没有找到一个简单快速的解决方案,我至少找到了一个解决方案,它可以让我得到我正在寻找的结果,即使它需要一些时间(非常适合慵懒的周日下午)。

该解决方案涉及 Visual Studio .NET 2010 和 ReSharper(我使用的是 7.1 版),如下所示。

分步解决方案

1.)右键单击​​ VS.NET 中的主 RESX 文件,然后从上下文菜单中选择“查找用法”:

在此处输入图像描述

这将打开 ReSharper 的“查找结果”窗口。

2.)双击解决方案窗口中的每个事件:

在此处输入图像描述

这将打开包含资源的源代码窗口。

3.)从源代码窗口中重命名此资源:

在此处输入图像描述

它将调出 ReSharper 的“重命名资源”对话框。

4.)给资源一个带有唯一前缀的新名称。在我的示例中,这是“TaskDialog_”:

在此处输入图像描述

它将重命名资源以及自动生成的 C# 包装器/访问类。

5.)对“使用”窗口中的所有资源重复上述步骤 2、3 和 4。

6.)在 Visual Studio 的资源编辑器中打开 RESX 文件并选择所有不带前缀的文件:

在此处输入图像描述

7.)现在单击窗口顶部的“删除资源”按钮或只需按下Del键:

在此处输入图像描述

您终于有了一个 RESX 文件,其中仅包含文件中实际使用的资源。

8.)(可选)如果您有多种语言的资源(例如,德语的“Resources.de.resx”),也对这些 RESX 文件重复步骤 7 和 8。

警告

请注意,如果您通过强类型、自动生成的 C# 类以外的方式访问字符串,这将不起作用Resources

于 2012-12-09T10:03:40.323 回答
6

我最近构建了一个工具来检测和删除未使用的字符串资源。我使用这篇文章中的信息作为参考。该工具可能并不完美,但它完成了繁重的工作,如果您有一个历史悠久的大项目,它将很有用。我们在内部使用此工具来整合资源文件,并删除未使用的资源(我们从 10,000 个资源中删除了 4,000 多个资源)。

您可以查看源代码,或者从这里安装 ClickOnce:https ://resxutils.codeplex.com/

于 2013-10-28T19:19:35.940 回答
3

我有一个类似的问题。我为翻译表创建了数千个资源字符串,其中许多不再需要或通过代码引用。由于有大约 180 个依赖代码文件,我无法手动检查每个资源字符串。

以下代码(在 vb.net 中)将通过您的项目查找孤立资源(在项目资源中,而不是任何单个表单的资源中)。我的项目花了大约 1 分钟。可以修改它以查找字符串、图像或任何其他资源类型。

总而言之;

  • 1) 使用解决方案项目文件收集所有包含的代码模块并将它们附加到单个字符串变量中;
  • 2)循环遍历所有项目资源对象,并创建一个列表(在我的情况下)是字符串;
  • 3) 是否在组合项目文本变量中查找资源字符串代码的字符串搜索;
  • 4) 报告未被引用的资源对象。

该函数返回 Windows 剪贴板上的对象名称,以便粘贴到电子表格中或作为资源名称的列表数组。

编辑:模块中的示例调用:modTest
? modTest.GetUnusedResources("C:\Documents and Settings\me\My Documents\Visual Studio 2010\Projects\myProj\myProj.vbproj", True, true)

'project file is the vbproj file for my solution
Public Function GetUnusedResources(projectFile As String, useClipboard As Boolean, strict As Boolean) As List(Of String)


    Dim myProjectFiles As New List(Of String)
    Dim baseFolder = System.IO.Path.GetDirectoryName(projectFile) + "\"

    'get list of project files 
    Dim reader As Xml.XmlTextReader = New Xml.XmlTextReader(projectFile)
    Do While (reader.Read())
        Select Case reader.NodeType
            Case Xml.XmlNodeType.Element 'Display beginning of element.
                If reader.Name.ToLowerInvariant() = "compile" Then ' only get compile included files
                    If reader.HasAttributes Then 'If attributes exist
                        While reader.MoveToNextAttribute()
                            If reader.Name.ToLowerInvariant() = "include" Then myProjectFiles.Add((reader.Value))
                        End While
                    End If
                End If
        End Select
    Loop

    'now collect files into a single string
    Dim fileText As New System.Text.StringBuilder
    For Each fileItem As String In myProjectFiles
        Dim textFileStream As System.IO.TextReader
        textFileStream = System.IO.File.OpenText(baseFolder + fileItem)
        fileText.Append(textFileStream.ReadToEnd)
        textFileStream.Close()
    Next
    '  Debug.WriteLine(fileText)

    ' Create a ResXResourceReader for the file items.resx.
    Dim rsxr As New System.Resources.ResXResourceReader(baseFolder + "My Project\Resources.resx")
    rsxr.BasePath = baseFolder + "Resources"
    Dim resourceList As New List(Of String)
    ' Iterate through the resources and display the contents to the console.
    For Each resourceValue As DictionaryEntry In rsxr
        ' Debug.WriteLine(resourceValue.Key.ToString())
        If TypeOf resourceValue.Value Is String Then ' or bitmap or other type if required
            resourceList.Add(resourceValue.Key.ToString())
        End If
    Next
    rsxr.Close()  'Close the reader.

    'finally search file string for occurances of each resource string
    Dim unusedResources As New List(Of String)
    Dim clipBoardText As New System.Text.StringBuilder
    Dim searchText = fileText.ToString()
    For Each resourceString As String In resourceList
        Dim resourceCall = "My.Resources." + resourceString ' find code reference to the resource name
        Dim resourceAttribute = "(""" + resourceString + """)" ' find attribute reference to the resource name
        Dim searchResult As Boolean = False
        searchResult = searchResult Or searchText.Contains(resourceCall)
        searchResult = searchResult Or searchText.Contains(resourceAttribute)
        If Not strict Then searchResult = searchResult Or searchText.Contains(resourceString)
        If Not searchResult Then ' resource name no found so add to list
            unusedResources.Add(resourceString)
            clipBoardText.Append(resourceString + vbCrLf)
        End If
    Next

    'make clipboard object
    If useClipboard Then
        Dim dataObject As New DataObject ' Make a DataObject clipboard
        dataObject.SetData(DataFormats.Text, clipBoardText.ToString())        ' Add the data in string format.
        Clipboard.SetDataObject(dataObject) ' Copy data to the clipboard.
    End If

    Return unusedResources

End Function
于 2013-02-13T22:36:43.623 回答
3

我使用 ReSharper 查找未使用的资源字段,然后如果项目包含少量资源,则手动删除它们。如果我们已经有未使用项目的列表,可以使用一些简短的脚本。

接下来是解决方案:

  • 显示本文所述的所有未使用的成员
  • 从生成的文件掩码中临时删除 *.Designer.cs (ReSharper → 选项 → CodeInspection → GeneratedCode)
  • 还要从附加到资源文件的 Designer.cs 文件顶部注释或删除注释(表示代码是自动生成的)。

您将获得所有未使用资源的列表,以便将它们从 resx 中删除。

于 2014-06-13T08:33:06.283 回答
1

我自己一直在考虑这个问题,我相信我有两个选择。这两者都依赖于我使用辅助方法从资源文件中提取所需资源的事实。

  1. 记录
    向“getresource”方法或方法添加一些代码,以便每次访问资源时,将资源键写入日志。然后尝试访问站点的每个部分(测试脚本在这里可能会有所帮助)。生成的日志条目应该给出所有活动资源键的列表,其余的可以被垃圾。

  2. 代码分析
    我正在查看T4是否能够完成解决方案并创建对“getresource”辅助方法的所有引用的列表。结果键列表将处于活动状态,其余的可以删除。

这两种方法都有局限性。日志记录方法仅与测试覆盖的代码一样好,并且代码分析可能并不总是找到键而不是包含键的字符串,因此那里需要一些额外的手动工作。

我想我会尝试两个。我会让你知道情况如何。

于 2009-06-30T19:01:29.310 回答
1

重命名您当前的图像目录,然后创建一个新目录,在 VS 中进行文件查找搜索您的图像路径,即“/content/images”,多选所有使用的图像并将它们拖到新的图像文件夹中。然后,您可以从项目中排除旧目录,或者将其删除。

于 2011-02-03T22:48:00.917 回答