com.unity.ide.visualstudio@2.0.11

## [2.0.11] - 2021-07-01

Integration:

- Added support for Visual Studio and Visual Studio For Mac 2022.
- Fixed an issue when the package was enabled for background processes.

Project generation:

- Use absolute paths for Analyzers and rulesets.

## [2.0.10] - 2021-06-10

Project generation:

- Improved project generation performance when a file is moved, deleted or modified.

Integration:

- Improved Inner-loop performance by avoiding to call the package manager when looking up `vswhere` utility.
- Fixed a network issue preventing the communication between Visual Studio and Unity on Windows.
This commit is contained in:
Unity Technologies
2021-07-01 00:00:00 +00:00
parent b0f2251c48
commit f6444c620d
22 changed files with 428 additions and 274 deletions

View File

@@ -1,17 +1,39 @@
# Code Editor Package for Visual Studio # Code Editor Package for Visual Studio
## [2.0.11] - 2021-07-01
Integration:
- Added support for Visual Studio and Visual Studio For Mac 2022.
- Fixed an issue when the package was enabled for background processes.
Project generation:
- Use absolute paths for Analyzers and rulesets.
## [2.0.10] - 2021-06-10
Project generation:
- Improved project generation performance when a file is moved, deleted or modified.
Integration:
- Improved Inner-loop performance by avoiding to call the package manager when looking up `vswhere` utility.
- Fixed a network issue preventing the communication between Visual Studio and Unity on Windows.
## [2.0.9] - 2021-05-04 ## [2.0.9] - 2021-05-04
Project generation: Project generation:
Added support for CLI. - Added support for CLI.
Integration: Integration:
Improved performance when discovering Visual Studio installations. - Improved performance when discovering Visual Studio installations.
Warn when legacy assemblies are present in the project. - Warn when legacy assemblies are present in the project.
Warn when the package version is not up-to-date. - Warn when the package version is not up-to-date.
## [2.0.8] - 2021-04-09 ## [2.0.8] - 2021-04-09

View File

@@ -118,12 +118,7 @@ static BOOL ApplicationSupportsQueryOpenedSolution(NSString* appPath)
return NO; return NO;
NSString* version = (NSString*)versionValue; NSString* version = (NSString*)versionValue;
NSArray* components = [version componentsSeparatedByString:@"."]; return [version compare:@"8.6" options:NSNumericSearch] != NSOrderedAscending;
if (!components || components.count < 2)
return NO;
return [components[0] integerValue] >= 8
&& [components[1] integerValue] >= 6;
} }
static NSArray<NSRunningApplication*>* QueryRunningInstances(NSString *appPath) static NSArray<NSRunningApplication*>* QueryRunningInstances(NSString *appPath)

View File

@@ -21,9 +21,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
public static void FindVSWhere() public static void FindVSWhere()
{ {
_vsWherePath = FileUtility _vsWherePath = FileUtility.GetPackageAssetFullPath("Editor", "VSWhere", "vswhere.exe");
.FindPackageAssetFullPath("VSWhere a:packages", "vswhere.exe")
.FirstOrDefault();
} }
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations() public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
@@ -71,7 +69,12 @@ namespace Microsoft.Unity.VisualStudio.Editor
// On Mac we use the .app folder, so we need to access to main assembly // On Mac we use the .app folder, so we need to access to main assembly
if (VisualStudioEditor.IsOSX) if (VisualStudioEditor.IsOSX)
fvi = Path.Combine(editorPath, "Contents", "Resources", "lib", "monodevelop", "bin", "VisualStudio.exe"); {
fvi = Path.Combine(editorPath, "Contents/Resources/lib/monodevelop/bin/VisualStudio.exe");
if (!File.Exists(fvi))
fvi = Path.Combine(editorPath, "Contents/MonoBundle/VisualStudio.exe");
}
if (!File.Exists(fvi)) if (!File.Exists(fvi))
return false; return false;

View File

@@ -5,8 +5,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine; using UnityEngine;
namespace Microsoft.Unity.VisualStudio.Editor namespace Microsoft.Unity.VisualStudio.Editor
@@ -16,27 +14,19 @@ namespace Microsoft.Unity.VisualStudio.Editor
public const char WinSeparator = '\\'; public const char WinSeparator = '\\';
public const char UnixSeparator = '/'; public const char UnixSeparator = '/';
// Safe for packages as we use packageInfo.resolvedPath, so this should work in library package cache as well public static string GetPackageAssetFullPath(params string[] components)
public static string[] FindPackageAssetFullPath(string assetfilter, string filefilter)
{ {
return AssetDatabase.FindAssets(assetfilter) // Unity has special IO handling of Packages and will resolve those path to the right package location
.Select(AssetDatabase.GUIDToAssetPath) return Path.GetFullPath(Path.Combine("Packages", "com.unity.ide.visualstudio", Path.Combine(components)));
.Where(assetPath => assetPath.Contains(filefilter))
.Select(asset =>
{
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(asset);
return Normalize(packageInfo.resolvedPath + asset.Substring(packageInfo.assetPath.Length));
})
.ToArray();
} }
public static string GetAssetFullPath(string asset) public static string GetAssetFullPath(string asset)
{ {
var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, "..")); var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
return Path.GetFullPath(Path.Combine(basePath, Normalize(asset))); return Path.GetFullPath(Path.Combine(basePath, NormalizePathSeparators(asset)));
} }
public static string Normalize(string path) public static string NormalizePathSeparators(this string path)
{ {
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
return path; return path;
@@ -66,11 +56,17 @@ namespace Microsoft.Unity.VisualStudio.Editor
return relative == Path.GetFileName(relative); return relative == Path.GetFileName(relative);
} }
public static string MakeAbsolutePath(this string path, string projectDirectory)
{
if (string.IsNullOrEmpty(path)) { return string.Empty; }
return Path.IsPathRooted(path) ? path : Path.Combine(projectDirectory, path);
}
// returns null if outside of the project scope // returns null if outside of the project scope
internal static string MakeRelativeToProjectPath(string fileName) internal static string MakeRelativeToProjectPath(string fileName)
{ {
var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, "..")); var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
fileName = Normalize(fileName); fileName = NormalizePathSeparators(fileName);
if (!Path.IsPathRooted(fileName)) if (!Path.IsPathRooted(fileName))
fileName = Path.Combine(basePath, fileName); fileName = Path.Combine(basePath, fileName);
@@ -82,6 +78,5 @@ namespace Microsoft.Unity.VisualStudio.Editor
.Substring(basePath.Length) .Substring(basePath.Length)
.Trim(Path.DirectorySeparatorChar); .Trim(Path.DirectorySeparatorChar);
} }
} }
} }

