在.NET解决方案中查找未使用的资源

时间:2008-10-29 06:27:09

标签: .net resources

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

10 个答案:

答案 0 :(得分:36)

最近ResXManager 1.0.0.41添加了一项功能,以显示对字符串资源的引用次数。

Screenshot showing the new reference column

答案 1 :(得分:15)

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

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

RESX Unused Finder screenshot

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

答案 2 :(得分:11)

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

答案 3 :(得分:10)

这不是算法可以可靠计算的信息。被检查的程序可以获取所有资源的列表并对它们执行某些操作,例如让用户从多个图标中进行选择。

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

答案 4 :(得分:6)

由于我找不到简单快速解决方案,我发现至少有一个解决方案可以让我得到我正在寻找的结果,即使这需要一些时间(适合懒惰的周日下午)。

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

分步解决方案

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

enter image description here

这将显示ReSharper的“查找结果”窗口。

2。)双击解决方案窗口中的每个匹配项:

enter image description here

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

3。)在源代码窗口中重命名此资源:

enter image description here

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

4。)为资源指定一个带有唯一前缀的新名称。在我的例子中,这是“TaskDialog _”:

enter image description here

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

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

6。)在Visual Studio的资源编辑器中打开RESX文件,然后选择没有前缀的所有文件:

enter image description here

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

enter image description here

您最终拥有一个RESX文件,其中只包含文件中实际使用的资源。

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

警告

请注意,如果您通过强类型自动生成的C#类Resources访问字符串,则无法使用此功能。

答案 5 :(得分:6)

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

您可以查看源代码,或者只需从此处安装ClickOnce:https://resxutils.codeplex.com/

答案 6 :(得分: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

答案 7 :(得分:2)

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

接下来是解决方案:

  • 按照this article
  • 中的说明显示所有未使用的成员
  • 临时从生成的文件掩码中删除* .Designer.cs (ReSharper→选项→CodeInspection→GeneratedCode)
  • 同时评论或删除评论(表示代码是自动的 从附加到资源文件的Designer.cs文件的顶部生成)。

您将拥有所有未使用资源的列表,并将其从resx中删除。

答案 8 :(得分:1)

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

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

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

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

    我想我会两个都试试。我会告诉你它是怎么回事。

答案 9 :(得分:1)

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