Я пытаюсь поставить отметку сборки в нижней части своего приложения с такими подробностями, как дата сборки, версия фреймворка, а также версия Visual Studio (т. е. версия Visual Studio, используемая для сборки приложения).
Раньше это было жестко закодировано, но теперь, когда мы мигрируем, сделать это программным — хорошая возможность. Мне удалось сделать первые два атрибута так:
Dim targetFrameworkAttribute As TargetFrameworkAttribute =
Assembly.GetExecutingAssembly().GetCustomAttributes(GetType(TargetFrameworkAttribute), False).SingleOrDefault()
lblBuildDate.Text = $"Build date: {mdBuildDate} - [ VS2017 ] [ {targetFrameworkAttribute.FrameworkDisplayName.Replace(" Framework", "")} ]"
(mdBuildDate собирается из базы данных в виде строки)
Но я изо всех сил пытаюсь найти способ собрать версию Visual Studio из сборки или где-либо еще.
Кто-нибудь знает возможно ли это?
Вы можете получить его из стандартного вывода vswhere.exe
Dim proc = New Process() With
{
.StartInfo = New ProcessStartInfo() With
{
.FileName = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe",
.UseShellExecute = False,
.RedirectStandardOutput = True,
.CreateNoWindow = True
}
}
Dim lines = New Dictionary(Of String, String)()
proc.Start()
While Not proc.StandardOutput.EndOfStream
Dim line = proc.StandardOutput.ReadLine()
If line.Contains(": ") Then
Dim split = line.Split(": ", StringSplitOptions.None)
lines.Add(split(0), split(1))
End If
End While
Dim installationVersion = lines("installationVersion")
путем объединения этот ответ и этот пост MSDN Дэниела Мейкснера.
Поместите его в готовое приложение, пометив объект настроек вашего приложения номером версии. Или, возможно, текстовый шаблон?
Появляется vswhere.exe
необходимо установить вручную, если не используется VS2017+. Если у вас установлено несколько версий VS, как узнать, какая версия была собрана?
@topshot Для < 2017 есть и другие методы. Например, см. docs.microsoft.com/en-us/visualstudio/extensibility/internals/… для 2015 года. Microsoft изменила ситуацию.
Чего я не понимаю, так это того, как узнать, какая версия сделала фактическую сборку, как спрашивал OP, когда у вас установлено несколько версий. Может я не такой как большинство разработчиков, но у меня на компе 4 версии.
Каждая версия VS будет иметь свой собственный msbuild.exe, поэтому вам все равно нужно будет определить правильный вариант в зависимости от того, с какой VS вы работаете.
Я надеюсь, это поможет
internal static string GetVisualStudioInstalledPath()
{
var visualStudioInstalledPath = string.Empty;
var visualStudioRegistryPath = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0");
if (visualStudioRegistryPath != null)
{
visualStudioInstalledPath = visualStudioRegistryPath.GetValue("InstallDir", string.Empty)
as string;
}
if (string.IsNullOrEmpty(visualStudioInstalledPath) ||
!Directory.Exists(visualStudioInstalledPath))
{
visualStudioRegistryPath = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\VisualStudio\14.0");
if (visualStudioRegistryPath != null)
{
visualStudioInstalledPath = visualStudioRegistryPath.GetValue("InstallDir",
string.Empty) as string;
}
}
if (string.IsNullOrEmpty(visualStudioInstalledPath) ||
!Directory.Exists(visualStudioInstalledPath))
{
visualStudioRegistryPath = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\12.0");
if (visualStudioRegistryPath != null)
{
visualStudioInstalledPath = visualStudioRegistryPath.GetValue("InstallDir",
string.Empty) as string;
}
}
if (string.IsNullOrEmpty(visualStudioInstalledPath) ||
!Directory.Exists(visualStudioInstalledPath))
{
visualStudioRegistryPath = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\VisualStudio\12.0");
if (visualStudioRegistryPath != null)
{
visualStudioInstalledPath = visualStudioRegistryPath.GetValue("InstallDir",
string.Empty) as string;
}
}
return visualStudioInstalledPath;
}
Как и в случае с другим ответом, эта проблема подходит для разработчиков в команде, но это не сработает, если приложение запускается клиентами, у которых не установлена Visual Studio.
@Jacob JA Shanks: Я согласен, но предлагаю также добавить номер версии Visual Studio в базу данных. Просто предложение подумать.
Это было бы окончательным решением, но, поскольку мое предварительное исследование, чтобы увидеть, есть ли атрибут, которым я мог бы воспользоваться, ничего не дало, подумал, что могу попробовать опубликовать здесь, чтобы увидеть, не пропустил ли я что-то :)
Целевая версия платформы и версия Visual Studio доступны во время операции сборки как Свойства MSBuild как определенные или зарезервированные свойства. Эти свойства можно сделать доступными для использования в текстовом шаблоне T4 для генерации кода.
Следующая процедура основана на VS2017 Community Edition.
<#@ template debug = "false" hostspecific = "true" language = "VB" #>
<#@ parameter type = "System.String" name = "VisualStudioVersion" #>
<#@ parameter type = "System.String" name = "TargetFrameworkVersion" #>
<#@ assembly name = "System.Core" #>
<#@ output extension = ".vb" #>
Module ProjectInfo
Public ReadOnly VisualStudioVersion As String = "<#= VisualStudioVersion #>"
Public ReadOnly TargetFrameworkVersion As String = "<#= TargetFrameworkVersion #>"
Public ReadOnly BuildDate As New DateTime(<#= DateTime.Now().Ticks #>L)
End Module
<!-- Define the parameters available T4 Text templates -->
<ItemGroup>
<T4ParameterValues Include = "VisualStudioVersion">
<Value>$(VisualStudioVersion)</Value>
<Visible>false</Visible>
</T4ParameterValues>
<T4ParameterValues Include = "TargetFrameworkVersion">
<Value>$(TargetFrameworkVersion)</Value>
<Visible>false</Visible>
</T4ParameterValues>
</ItemGroup>
<!-- the following will cause the T4 template to be processed before the build process begins -->
<Import Project = "$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets" />
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
Module ProjectInfo
Public ReadOnly VisualStudioVersion As String = "15.0"
Public ReadOnly TargetFrameworkVersion As String = "v4.72"
Public ReadOnly BuildDate As New DateTime(636968364980609475L)
End Module
После того, как вы успешно создадите свой проект, значения, определенные в "ProjectInfo.vb", будут доступны для другого кода. Файл будет регенерироваться при каждой сборке.
Справочные статьи:
Редактировать: В качестве альтернативы редактированию файла имя проекта.vbproj вы также можете поместить операторы, представленные на шаге 5, в текстовый файл с именем Directory.Build.targets, который будет находиться в папке проекта. Содержимое должно быть заключено в тег <Project>
.
<Project>
statements from Step 5
</Project>
Спасибо за подробную инструкцию! Я попробую, когда вернусь в офис
Проблем с настройкой не было, работает отлично! Небольшая оговорка заключается в том, что это номер версии, а не год, но это справедливый компромисс. Большое спасибо!
@JacobJAShanks, команда $(something)
в MSBuild очень универсальна в том, что она может получить. Он может извлекать данные из переменных среды, свойств MSBuild или даже оценивать статические методы/свойства класса .Net. С учетом сказанного появляется переменная среды с именем VisualStudioEdition, которая дает «Microsoft Visual Studio Community 2017» для настройки, используемой в моем ответе. Я бы порекомендовал заключить возвращаемое значение в одинарные кавычки, чтобы избежать ошибок «Экспресс-блок оценивается как нулевой», если он не существует. то есть <Value>'$(VisualStudioEdition)'</Value>
Это нормально для компьютеров разработчиков (при условии, что мы все используем одну и ту же версию), но не для клиентских компьютеров, на которых не установлена Visual Studio. Это действительно должна быть запись версии Visual Studio, используемой для сборки приложения, а не версии, установленной на устройстве.