nerushfgbhjkze4ghbieurzdh789izouehzbugk4789ziogh
This commit is contained in:
parent
8f4df05ac8
commit
d2f03874f5
11 changed files with 451 additions and 0 deletions
18
GetGitDir/GetGitDir.csproj
Normal file
18
GetGitDir/GetGitDir.csproj
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
BIN
GetGitDir/GetGitDir.exe
Normal file
BIN
GetGitDir/GetGitDir.exe
Normal file
Binary file not shown.
25
GetGitDir/GetGitDir.sln
Normal file
25
GetGitDir/GetGitDir.sln
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34511.84
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GetGitDir", "GetGitDir.csproj", "{13C3220F-81E4-46E1-9D45-BFE51D425C7A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F57CB7EB-01A8-4A5D-ABDF-F6A655B99AE5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
20
GetGitDir/Program.cs
Normal file
20
GetGitDir/Program.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
try
|
||||
{
|
||||
if (!new FileInfo(".git").Exists)
|
||||
return 1;
|
||||
|
||||
var content = File.ReadAllLines(".git");
|
||||
|
||||
if (!content.Any(x => x.StartsWith("gitdir: ")))
|
||||
return 1;
|
||||
|
||||
var gitDirLine = content.First(x => x.StartsWith("gitdir: "));
|
||||
|
||||
Console.WriteLine(gitDirLine[8..]);
|
||||
return 0;
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
9
TranslationSourceGenerator/GlobalSuppressions.cs
Normal file
9
TranslationSourceGenerator/GlobalSuppressions.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>", Scope = "member", Target = "~P:TranslationSourceGenerator.Log._logger")]
|
||||
[assembly: SuppressMessage("GeneratedRegex", "SYSLIB1045:Convert to 'GeneratedRegexAttribute'.", Justification = "<Pending>")]
|
||||
15
TranslationSourceGenerator/Log.cs
Normal file
15
TranslationSourceGenerator/Log.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Project Makoto
|
||||
// Copyright (C) 2023 Fortunevale
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY
|
||||
|
||||
namespace TranslationSourceGenerator;
|
||||
|
||||
internal class Log
|
||||
{
|
||||
internal static LoggerClient _logger { get; set; }
|
||||
}
|
||||
295
TranslationSourceGenerator/Program.cs
Normal file
295
TranslationSourceGenerator/Program.cs
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
// Project Makoto
|
||||
// Copyright (C) 2023 Fortunevale
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY
|
||||
|
||||
global using Xorog.Logger;
|
||||
global using Xorog.UniversalExtensions;
|
||||
global using Xorog.UniversalExtensions.Entities;
|
||||
global using static TranslationSourceGenerator.Log;
|
||||
global using static Xorog.UniversalExtensions.UniversalExtensions;
|
||||
global using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TranslationSourceGenerator;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
public string MakotoSourceOrigin => $@"
|
||||
// Project Makoto
|
||||
// Copyright (C) 2023 Fortunevale
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY
|
||||
|
||||
namespace {this.Namespace};
|
||||
|
||||
#pragma warning disable CS8981
|
||||
#pragma warning disable CS8618
|
||||
#pragma warning disable IDE1006
|
||||
public class Translations : ITranslations
|
||||
{{
|
||||
public Dictionary<string, int> Progress = new();
|
||||
public CommandTranslation[] CommandList {{ get; set; }}
|
||||
|
||||
|
||||
#region AutoGenerated
|
||||
// InsertPoint
|
||||
#endregion AutoGenerated
|
||||
}}
|
||||
";
|
||||
|
||||
public string StringsJson { get; set; }
|
||||
|
||||
public string TranslationCs { get; set; }
|
||||
|
||||
public string Namespace { get; set; }
|
||||
|
||||
static void Main(string[] args)
|
||||
=> new Program().Execute(args).GetAwaiter().GetResult();
|
||||
|
||||
public async Task Execute(string[] args)
|
||||
{
|
||||
if (!Directory.Exists($"{new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory.FullName}/logs"))
|
||||
_ = Directory.CreateDirectory($"{new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory.FullName}/logs");
|
||||
|
||||
_logger = LoggerClient.StartLogger($"{new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory.FullName}/logs/{DateTime.UtcNow:dd-MM-yyyy_HH-mm-ss}.log", CustomLogLevel.Debug, DateTime.UtcNow.AddDays(-3), false);
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
if (!File.Exists(args.Length > 0 ? args[0] : "e252zru2rjb2rtb23jbrj2bthj2bthjb2jtb4jbtb2jtb4hj"))
|
||||
{
|
||||
_logger.LogError("Translation json expected as arg0");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(args.Length > 1 ? args[1] : "e252zru2rjb2rtb23jbrj2bthj2bthjb2jtb4jbtb2jtb4hj"))
|
||||
{
|
||||
_logger.LogError("Translation json expected as arg1");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Length < 2)
|
||||
{
|
||||
_logger.LogError("Namespace expected as arg2");
|
||||
return;
|
||||
}
|
||||
|
||||
this.StringsJson = args[0];
|
||||
this.TranslationCs = args[1];
|
||||
this.Namespace = args[2];
|
||||
|
||||
_logger.LogDebug("Project Makoto Translation Source Generator started up.");
|
||||
_logger.LogDebug("Strings.json Location: {0}", Path.GetFullPath(this.StringsJson));
|
||||
_logger.LogDebug("Translation.cs Location: {0}", Path.GetFullPath(this.TranslationCs));
|
||||
DateTime lastModify = new();
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dictionary<string, List<string>> addedFields = new();
|
||||
|
||||
FileInfo fileInfo = new(this.StringsJson);
|
||||
|
||||
if (lastModify != fileInfo.LastWriteTimeUtc)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<string> Warnings = new();
|
||||
var Insert = "";
|
||||
|
||||
_logger.LogDebug("Translation file updated. Updating Translations.cs..");
|
||||
|
||||
var jsonFile = (JObject)JsonConvert.DeserializeObject(File.ReadAllText(this.StringsJson));
|
||||
|
||||
string CreateValidValueName(string str)
|
||||
=> Regex.Replace(str, @"[^a-zA-Z0-9]", "_");
|
||||
|
||||
void RecursiveHandle(JObject token, string ParentPath, int depth)
|
||||
{
|
||||
foreach (var item in token)
|
||||
{
|
||||
var className = CreateValidValueName($"{item.Key.First().ToString().ToLower()}{item.Key.Remove(0, 1)}");
|
||||
|
||||
switch (className)
|
||||
{
|
||||
case "object":
|
||||
className = $"@{className}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var fieldName = CreateValidValueName(item.Key.FirstLetterToUpper());
|
||||
var entryPoint = $"{ParentPath}/{className}";
|
||||
var IndexPath = $"// {ParentPath} InsertPoint";
|
||||
|
||||
var InsertPosition = 0;
|
||||
if (!ParentPath.IsNullOrWhiteSpace())
|
||||
{
|
||||
InsertPosition = Insert.IndexOf(IndexPath) + IndexPath.Length;
|
||||
}
|
||||
|
||||
if (!addedFields.ContainsKey(IndexPath))
|
||||
addedFields.Add(IndexPath, new());
|
||||
|
||||
switch (item.Value.Type)
|
||||
{
|
||||
case JTokenType.Object:
|
||||
{
|
||||
var containsLocaleCode = false;
|
||||
var localeCodeIsArray = false;
|
||||
|
||||
List<KeyValuePair<string, JToken?>> tokens = new();
|
||||
foreach (var subItem in item.Value.ToObject<JObject>())
|
||||
{
|
||||
tokens.Add(subItem);
|
||||
|
||||
if (subItem.Key == "en")
|
||||
{
|
||||
containsLocaleCode = true;
|
||||
localeCodeIsArray = subItem.Value.Type == JTokenType.Array;
|
||||
}
|
||||
}
|
||||
|
||||
if (containsLocaleCode)
|
||||
{
|
||||
if (!localeCodeIsArray)
|
||||
{
|
||||
var line = $"{new string(' ', depth * 4)}public SingleTranslationKey {CreateValidValueName(item.Key)};";
|
||||
|
||||
if (addedFields[IndexPath].Contains(line))
|
||||
continue;
|
||||
|
||||
_logger.LogDebug("Found SingleKey '{0}'", item.Key);
|
||||
Insert = Insert.Insert(InsertPosition, $"\n{line}");
|
||||
|
||||
addedFields[IndexPath].Add(line);
|
||||
|
||||
if (!tokens.Any(x => x.Key == "de"))
|
||||
Warnings.Add($"String at path {entryPoint} has no de translation");
|
||||
}
|
||||
else
|
||||
{
|
||||
var line = $"{new string(' ', depth * 4)}public MultiTranslationKey {CreateValidValueName(item.Key)};";
|
||||
|
||||
if (addedFields[IndexPath].Contains(line))
|
||||
continue;
|
||||
|
||||
_logger.LogDebug("Found MultiKey '{0}'", item.Key);
|
||||
Insert = Insert.Insert(InsertPosition, $"\n{line}");
|
||||
|
||||
addedFields[IndexPath].Add(line);
|
||||
|
||||
if (!tokens.Any(x => x.Key == "de"))
|
||||
Warnings.Add($"String at path {entryPoint} has no de translation");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug("Found Group '{0}'", item.Key);
|
||||
|
||||
var line = $"\n{new string(' ', depth * 4)}public {className} {fieldName};\n" +
|
||||
$"{new string(' ', depth * 4)}public sealed class {className}\n" +
|
||||
$"{new string(' ', depth * 4)}{{\n" +
|
||||
$"{new string(' ', depth * 4)}// {entryPoint} InsertPoint\n" +
|
||||
$"{new string(' ', depth * 4)}}}\n";
|
||||
|
||||
if (addedFields[IndexPath].Contains(line))
|
||||
break;
|
||||
|
||||
Insert = Insert.Insert(InsertPosition, line);
|
||||
addedFields[IndexPath].Add(line);
|
||||
}
|
||||
|
||||
RecursiveHandle(item.Value.ToObject<JObject>(), entryPoint, depth + 1);
|
||||
break;
|
||||
}
|
||||
case JTokenType.Integer:
|
||||
{
|
||||
_logger.LogDebug("Found Int '{0}'", item.Key);
|
||||
|
||||
var line = $"\n{new string(' ', depth * 4)}public int {CreateValidValueName(item.Key)};";
|
||||
|
||||
if (addedFields[IndexPath].Contains(line))
|
||||
continue;
|
||||
|
||||
Insert = Insert.Insert(InsertPosition, line);
|
||||
addedFields[IndexPath].Add(line);
|
||||
break;
|
||||
}
|
||||
case JTokenType.Array:
|
||||
{
|
||||
_logger.LogDebug("Found Array '{0}'", item.Key);
|
||||
|
||||
var line = $"\n{new string(' ', depth * 4)}public {className}[] {fieldName};\n" +
|
||||
$"{new string(' ', depth * 4)}public sealed class {className}\n" +
|
||||
$"{new string(' ', depth * 4)}{{\n" +
|
||||
$"{new string(' ', depth * 4)}// {entryPoint} InsertPoint\n" +
|
||||
$"{new string(' ', depth * 4)}}}\n";
|
||||
|
||||
if (fieldName == "CommandList" && IndexPath == "// InsertPoint")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addedFields[IndexPath].Contains(line))
|
||||
{
|
||||
Insert = Insert.Insert(InsertPosition, line);
|
||||
addedFields[IndexPath].Add(line);
|
||||
}
|
||||
|
||||
foreach (var b in item.Value.ToObject<JArray>())
|
||||
RecursiveHandle(b.ToObject<JObject>(), entryPoint, depth + 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RecursiveHandle(jsonFile, "", 1);
|
||||
foreach (var b in Warnings)
|
||||
{
|
||||
_logger.LogWarn(b);
|
||||
}
|
||||
|
||||
_logger.LogWarn("Source Generation finished with {Count} warnings.", Warnings.Count);
|
||||
|
||||
Insert = string.Join("\n", Insert.Split("\n").Where(x => !x.Contains("InsertPoint")));
|
||||
|
||||
File.WriteAllText(this.TranslationCs, string.Join("\n", this.MakotoSourceOrigin.Replace("// InsertPoint", Insert).ReplaceLineEndings("\n").Split("\n", StringSplitOptions.RemoveEmptyEntries).Where(x => !x.IsNullOrWhiteSpace())));
|
||||
|
||||
_logger.LogDebug("Updated Translations.cs.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Failed to update Translations.cs.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
lastModify = fileInfo.LastWriteTimeUtc;
|
||||
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Failed to watch file", ex);
|
||||
await Task.Delay(10000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Task.Delay(-1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"profiles": {
|
||||
"TranslationSourceGenerator": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "\"C:\\Users\\Xorog\\Documents\\GitHub\\ProjectIchigo\\ProjectMakoto\\Translations\\strings.json\" \"C:\\Users\\Xorog\\Documents\\GitHub\\ProjectIchigo\\ProjectMakoto\\Entities\\Translation\\Translations.cs\""
|
||||
}
|
||||
}
|
||||
}
|
||||
1
TranslationSourceGenerator/RunDefault.sh
Normal file
1
TranslationSourceGenerator/RunDefault.sh
Normal file
|
|
@ -0,0 +1 @@
|
|||
dotnet run -- ../../ProjectMakoto/Translations/strings.json ../../ProjectMakoto/Entities/Translation/Translations.cs ProjectMakoto.Entities
|
||||
16
TranslationSourceGenerator/TranslationSourceGenerator.csproj
Normal file
16
TranslationSourceGenerator/TranslationSourceGenerator.csproj
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>annotations</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Dependencies\Xorog.Logger\Xorog.Logger.csproj" />
|
||||
<ProjectReference Include="..\..\Dependencies\Xorog.UniversalExtensions\Xorog.UniversalExtensions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
44
TranslationSourceGenerator/TranslationSourceGenerator.sln
Normal file
44
TranslationSourceGenerator/TranslationSourceGenerator.sln
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34309.116
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TranslationSourceGenerator", "TranslationSourceGenerator.csproj", "{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xorog.Logger", "..\..\Dependencies\Xorog.Logger\Xorog.Logger.csproj", "{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xorog.UniversalExtensions", "..\..\Dependencies\Xorog.UniversalExtensions\Xorog.UniversalExtensions.csproj", "{1082AEE5-F298-412D-BE0D-12253D25AF1C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
x64|x64 = x64|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Debug|x64.Build.0 = Debug|x64
|
||||
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Release|x64.ActiveCfg = Release|x64
|
||||
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Release|x64.Build.0 = Release|x64
|
||||
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.x64|x64.ActiveCfg = Debug|x64
|
||||
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.x64|x64.Build.0 = Debug|x64
|
||||
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Debug|x64.Build.0 = Debug|x64
|
||||
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Release|x64.ActiveCfg = Release|x64
|
||||
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Release|x64.Build.0 = Release|x64
|
||||
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.x64|x64.ActiveCfg = x64|x64
|
||||
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.x64|x64.Build.0 = x64|x64
|
||||
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Debug|x64.Build.0 = Debug|x64
|
||||
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Release|x64.ActiveCfg = Release|x64
|
||||
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Release|x64.Build.0 = Release|x64
|
||||
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.x64|x64.ActiveCfg = x64|x64
|
||||
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.x64|x64.Build.0 = x64|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0B29991B-405D-41AD-8AAA-56C1A701ED99}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Loading…
Add table
Add a link
Reference in a new issue