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

你如何去查找可能已经成为“孤立”且不再需要的.resx文件中未使用的图标,图像,string?

algorithm不能可靠地计算这些信息。 被检查的程序可以获取所有资源的列表并且对它们做一些事情,比如让用户从多个图标中select。

您最好的select是search所有您select的资源访问API的引用,并手动检查这些API。 使用grep / sed你可能可以通过处理所有使用简单string的“简单”的手工来减less手动检查的站点。

最近ResXManager 1.0.0.41添加了一个function来显示string资源的引用数量。

屏幕截图显示新的参考列

我找不到任何现有的解决scheme,将searchXAML文件中的string资源引用并批量删除不使用的解决scheme。

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

RESX未使用的Finder截图

它会search项目目录以查找string资源,然后显示无法find匹配项的列表。 您可以指定一个模板进行search,以便在XAML文件中find引用。

我创build了一个免费的开源VS扩展,在项目中查找未使用的图像,刚发布了第一个版本: https : //github.com/jitbit/vs-unused-image-finder

由于找不到简单 快捷的解决scheme,我发现至less有一个解决scheme可以让我得到我期待的结果,即使这需要一些时间(对于懒惰的周日下午来说也是理想的)。

该解决scheme涉及Visual Studio .NET 2010和ReSharper(我正在使用版本7.1),如下所示。

一步一步的解决scheme

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

在这里输入图像说明

这将带来ReSharper的“查找结果”窗口。

2.)在解决scheme窗口中双击每个事件:

在这里输入图像说明

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

3.)在源代码窗口内重命名这个资源:

在这里输入图像说明

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

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

在这里输入图像说明

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

5.)在“使用”窗口中重复上述步骤2,3和4以获取所有资源。

6.)在Visual Studio的资源编辑器中打开RESX文件,select所有没有前缀的文件:

在这里输入图像说明

7.)现在单击窗口顶部的“删除资源”button,或者直接按Del键:

在这里输入图像说明

你终于有一个RESX文件只有在你的文件中使用的资源。

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

警告

请注意,如果您通过强types,自动生成的C#类Resources访问string,则这不起作用。

我最近build立了一个工具来检测和删除未使用的string资源。 我用这篇文章中的信息作为参考。 这个工具可能并不完美,但是如果你有一个有着悠久历史的大项目,那么这个工具将会很有用。 我们在内部使用这个工具来整合资源文件,并删除未使用的资源(我们摆脱了10000个以上的4000多个资源)。

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

我有一个类似的问题。 几千个我为转换表创build的资源string,其中许多资源string不再需要或由代码引用。 有大约180个依赖代码文件,我不会手动通过每个资源string。

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

总之呢,

  • 1)使用解决scheme项目文件收集所有包含的代码模块,并将它们附加到单个stringvariables;
  • 2)遍历所有的项目资源对象,并创build一个列表(在我的情况下)的string;
  • 3)是否在组合的项目文本variables中查找资源string代码;
  • 4)报告未被引用的资源对象。

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

编辑 :示例调用模块: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 

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

接下来的解决scheme是:

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

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

  1. logging
    将一些代码添加到“getresource”方法或方法中,以便每次访问资源时都将资源密钥写入日志。 然后尝试访问网站的每个部分(testing脚本可能会有所帮助)。 生成的日志条目应该提供所有活动资源键的列表,其余的可以被废弃。

  2. 代码分析
    我正在看是否T4能够通过解决scheme,并创build一个所有引用“getresource”帮助方法的列表。 键的结果列表将被激活,其余的可以被删除。

这两种方法都有局限性。 日志logging方法只与testing所涉及的代码一样好,代码分析可能并不总是find键而不是包含键的string,因此在那里需要一些额外的手动工作。

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

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