Unity 代码调用重新生成csproj文件
结论
先放结论:editor代码中直接调用
Unity.CodeEditor.CodeEditor.CurrentEditor.SyncAll();
原因
在一些操作后,比如修改csc.rsp
的内容之后,需要重新生成csproj文件
方法是 Edit -> Preferences -> External Tools -> Regenerate project files
但是多按几次就比较烦了,想通过代码调用生成csproj文件
但是网上直接搜又找不到,可能因为关键词不对
首先查看unity官方开源的编辑器代码
找到了这段
private void RegenerateProjectFiles()
{
var rect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect(new GUILayoutOption[] {}));
rect.width = 252;
if (GUI.Button(rect, "Regenerate project files"))
{
SyncVS.Synchronizer.Sync();
}
}
和按钮上的文字一模一样,应该就是这个了。
但是UnityEditor.SyncVS
这个类访问权限是internal,直接访问不了,又不想再用反射一层层调
VS里面跳转到UnityEditor.SyncVS
这个类的定义,可以看到程序集是UnityEditor.CoreModule
, 也就是UnityEditor.dll
这个文件
使用ILSpy导入这个dll,可以看到一堆诸如
[assembly: InternalsVisibleTo("Unity.InternalAPIEditorBridge.001")]
这样的内容。
Unity不想把所有方法都直接开放出来(所有人随便就能调用也容易出bug),又要给其他程序集使用,就预定义了一堆这种东西
只要一个程序集的名字在这里出现就可以调用UnityEditor.CoreModule的internal访问权限。
挑一个没被占用的(可能会被安装的Packages包占用),就“Unity.InternalAPIEditorBridge.001”了
新建文件夹"Assets/Editor/Unity.InternalAPIEditorBridge.001"
新建asmdef文件"Assets/Editor/Unity.InternalAPIEditorBridge.001/Unity.InternalAPIEditorBridge.001.asmdef"
新建一个C#代码文件"Assets/Editor/Unity.InternalAPIEditorBridge.001/UnityEditorExterns.cs"
namespace UnityEditor
{
public static class UnityEditorExterns
{
public static void RegenerateCSharpProjectFiles()
{
UnityEditor.SyncVS.Synchronizer.Sync();
}
}
}
然后在正常的Editor代码文件里面调用即可
然后问题来了,生成文件之后,发现VS里面的引用不太对,甚至刚才写的UnityEditorExterns.RegenerateCSharpProjectFiles()
都找不到引用了
对比手动去Preferences窗口点击之后生成的文件,也是有差距的。
难道被什么覆盖了?全局搜索“Regenerate project files”,在“com.unity.ide.visualstudio@2.0.14/Editor/VisualStudioEditor.cs”里面找到下面的内容
private void RegenerateProjectFiles()
{
var rect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect(new GUILayoutOption[] {}));
rect.width = 252;
if (GUI.Button(rect, "Regenerate project files"))
{
_generator.Sync();
}
}
搜索“_generator.Sync()” 又找到了下面的内容
public void SyncAll()
{
AssetDatabase.Refresh();
_generator.Sync();
}
看来如果能调用到这个SyncAll()
, 应该就可以了
继续追踪后,发现这个方法是实现Unity.CodeEditor.IExternalCodeEditor
的接口方法,而IExternalCodeEditor
这个接口实例可以通过Unity.CodeEditor.CodeEditor.CurrentEditor
取到, 这一路都是public的,甚至不需要“InternalAPIEditorBridge”
直接调用
Unity.CodeEditor.CodeEditor.CurrentEditor.SyncAll();
执行后发现生成了正确的csproj文件