C# 转到资源重构

C# 转到资源重构,c#,visual-studio,roslyn,resx,vsix,C#,Visual Studio,Roslyn,Resx,Vsix,我正试图让我自己的转向资源重构(就像在ReSharper中找到的那样)。在我的CodeAction.GetChangedDocumentAsync方法中,我正在执行以下3个步骤: 使用XmlDocument 使用DTE运行自定义工具以更新Resources.Designer.cs文件 将文本字符串替换为新资源的限定标识符SyntaxNode.ReplaceNode 步骤1和2可以,但第3步不起作用。如果我删除步骤2,则步骤3正在工作 我不知道这是因为我混合了Roslyn和DTE,还是因为第2步在

我正试图让我自己的转向资源重构(就像在ReSharper中找到的那样)。在我的
CodeAction.GetChangedDocumentAsync
方法中,我正在执行以下3个步骤:

  • 使用
    XmlDocument
  • 使用DTE运行自定义工具以更新Resources.Designer.cs文件
  • 将文本字符串替换为新资源的限定标识符
    SyntaxNode.ReplaceNode
  • 步骤1和2可以,但第3步不起作用。如果我删除步骤2,则步骤3正在工作

    我不知道这是因为我混合了Roslyn和DTE,还是因为第2步在解决方案中生成新代码,而缓存的上下文变得无效

    // Add the resource to the Resources.resx file
    var xmlDoc = new XmlDocument();
    xmlDoc.Load(resxPath);
    XmlNode node = xmlDoc.SelectSingleNode($"//data[@name='{resourceIndentifierName}']");
    if (node != null) return;
    XmlElement dataElement = xmlDoc.CreateElement("data");
    
    XmlAttribute nameAtt = xmlDoc.CreateAttribute("name");
    nameAtt.Value = resourceIndentifierName;
    dataElement.Attributes.Append(nameAtt);
    
    XmlAttribute spaceAtt = xmlDoc.CreateAttribute("space", "xml");
    spaceAtt.Value = "preserve";
    dataElement.Attributes.Append(spaceAtt);
    
    XmlElement valueElement = xmlDoc.CreateElement("value");
    valueElement.InnerText = value;
    dataElement.AppendChild(valueElement);
    
    XmlNode rootNode = xmlDoc.SelectSingleNode("//root");
    Debug.Assert(rootNode != null, "rootNode != null");
    rootNode.AppendChild(dataElement);
    xmlDoc.Save(resxPath);
    
    // Update the Resources.Designer.cs file
    var dte = (DTE2)Package.GetGlobalService(typeof(SDTE));
    ProjectItem item = dte.Solution.FindProjectItem(resxPath);
    ((VSProjectItem) item.Object)?.RunCustomTool();
    
    // Replace the node
    SyntaxNode oldRoot = await context.Document.GetSyntaxRootAsync(cancellationToken)
      .ConfigureAwait(false);
    SyntaxNode newRoot = oldRoot.ReplaceNode(oldNode, newNode);
    return context.Document.WithSyntaxRoot(newRoot);
    
    这是因为第2步在解决方案中生成新代码,而我的缓存上下文变得无效


    这就是正在发生的事情。调用
    RunCustomTool
    时,visual studio file watcher api会告诉roslyn文件已更新,roslyn会生成一组新的解决方案快照。当您尝试应用代码修复时,roslyn会查看代码修复来自的解决方案快照,发现它与当前快照不匹配,并且无法应用它

    什么是
    newNode
    newNode
    QualifiedName
    :Properties.Resources.myresource到底发生了什么?但你不能这样做;代码操作必须是纯函数。例如,悬停预览怎么样?我已经暂时禁用了预览()在第一次运行时,资源被添加到.resx文件中,但代码中没有任何更改。在第二次运行时,资源存在,因此.resx保持不变,代码被更改。我已经实现了
    GetChangedSolutionAsync
    ,而不是
    GetChangedDocumentAsync
    ,现在我正在用Roslyn更新.Designer.cs,而不是用
    RunCustomTool
    。而且它工作得很好。非常感谢。最后它不起作用了,因为我的重构和ResXFileCodeGenerator之间存在冲突。每次修改.resx时,ResXFileCodeGenerator都会更新.Designer.cs,我的快照将无效。如果禁用ResXFileCodeGenerator,.Designer.cs将从解决方案中消失。我要把它变成一个标准的VS命令。