View File

@@ -17,11 +17,31 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
private readonly object _disposeLock = new object(); private readonly object _disposeLock = new object();
private bool _disposed; private bool _disposed;
#if UNITY_EDITOR_WIN
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetHandleInformation(IntPtr hObject, HandleFlags dwMask, HandleFlags dwFlags);
[Flags]
private enum HandleFlags: uint
{
None = 0,
Inherit = 1,
ProtectFromClose = 2
}
#endif
protected Messager(int port) protected Messager(int port)
{ {
_socket = new UdpSocket(); _socket = new UdpSocket();
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false);
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
#if UNITY_EDITOR_WIN
// Explicitely disable inheritance for our UDP socket handle
// We found that Unity is creating a fork when importing new assets that can clone our socket
SetHandleInformation(_socket.Handle, HandleFlags.Inherit, HandleFlags.None);
#endif
_socket.Bind(IPAddress.Any, port); _socket.Bind(IPAddress.Any, port);
BeginReceiveMessage(); BeginReceiveMessage();
@@ -72,9 +92,7 @@ namespace Microsoft.Unity.VisualStudio.Editor.Messaging
{ {
message.Origin = (IPEndPoint)endPoint; message.Origin = (IPEndPoint)endPoint;
int port; if (IsValidTcpMessage(message, out var port, out var bufferSize))
int bufferSize;
if (IsValidTcpMessage(message, out port, out bufferSize))
{ {
// switch to TCP mode to handle big messages // switch to TCP mode to handle big messages
TcpClient.Queue(message.Origin.Address, port, bufferSize, buffer => TcpClient.Queue(message.Origin.Address, port, bufferSize, buffer =>

View File

@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>19H1030</string> <string>19H1217</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>

View File

@@ -13,9 +13,9 @@ using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Unity.CodeEditor; using Unity.CodeEditor;
using Unity.Profiling;
using UnityEditor; using UnityEditor;
using UnityEditor.Compilation; using UnityEditor.Compilation;
using UnityEditorInternal;
using UnityEngine; using UnityEngine;
namespace Microsoft.Unity.VisualStudio.Editor namespace Microsoft.Unity.VisualStudio.Editor
@@ -45,9 +45,9 @@ namespace Microsoft.Unity.VisualStudio.Editor
const string k_WindowsNewline = "\r\n"; const string k_WindowsNewline = "\r\n";
string m_SolutionProjectEntryTemplate = @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""{4}EndProject"; const string m_SolutionProjectEntryTemplate = @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""{4}EndProject";
string m_SolutionProjectConfigurationTemplate = string.Join("\r\n", readonly string m_SolutionProjectConfigurationTemplate = string.Join(k_WindowsNewline,
@" {{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", @" {{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU",
@" {{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU", @" {{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU",
@" {{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU", @" {{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU",
@@ -55,10 +55,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
static readonly string[] k_ReimportSyncExtensions = { ".dll", ".asmdef" }; static readonly string[] k_ReimportSyncExtensions = { ".dll", ".asmdef" };
static readonly Regex k_ScriptReferenceExpression = new Regex(
@"^Library.ScriptAssemblies.(?<dllname>(?<project>.*)\.dll$)",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
string[] m_ProjectSupportedExtensions = Array.Empty<string>(); string[] m_ProjectSupportedExtensions = Array.Empty<string>();
string[] m_BuiltinSupportedExtensions = Array.Empty<string>(); string[] m_BuiltinSupportedExtensions = Array.Empty<string>();
@@ -101,16 +97,51 @@ namespace Microsoft.Unity.VisualStudio.Editor
/// A set of files that got reimported /// A set of files that got reimported
/// </param> /// </param>
public bool SyncIfNeeded(IEnumerable<string> affectedFiles, IEnumerable<string> reimportedFiles) public bool SyncIfNeeded(IEnumerable<string> affectedFiles, IEnumerable<string> reimportedFiles)
{
using (solutionSyncMarker.Auto())
{ {
SetupProjectSupportedExtensions(); SetupProjectSupportedExtensions();
// See https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/
// We create a .vsconfig file to make sure our ManagedGame workload is installed
CreateVsConfigIfNotFound();
// Don't sync if we haven't synced before // Don't sync if we haven't synced before
if (HasSolutionBeenGenerated() && HasFilesBeenModified(affectedFiles, reimportedFiles)) var affected = affectedFiles as ICollection<string> ?? affectedFiles.ToArray();
var reimported = reimportedFiles as ICollection<string> ?? reimportedFiles.ToArray();
if (!HasFilesBeenModified(affected, reimported))
{ {
Sync(); return false;
}
var assemblies = m_AssemblyNameProvider.GetAssemblies(ShouldFileBePartOfSolution);
var allProjectAssemblies = RelevantAssembliesForMode(assemblies).ToList();
SyncSolution(allProjectAssemblies);
var allAssetProjectParts = GenerateAllAssetProjectParts();
var affectedNames = affected
.Select(asset => m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset))
.Where(name => !string.IsNullOrWhiteSpace(name)).Select(name =>
name.Split(new[] {".dll"}, StringSplitOptions.RemoveEmptyEntries)[0]);
var reimportedNames = reimported
.Select(asset => m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset))
.Where(name => !string.IsNullOrWhiteSpace(name)).Select(name =>
name.Split(new[] {".dll"}, StringSplitOptions.RemoveEmptyEntries)[0]);
var affectedAndReimported = new HashSet<string>(affectedNames.Concat(reimportedNames));
foreach (var assembly in allProjectAssemblies)
{
if (!affectedAndReimported.Contains(assembly.name))
continue;
SyncProject(assembly,
allAssetProjectParts,
responseFilesData: ParseResponseFileData(assembly).ToArray());
}
return true; return true;
} }
return false;
} }
private void CreateVsConfigIfNotFound() private void CreateVsConfigIfNotFound()
@@ -151,6 +182,8 @@ namespace Microsoft.Unity.VisualStudio.Editor
editor?.TryGetVisualStudioInstallationForPath(CodeEditor.CurrentEditorInstallation, searchInstallations: true, out m_CurrentInstallation); editor?.TryGetVisualStudioInstallationForPath(CodeEditor.CurrentEditorInstallation, searchInstallations: true, out m_CurrentInstallation);
} }
static ProfilerMarker solutionSyncMarker = new ProfilerMarker("SolutionSynchronizerSync");
public void Sync() public void Sync()
{ {
// We need the exact VS version/capabilities to tweak project generation (analyzers/langversion) // We need the exact VS version/capabilities to tweak project generation (analyzers/langversion)
@@ -170,6 +203,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
{ {
GenerateAndWriteSolutionAndProjects(); GenerateAndWriteSolutionAndProjects();
} }
OnGeneratedCSProjectFiles(); OnGeneratedCSProjectFiles();
} }
@@ -246,27 +280,19 @@ namespace Microsoft.Unity.VisualStudio.Editor
{ {
// Only synchronize assemblies that have associated source files and ones that we actually want in the project. // Only synchronize assemblies that have associated source files and ones that we actually want in the project.
// This also filters out DLLs coming from .asmdef files in packages. // This also filters out DLLs coming from .asmdef files in packages.
var assemblies = m_AssemblyNameProvider.GetAssemblies(ShouldFileBePartOfSolution); var assemblies = m_AssemblyNameProvider.GetAssemblies(ShouldFileBePartOfSolution).ToList();
var allAssetProjectParts = GenerateAllAssetProjectParts(); var allAssetProjectParts = GenerateAllAssetProjectParts();
var assemblyList = assemblies.ToList(); SyncSolution(assemblies);
SyncSolution(assemblyList); var allProjectAssemblies = RelevantAssembliesForMode(assemblies);
var allProjectAssemblies = RelevantAssembliesForMode(assemblyList).ToList(); foreach (var assembly in allProjectAssemblies)
foreach (Assembly assembly in allProjectAssemblies)
{ {
SyncProject(assembly, SyncProject(assembly,
allAssetProjectParts, allAssetProjectParts,
responseFilesData: ParseResponseFileData(assembly), responseFilesData: ParseResponseFileData(assembly).ToArray());
allProjectAssemblies,
#if UNITY_2020_2_OR_NEWER
assembly.compilerOptions.RoslynAnalyzerDllPaths);
#else
Array.Empty<string>());
#endif
} }
} }
@@ -310,7 +336,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
if (IsSupportedFile(asset) && ScriptingLanguage.None == ScriptingLanguageFor(asset)) if (IsSupportedFile(asset) && ScriptingLanguage.None == ScriptingLanguageFor(asset))
{ {
// Find assembly the asset belongs to by adding script extension and using compilation pipeline. // Find assembly the asset belongs to by adding script extension and using compilation pipeline.
var assemblyName = m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset + ".cs"); var assemblyName = m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset);
if (string.IsNullOrEmpty(assemblyName)) if (string.IsNullOrEmpty(assemblyName))
{ {
@@ -340,13 +366,11 @@ namespace Microsoft.Unity.VisualStudio.Editor
private void SyncProject( private void SyncProject(
Assembly assembly, Assembly assembly,
Dictionary<string, string> allAssetsProjectParts, Dictionary<string, string> allAssetsProjectParts,
IEnumerable<ResponseFileData> responseFilesData, ResponseFileData[] responseFilesData)
List<Assembly> allProjectAssemblies,
string[] roslynAnalyzerDllPaths)
{ {
SyncProjectFileIfNotChanged( SyncProjectFileIfNotChanged(
ProjectFile(assembly), ProjectFile(assembly),
ProjectText(assembly, allAssetsProjectParts, responseFilesData, allProjectAssemblies, roslynAnalyzerDllPaths)); ProjectText(assembly, allAssetsProjectParts, responseFilesData));
} }
private void SyncProjectFileIfNotChanged(string path, string newContents) private void SyncProjectFileIfNotChanged(string path, string newContents)
@@ -444,11 +468,9 @@ namespace Microsoft.Unity.VisualStudio.Editor
private string ProjectText(Assembly assembly, private string ProjectText(Assembly assembly,
Dictionary<string, string> allAssetsProjectParts, Dictionary<string, string> allAssetsProjectParts,
IEnumerable<ResponseFileData> responseFilesData, ResponseFileData[] responseFilesData)
List<Assembly> allProjectAssemblies,
string[] roslynAnalyzerDllPaths)
{ {
var projectBuilder = new StringBuilder(ProjectHeader(assembly, responseFilesData, roslynAnalyzerDllPaths)); var projectBuilder = new StringBuilder(ProjectHeader(assembly, responseFilesData));
var references = new List<string>(); var references = new List<string>();
projectBuilder.Append(@" <ItemGroup>").Append(k_WindowsNewline); projectBuilder.Append(@" <ItemGroup>").Append(k_WindowsNewline);
@@ -503,7 +525,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
if (0 < assembly.assemblyReferences.Length) if (0 < assembly.assemblyReferences.Length)
{ {
projectBuilder.Append(" <ItemGroup>").Append(k_WindowsNewline); projectBuilder.Append(" <ItemGroup>").Append(k_WindowsNewline);
foreach (Assembly reference in assembly.assemblyReferences.Where(i => i.sourceFiles.Any(ShouldFileBePartOfSolution))) foreach (var reference in assembly.assemblyReferences.Where(i => i.sourceFiles.Any(ShouldFileBePartOfSolution)))
{ {
projectBuilder.Append(" <ProjectReference Include=\"").Append(reference.name).Append(GetProjectExtension()).Append("\">").Append(k_WindowsNewline); projectBuilder.Append(" <ProjectReference Include=\"").Append(reference.name).Append(GetProjectExtension()).Append("\">").Append(k_WindowsNewline);
projectBuilder.Append(" <Project>{").Append(ProjectGuid(reference)).Append("}</Project>").Append(k_WindowsNewline); projectBuilder.Append(" <Project>{").Append(ProjectGuid(reference)).Append("}</Project>").Append(k_WindowsNewline);
@@ -514,7 +536,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
projectBuilder.Append(@" </ItemGroup>").Append(k_WindowsNewline); projectBuilder.Append(@" </ItemGroup>").Append(k_WindowsNewline);
} }
projectBuilder.Append(ProjectFooter()); projectBuilder.Append(GetProjectFooter());
return projectBuilder.ToString(); return projectBuilder.ToString();
} }
@@ -548,29 +570,20 @@ namespace Microsoft.Unity.VisualStudio.Editor
} }
private static readonly Regex InvalidCharactersRegexPattern = new Regex(@"\?|&|\*|""|<|>|\||#|%|\^|;" + (VisualStudioEditor.IsWindows ? "" : "|:")); private static readonly Regex InvalidCharactersRegexPattern = new Regex(@"\?|&|\*|""|<|>|\||#|%|\^|;" + (VisualStudioEditor.IsWindows ? "" : "|:"));
public string SolutionFile() public string SolutionFile()
{ {
return Path.Combine(FileUtility.Normalize(ProjectDirectory), $"{InvalidCharactersRegexPattern.Replace(m_ProjectName, "_")}.sln"); return Path.Combine(ProjectDirectory.NormalizePathSeparators(), $"{InvalidCharactersRegexPattern.Replace(m_ProjectName, "_")}.sln");
} }
internal string VsConfigFile() internal string VsConfigFile()
{ {
return Path.Combine(FileUtility.Normalize(ProjectDirectory), ".vsconfig"); return Path.Combine(ProjectDirectory.NormalizePathSeparators(), ".vsconfig");
} }
private string ProjectHeader( internal string GetLangVersion(Assembly assembly)
Assembly assembly,
IEnumerable<ResponseFileData> responseFilesData,
string[] roslynAnalyzerDllPaths
)
{ {
var toolsVersion = "4.0";
var productVersion = "10.0.20506";
const string baseDirectory = ".";
var targetFrameworkVersion = "v4.7.1";
var targetLanguageVersion = "latest"; // danger: latest is not the same absolute value depending on the VS version. var targetLanguageVersion = "latest"; // danger: latest is not the same absolute value depending on the VS version.
if (m_CurrentInstallation != null) if (m_CurrentInstallation != null)
{ {
var vsLanguageSupport = m_CurrentInstallation.LatestLanguageVersionSupported; var vsLanguageSupport = m_CurrentInstallation.LatestLanguageVersionSupported;
@@ -580,43 +593,48 @@ namespace Microsoft.Unity.VisualStudio.Editor
targetLanguageVersion = (vsLanguageSupport <= unityLanguageSupport ? vsLanguageSupport : unityLanguageSupport).ToString(2); // (major, minor) only targetLanguageVersion = (vsLanguageSupport <= unityLanguageSupport ? vsLanguageSupport : unityLanguageSupport).ToString(2); // (major, minor) only
} }
return targetLanguageVersion;
}
private string ProjectHeader(
Assembly assembly,
ResponseFileData[] responseFilesData
)
{
var projectType = ProjectTypeOf(assembly.name); var projectType = ProjectTypeOf(assembly.name);
string rulesetPath = null;
var analyzers = Array.Empty<string>();
var arguments = new object[] if (m_CurrentInstallation != null && m_CurrentInstallation.SupportsAnalyzers)
{
toolsVersion,
productVersion,
ProjectGuid(assembly),
XmlFilename(FileUtility.Normalize(InternalEditorUtility.GetEngineAssemblyPath())),
XmlFilename(FileUtility.Normalize(InternalEditorUtility.GetEditorAssemblyPath())),
string.Join(";", assembly.defines.Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray()),
MSBuildNamespaceUri,
assembly.name,
assembly.outputPath,
GetRootNamespace(assembly),
targetFrameworkVersion,
targetLanguageVersion,
baseDirectory,
assembly.compilerOptions.AllowUnsafeCode | responseFilesData.Any(x => x.Unsafe),
// flavoring
projectType + ":" + (int)projectType,
EditorUserBuildSettings.activeBuildTarget + ":" + (int)EditorUserBuildSettings.activeBuildTarget,
Application.unityVersion,
VisualStudioIntegration.PackageVersion()
};
try
{ {
analyzers = m_CurrentInstallation.GetAnalyzers();
#if UNITY_2020_2_OR_NEWER #if UNITY_2020_2_OR_NEWER
return string.Format(GetProjectHeaderTemplate(roslynAnalyzerDllPaths, assembly.compilerOptions.RoslynAnalyzerRulesetPath), arguments); analyzers = analyzers != null ? analyzers.Concat(assembly.compilerOptions.RoslynAnalyzerDllPaths).ToArray() : assembly.compilerOptions.RoslynAnalyzerDllPaths;
#else rulesetPath = assembly.compilerOptions.RoslynAnalyzerRulesetPath;
return string.Format(GetProjectHeaderTemplate(Array.Empty<string>(), null), arguments);
#endif #endif
} }
catch (Exception)
var projectProperties = new ProjectProperties()
{ {
throw new NotSupportedException("Failed creating c# project because the c# project header did not have the correct amount of arguments, which is " + arguments.Length); ProjectGuid = ProjectGuid(assembly),
} LangVersion = GetLangVersion(assembly),
AssemblyName = assembly.name,
RootNamespace = GetRootNamespace(assembly),
OutputPath = assembly.outputPath,
// Analyzers
Analyzers = analyzers,
RulesetPath = rulesetPath,
// RSP alterable
Defines = assembly.defines.Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray(),
Unsafe = assembly.compilerOptions.AllowUnsafeCode | responseFilesData.Any(x => x.Unsafe),
// VSTU Flavoring
FlavoringProjectType = projectType + ":" + (int)projectType,
FlavoringBuildTarget = EditorUserBuildSettings.activeBuildTarget + ":" + (int)EditorUserBuildSettings.activeBuildTarget,
FlavoringUnityVersion = Application.unityVersion,
FlavoringPackageVersion = VisualStudioIntegration.PackageVersion(),
};
return GetProjectHeader(projectProperties);
} }
private enum ProjectType private enum ProjectType
@@ -642,9 +660,123 @@ namespace Microsoft.Unity.VisualStudio.Editor
return ProjectType.Game; return ProjectType.Game;
} }
private string GetProjectHeader(ProjectProperties properties)
{
var header = new[]
{
$@"<?xml version=""1.0"" encoding=""utf-8""?>",
$@"<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">",
$@" <PropertyGroup>",
$@" <LangVersion>{properties.LangVersion}</LangVersion>",
$@" </PropertyGroup>",
$@" <PropertyGroup>",
$@" <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>",
$@" <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>",
$@" <ProductVersion>10.0.20506</ProductVersion>",
$@" <SchemaVersion>2.0</SchemaVersion>",
$@" <RootNamespace>{properties.RootNamespace}</RootNamespace>",
$@" <ProjectGuid>{{{properties.ProjectGuid}}}</ProjectGuid>",
$@" <OutputType>Library</OutputType>",
$@" <AppDesignerFolder>Properties</AppDesignerFolder>",
$@" <AssemblyName>{properties.AssemblyName}</AssemblyName>",
$@" <TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>",
$@" <FileAlignment>512</FileAlignment>",
$@" <BaseDirectory>.</BaseDirectory>",
$@" </PropertyGroup>",
$@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "">",
$@" <DebugSymbols>true</DebugSymbols>",
$@" <DebugType>full</DebugType>",
$@" <Optimize>false</Optimize>",
$@" <OutputPath>{properties.OutputPath}</OutputPath>",
$@" <DefineConstants>{string.Join(";", properties.Defines)}</DefineConstants>",
$@" <ErrorReport>prompt</ErrorReport>",
$@" <WarningLevel>4</WarningLevel>",
$@" <NoWarn>0169</NoWarn>",
$@" <AllowUnsafeBlocks>{properties.Unsafe}</AllowUnsafeBlocks>",
$@" </PropertyGroup>",
$@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "">",
$@" <DebugType>pdbonly</DebugType>",
$@" <Optimize>true</Optimize>",
$@" <OutputPath>Temp\bin\Release\</OutputPath>",
$@" <ErrorReport>prompt</ErrorReport>",
$@" <WarningLevel>4</WarningLevel>",
$@" <NoWarn>0169</NoWarn>",
$@" <AllowUnsafeBlocks>{properties.Unsafe}</AllowUnsafeBlocks>",
$@" </PropertyGroup>"
};
var forceExplicitReferences = new[]
{
$@" <PropertyGroup>",
$@" <NoConfig>true</NoConfig>",
$@" <NoStdLib>true</NoStdLib>",
$@" <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>",
$@" <ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>",
$@" <ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>",
$@" </PropertyGroup>"
};
var flavoring = new[]
{
$@" <PropertyGroup>",
$@" <ProjectTypeGuids>{{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1}};{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}</ProjectTypeGuids>",
$@" <UnityProjectGenerator>Package</UnityProjectGenerator>",
$@" <UnityProjectGeneratorVersion>{properties.FlavoringPackageVersion}</UnityProjectGeneratorVersion>",
$@" <UnityProjectType>{properties.FlavoringProjectType}</UnityProjectType>",
$@" <UnityBuildTarget>{properties.FlavoringBuildTarget}</UnityBuildTarget>",
$@" <UnityVersion>{properties.FlavoringUnityVersion}</UnityVersion>",
$@" </PropertyGroup>"
};
var footer = new[]
{
@""
};
var lines = header
.Concat(forceExplicitReferences)
.Concat(flavoring)
.ToList();
if (!string.IsNullOrEmpty(properties.RulesetPath))
{
lines.Add(@" <PropertyGroup>");
lines.Add($" <CodeAnalysisRuleSet>{properties.RulesetPath.MakeAbsolutePath(ProjectDirectory).NormalizePathSeparators()}</CodeAnalysisRuleSet>");
lines.Add(@" </PropertyGroup>");
}
if (properties.Analyzers.Any())
{
lines.Add(@" <ItemGroup>");
foreach (var analyzer in properties.Analyzers)
{
lines.Add($@" <Analyzer Include=""{analyzer.MakeAbsolutePath(ProjectDirectory).NormalizePathSeparators()}"" />");
}
lines.Add(@" </ItemGroup>");
}
return string.Join(k_WindowsNewline, lines.Concat(footer));
}
private static string GetProjectFooter()
{
return string.Join(k_WindowsNewline,
@" <Import Project=""$(MSBuildToolsPath)\Microsoft.CSharp.targets"" />",
@" <Target Name=""GenerateTargetFrameworkMonikerAttribute"" />",
@" <!-- To modify your build process, add your task inside one of the targets below and uncomment it.",
@" Other similar extension points exist, see Microsoft.Common.targets.",
@" <Target Name=""BeforeBuild"">",
@" </Target>",
@" <Target Name=""AfterBuild"">",
@" </Target>",
@" -->",
@"</Project>",
@"");
}
private static string GetSolutionText() private static string GetSolutionText()
{ {
return string.Join("\r\n", return string.Join(k_WindowsNewline,
@"", @"",
@"Microsoft Visual Studio Solution File, Format Version {0}", @"Microsoft Visual Studio Solution File, Format Version {0}",
@"# Visual Studio {1}", @"# Visual Studio {1}",
@@ -662,126 +794,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
@"").Replace(" ", "\t"); @"").Replace(" ", "\t");
} }
private static string GetProjectFooterTemplate()
{
return string.Join("\r\n",
@" <Import Project=""$(MSBuildToolsPath)\Microsoft.CSharp.targets"" />",
@" <Target Name=""GenerateTargetFrameworkMonikerAttribute"" />",
@" <!-- To modify your build process, add your task inside one of the targets below and uncomment it.",
@" Other similar extension points exist, see Microsoft.Common.targets.",
@" <Target Name=""BeforeBuild"">",
@" </Target>",
@" <Target Name=""AfterBuild"">",
@" </Target>",
@" -->",
@"</Project>",
@"");
}
private string GetProjectHeaderTemplate(string[] roslynAnalyzerDllPaths, string roslynAnalyzerRulesetPath)
{
var header = new[]
{
@"<?xml version=""1.0"" encoding=""utf-8""?>",
@"<Project ToolsVersion=""{0}"" DefaultTargets=""Build"" xmlns=""{6}"">",
@" <PropertyGroup>",
@" <LangVersion>{11}</LangVersion>",
@" </PropertyGroup>",
@" <PropertyGroup>",
@" <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>",
@" <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>",
@" <ProductVersion>{1}</ProductVersion>",
@" <SchemaVersion>2.0</SchemaVersion>",
@" <RootNamespace>{9}</RootNamespace>",
@" <ProjectGuid>{{{2}}}</ProjectGuid>",
@" <OutputType>Library</OutputType>",
@" <AppDesignerFolder>Properties</AppDesignerFolder>",
@" <AssemblyName>{7}</AssemblyName>",
@" <TargetFrameworkVersion>{10}</TargetFrameworkVersion>",
@" <FileAlignment>512</FileAlignment>",
@" <BaseDirectory>{12}</BaseDirectory>",
@" </PropertyGroup>",
@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "">",
@" <DebugSymbols>true</DebugSymbols>",
@" <DebugType>full</DebugType>",
@" <Optimize>false</Optimize>",
@" <OutputPath>{8}</OutputPath>",
@" <DefineConstants>{5}</DefineConstants>",
@" <ErrorReport>prompt</ErrorReport>",
@" <WarningLevel>4</WarningLevel>",
@" <NoWarn>0169</NoWarn>",
@" <AllowUnsafeBlocks>{13}</AllowUnsafeBlocks>",
@" </PropertyGroup>",
@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "">",
@" <DebugType>pdbonly</DebugType>",
@" <Optimize>true</Optimize>",
@" <OutputPath>Temp\bin\Release\</OutputPath>",
@" <ErrorReport>prompt</ErrorReport>",
@" <WarningLevel>4</WarningLevel>",
@" <NoWarn>0169</NoWarn>",
@" <AllowUnsafeBlocks>{13}</AllowUnsafeBlocks>",
@" </PropertyGroup>"
};
var forceExplicitReferences = new[]
{
@" <PropertyGroup>",
@" <NoConfig>true</NoConfig>",
@" <NoStdLib>true</NoStdLib>",
@" <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>",
@" <ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>",
@" <ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>",
@" </PropertyGroup>"
};
var flavoring = new[]
{
@" <PropertyGroup>",
@" <ProjectTypeGuids>{{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1}};{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}</ProjectTypeGuids>",
@" <UnityProjectGenerator>Package</UnityProjectGenerator>",
@" <UnityProjectGeneratorVersion>{17}</UnityProjectGeneratorVersion>",
@" <UnityProjectType>{14}</UnityProjectType>",
@" <UnityBuildTarget>{15}</UnityBuildTarget>",
@" <UnityVersion>{16}</UnityVersion>",
@" </PropertyGroup>"
};
var footer = new[]
{
@""
};
var lines = header.Concat(forceExplicitReferences).Concat(flavoring).ToList();
// Only add analyzer block for compatible Visual Studio
if (m_CurrentInstallation != null && m_CurrentInstallation.SupportsAnalyzers)
{
#if UNITY_2020_2_OR_NEWER
if (roslynAnalyzerRulesetPath != null)
{
lines.Add(@" <PropertyGroup>");
lines.Add($" <CodeAnalysisRuleSet>{roslynAnalyzerRulesetPath}</CodeAnalysisRuleSet>");
lines.Add(@" </PropertyGroup>");
}
#endif
string[] analyzers = m_CurrentInstallation.GetAnalyzers();
string[] allAnalyzers = analyzers != null ? analyzers.Concat(roslynAnalyzerDllPaths).ToArray() : roslynAnalyzerDllPaths;
if (allAnalyzers.Any())
{
lines.Add(@" <ItemGroup>");
foreach (var analyzer in allAnalyzers)
{
lines.Add($@" <Analyzer Include=""{EscapedRelativePathFor(analyzer)}"" />");
}
lines.Add(@" </ItemGroup>");
}
}
return string.Join("\r\n", lines.Concat(footer));
}
private void SyncSolution(IEnumerable<Assembly> assemblies) private void SyncSolution(IEnumerable<Assembly> assemblies)
{ {
if (InvalidCharactersRegexPattern.IsMatch(ProjectDirectory)) if (InvalidCharactersRegexPattern.IsMatch(ProjectDirectory))
@@ -837,7 +849,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
if (array == null || array.Length == 0) if (array == null || array.Length == 0)
{ {
// HideSolution by default // HideSolution by default
array = new SolutionProperties[] { array = new [] {
new SolutionProperties() { new SolutionProperties() {
Name = "SolutionProperties", Name = "SolutionProperties",
Type = "preSolution", Type = "preSolution",
@@ -908,8 +920,8 @@ namespace Microsoft.Unity.VisualStudio.Editor
private string EscapedRelativePathFor(string file) private string EscapedRelativePathFor(string file)
{ {
var projectDir = FileUtility.Normalize(ProjectDirectory); var projectDir = ProjectDirectory.NormalizePathSeparators();
file = FileUtility.Normalize(file); file = file.NormalizePathSeparators();
var path = SkipPathPrefix(file, projectDir); var path = SkipPathPrefix(file, projectDir);
var packageInfo = m_AssemblyNameProvider.FindForAssetPath(path.Replace('\\', '/')); var packageInfo = m_AssemblyNameProvider.FindForAssetPath(path.Replace('\\', '/'));
@@ -917,7 +929,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
{ {
// We have to normalize the path, because the PackageManagerRemapper assumes // We have to normalize the path, because the PackageManagerRemapper assumes
// dir seperators will be os specific. // dir seperators will be os specific.
var absolutePath = Path.GetFullPath(FileUtility.Normalize(path)); var absolutePath = Path.GetFullPath(path.NormalizePathSeparators());
path = SkipPathPrefix(absolutePath, projectDir); path = SkipPathPrefix(absolutePath, projectDir);
} }
@@ -931,11 +943,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
return path; return path;
} }
private static string ProjectFooter()
{
return GetProjectFooterTemplate();
}
static string GetProjectExtension() static string GetProjectExtension()
{ {
return ".csproj"; return ".csproj";

View File

@@ -0,0 +1,27 @@
using System;
namespace Microsoft.Unity.VisualStudio.Editor
{
internal class ProjectProperties
{
public string ProjectGuid { get; set; } = string.Empty;
public string LangVersion { get; set; } = "latest";
public string AssemblyName { get; set; } = string.Empty;
public string RootNamespace { get; set; } = string.Empty;
public string OutputPath { get; set; } = string.Empty;
// Analyzers
public string[] Analyzers { get; set; } = Array.Empty<string>();
public string RulesetPath { get; set; } = string.Empty;
// RSP alterable
public string[] Defines { get; set; } = Array.Empty<string>();
public bool Unsafe { get; set; } = false;
// VSTU Flavouring
public string FlavoringProjectType { get; set; } = string.Empty;
public string FlavoringBuildTarget { get; set; } = string.Empty;
public string FlavoringUnityVersion { get; set; } = string.Empty;
public string FlavoringPackageVersion { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa7011e2ea1ff024083fea2179f3df08
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -30,7 +30,7 @@ namespace Microsoft.Unity.VisualStudio.Editor.Testing
FullName = testAdaptor.FullName; FullName = testAdaptor.FullName;
Type = testAdaptor.TypeInfo?.FullName; Type = testAdaptor.TypeInfo?.FullName;
Method = testAdaptor?.Method?.Name; Method = testAdaptor.Method?.Name;
Assembly = testAdaptor.TypeInfo?.Assembly?.Location; Assembly = testAdaptor.TypeInfo?.Assembly?.Location;
Parent = parent; Parent = parent;

View File

@@ -8,11 +8,14 @@ namespace Microsoft.Unity.VisualStudio.Editor.Testing
[InitializeOnLoad] [InitializeOnLoad]
internal class TestRunnerApiListener internal class TestRunnerApiListener
{ {
private static TestRunnerApi _testRunnerApi; private static readonly TestRunnerApi _testRunnerApi;
private static TestRunnerCallbacks _testRunnerCallbacks; private static readonly TestRunnerCallbacks _testRunnerCallbacks;
static TestRunnerApiListener() static TestRunnerApiListener()
{ {
if (!VisualStudioEditor.IsEnabled)
return;
_testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>(); _testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
_testRunnerCallbacks = new TestRunnerCallbacks(); _testRunnerCallbacks = new TestRunnerCallbacks();
@@ -26,7 +29,7 @@ namespace Microsoft.Unity.VisualStudio.Editor.Testing
private static void RetrieveTestList(TestMode mode) private static void RetrieveTestList(TestMode mode)
{ {
_testRunnerApi.RetrieveTestList(mode, (ta) => _testRunnerCallbacks.TestListRetrieved(mode, ta)); _testRunnerApi?.RetrieveTestList(mode, ta => _testRunnerCallbacks.TestListRetrieved(mode, ta));
} }
public static void ExecuteTests(string command) public static void ExecuteTests(string command)
@@ -41,12 +44,12 @@ namespace Microsoft.Unity.VisualStudio.Editor.Testing
var testMode = (TestMode)Enum.Parse(typeof(TestMode), command.Substring(0, index)); var testMode = (TestMode)Enum.Parse(typeof(TestMode), command.Substring(0, index));
var filter = command.Substring(index + 1); var filter = command.Substring(index + 1);
ExecuteTests(new Filter() { testMode = testMode, testNames = new string[] { filter } }); ExecuteTests(new Filter { testMode = testMode, testNames = new [] { filter } });
} }
private static void ExecuteTests(Filter filter) private static void ExecuteTests(Filter filter)
{ {
_testRunnerApi.Execute(new ExecutionSettings(filter)); _testRunnerApi?.Execute(new ExecutionSettings(filter));
} }
} }
} }

View File

@@ -10,6 +10,33 @@ namespace Microsoft.Unity.VisualStudio.Editor
{ {
internal static class UnityInstallation internal static class UnityInstallation
{ {
public static bool IsMainUnityEditorProcess
{
get
{
#if UNITY_2020_2_OR_NEWER
if (UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
return false;
#elif UNITY_2019_3_OR_NEWER
if (UnityEditor.Experimental.AssetDatabaseExperimental.IsAssetImportWorkerProcess())
return false;
#endif
#if UNITY_2021_1_OR_NEWER
if (UnityEditor.MPE.ProcessService.level == UnityEditor.MPE.ProcessLevel.Secondary)
return false;
#elif UNITY_2020_2_OR_NEWER
if (UnityEditor.MPE.ProcessService.level == UnityEditor.MPE.ProcessLevel.Slave)
return false;
#elif UNITY_2020_1_OR_NEWER
if (global::Unity.MPE.ProcessService.level == global::Unity.MPE.ProcessLevel.UMP_SLAVE)
return false;
#endif
return true;
}
}
public static Version LatestLanguageVersionSupported(Assembly assembly) public static Version LatestLanguageVersionSupported(Assembly assembly)
{ {
#if UNITY_2020_2_OR_NEWER #if UNITY_2020_2_OR_NEWER

View File

@@ -64,7 +64,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
var scene = SceneManager.GetSceneByPath(scenePath.Replace(Path.DirectorySeparatorChar, '/')); var scene = SceneManager.GetSceneByPath(scenePath.Replace(Path.DirectorySeparatorChar, '/'));
if (!scene.isLoaded) if (!scene.isLoaded)
{ {
var result = UnityEditor.EditorUtility.DisplayDialogComplex("Show Usage", var result = EditorUtility.DisplayDialogComplex("Show Usage",
$"Do you want to open \"{Path.GetFileName(scenePath)}\"?", $"Do you want to open \"{Path.GetFileName(scenePath)}\"?",
"Open Scene", "Open Scene",
"Cancel", "Cancel",

View File

@@ -35,6 +35,9 @@ namespace Microsoft.Unity.VisualStudio.Editor
static VisualStudioEditor() static VisualStudioEditor()
{ {
if (!UnityInstallation.IsMainUnityEditorProcess)
return;
if (IsWindows) if (IsWindows)
Discovery.FindVSWhere(); Discovery.FindVSWhere();
@@ -54,11 +57,11 @@ namespace Microsoft.Unity.VisualStudio.Editor
catch (Exception ex) catch (Exception ex)
{ {
UnityEngine.Debug.LogError($"Error detecting Visual Studio installations: {ex}"); UnityEngine.Debug.LogError($"Error detecting Visual Studio installations: {ex}");
return Array.Empty<VisualStudioInstallation>(); return Array.Empty<IVisualStudioInstallation>();
} }
} }
internal static bool IsEnabled => CodeEditor.CurrentEditor is VisualStudioEditor; internal static bool IsEnabled => CodeEditor.CurrentEditor is VisualStudioEditor && UnityInstallation.IsMainUnityEditorProcess;
public void CreateIfDoesntExist() public void CreateIfDoesntExist()
{ {
@@ -243,7 +246,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
return "Registry packages"; return "Registry packages";
case ProjectGenerationFlag.Unknown: case ProjectGenerationFlag.Unknown:
return "Packages from unknown sources"; return "Packages from unknown sources";
case ProjectGenerationFlag.None:
default: default:
return string.Empty; return string.Empty;
} }
@@ -286,9 +288,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
private bool OpenWindowsApp(string path, int line) private bool OpenWindowsApp(string path, int line)
{ {
var progpath = FileUtility var progpath = FileUtility.GetPackageAssetFullPath("Editor", "COMIntegration", "Release", "COMIntegration.exe");
.FindPackageAssetFullPath("COMIntegration a:packages", "COMIntegration.exe")
.FirstOrDefault();
if (string.IsNullOrWhiteSpace(progpath)) if (string.IsNullOrWhiteSpace(progpath))
return false; return false;

View File

@@ -158,6 +158,10 @@ namespace Microsoft.Unity.VisualStudio.Editor
var addinPath = IOPath.Combine(Path, $"Contents/Resources/lib/monodevelop/AddIns/{addinName}"); var addinPath = IOPath.Combine(Path, $"Contents/Resources/lib/monodevelop/AddIns/{addinName}");
if (File.Exists(IOPath.Combine(addinPath, addinAssembly))) if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
return addinPath; return addinPath;
addinPath = IOPath.Combine(Path, $"Contents/MonoBundle/Addins/{addinName}");
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
return addinPath;
} }
return null; return null;

View File

@@ -240,10 +240,9 @@ namespace Microsoft.Unity.VisualStudio.Editor
private static void CheckClient(Message message) private static void CheckClient(Message message)
{ {
Client client;
var endPoint = message.Origin; var endPoint = message.Origin;
if (!_clients.TryGetValue(endPoint, out client)) if (!_clients.TryGetValue(endPoint, out var client))
{ {
client = new Client client = new Client
{ {

19
ValidationConfig.json Normal file
View File

@@ -0,0 +1,19 @@
{
"FileContentKeywordValidation":
{
"Keywords":
[
{
"Targets": "+",
"Files":
[
"Editor/Discovery.cs"
],
"Patterns":
[
"vswhere\\.exe"
]
}
]
}
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a3f71b076c36a204a864f8c44142b3a9
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

10
ValidationExceptions.json Normal file
View File

@@ -0,0 +1,10 @@
{
"ErrorExceptions": [
{
"ValidationTest": "API Validation",
"ExceptionMessage": "Failed comparing against assemblies of previously promoted version of package. \nThis is most likely because the assemblies that were compared against were built with a different version of Unity. \nIf you are certain that there are no API changes warranting bumping the package version then you can add an exception for this error:\nRead more about this error and potential solutions at https://docs.unity3d.com/Packages/com.unity.package-validation-suite@latest/index.html?preview=1&subfolder=/manual/validation_exceptions.html#",
"PackageVersion": "2.0.11"
}
],
"WarningExceptions": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 788fbcfc0abc6c54b9504cfee3176c22
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -2,21 +2,21 @@
"name": "com.unity.ide.visualstudio", "name": "com.unity.ide.visualstudio",
"displayName": "Visual Studio Editor", "displayName": "Visual Studio Editor",
"description": "Code editor integration for supporting Visual Studio as code editor for unity. Adds support for generating csproj files for intellisense purposes, auto discovery of installations, etc.", "description": "Code editor integration for supporting Visual Studio as code editor for unity. Adds support for generating csproj files for intellisense purposes, auto discovery of installations, etc.",
"version": "2.0.9", "version": "2.0.11",
"unity": "2019.4", "unity": "2019.4",
"unityRelease": "21f1", "unityRelease": "25f1",
"dependencies": { "dependencies": {
"com.unity.test-framework": "1.1.9" "com.unity.test-framework": "1.1.9"
}, },
"relatedPackages": { "relatedPackages": {
"com.unity.ide.visualstudio.tests": "2.0.9" "com.unity.ide.visualstudio.tests": "2.0.11"
}, },
"upmCi": { "upmCi": {
"footprint": "b1cf463b7fca9fa8a65053f6120bce69640f5cea" "footprint": "321c90e37eb1ab86fe68d5f7e838c7e4553fc37e"
}, },
"repository": { "repository": {
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.ide.visualstudio.git", "url": "https://github.cds.internal.unity3d.com/unity/com.unity.ide.visualstudio.git",
"type": "git", "type": "git",
"revision": "c7cd4c6319806423b3d918b3e9599244e3993d41" "revision": "680e06d94ffca728223ae2cb14bb919cd354e2c1"
} }
} }