[英]How to get IntermediateOutputPath from Visual Studio extension and new csproj format
I have a new-style csproj
project file that overrides IntermediateOutputPath
. 我有一个新式的
csproj
项目文件,它覆盖了IntermediateOutputPath
。 It looks like this: 它看起来像这样:
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<IntermediateOutputPath>new\path\to\obj</IntermediateOutputPath>
</PropertyGroup>
The problem is, my Visual Studio extension can't access IntermediateOutputPath
property. 问题是,我的Visual Studio扩展无法访问
IntermediateOutputPath
属性。 Project.Properties
seems to have much less stuff compared to old project format. 与旧的项目格式相比,
Project.Properties
似乎有更少的东西。
I've also tried project.ConfigurationManager.ActiveConfiguration.Properties
with the similar success. 我也试过了类似成功的
project.ConfigurationManager.ActiveConfiguration.Properties
。
Is there any way to get this information from Visual Studio extension? 有没有办法从Visual Studio扩展中获取此信息?
So I created a simple extension to print all the properties 所以我创建了一个简单的扩展来打印所有属性
private string GetPropertiesString(Properties properties)
{
StringBuilder test = new StringBuilder();
foreach (Property property in properties)
{
try
{
test.AppendLine(property.Name + ":=" + property.Value.ToString());
Console.WriteLine(property.Name + ":=" + property.Value.ToString());
}
catch (Exception ex)
{
var x = ex.Message;
}
}
return test.ToString();
}
private void MenuItemCallback(object sender, EventArgs e)
{
DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2;
var sol = dte2.Solution;
var projs = sol.Projects;
foreach (var proj in sol)
{
var project = proj as Project;
var rows = project.ConfigurationManager.ConfigurationRowNames as IEnumerable<object>;
foreach (var row in rows)
{
var config = project.ConfigurationManager.ConfigurationRow(row.ToString()).Item(1) as Configuration;
string configs = GetPropertiesString(config.Properties);
}
}
}
And this gave below output 这给出了以下输出
LanguageVersion:=
RunCodeAnalysis:=False
NoStdLib:=False
ErrorReport:=prompt
CodeAnalysisUseTypeNameInSuppression:=True
CodeAnalysisInputAssembly:=bin\Debug\WindowsFormsApp1.exe
CodeAnalysisDictionaries:=
GenerateSerializationAssemblies:=2
CodeAnalysisModuleSuppressionsFile:=GlobalSuppressions.cs
StartWorkingDirectory:=
Optimize:=False
DocumentationFile:=
StartPage:=
OutputPath:=bin\Debug\
TreatWarningsAsErrors:=False
EnableASPDebugging:=False
IncrementalBuild:=True
CodeAnalysisFailOnMissingRules:=False
CodeAnalysisLogFile:=bin\Debug\WindowsFormsApp1.exe.CodeAnalysisLog.xml
DefineConstants:=DEBUG;TRACE
UseVSHostingProcess:=True
StartProgram:=
DefineDebug:=False
CodeAnalysisIgnoreBuiltInRules:=True
CodeAnalysisRuleSetDirectories:=;F:\VS2017\Team Tools\Static Analysis Tools\\Rule Sets
CodeAnalysisCulture:=
CodeAnalysisOverrideRuleVisibilities:=False
CodeAnalysisRuleAssemblies:=
DefineTrace:=False
DebugSymbols:=True
CodeAnalysisIgnoreBuiltInRuleSets:=True
CodeAnalysisRuleSet:=MinimumRecommendedRules.ruleset
NoWarn:=
CodeAnalysisIgnoreGeneratedCode:=True
EnableSQLServerDebugging:=False
BaseAddress:=4194304
RemoteDebugEnabled:=False
StartURL:=
AllowUnsafeBlocks:=False
TreatSpecificWarningsAsErrors:=
PlatformTarget:=AnyCPU
EnableUnmanagedDebugging:=False
StartWithIE:=False
StartArguments:=
IntermediatePath:=new\path\to\obj2\
CodeAnalysisRuleDirectories:=;F:\VS2017\Team Tools\Static Analysis Tools\FxCop\\Rules
DebugInfo:=full
CheckForOverflowUnderflow:=False
RemoteDebugMachine:=
Prefer32Bit:=True
CodeAnalysisSpellCheckLanguages:=
CodeAnalysisRules:=
RegisterForComInterop:=False
FileAlignment:=512
StartAction:=0
EnableASPXDebugging:=False
ConfigurationOverrideFile:=
WarningLevel:=4
RemoveIntegerChecks:=False
In the CS project I had added 在我添加的CS项目中
<IntermediateOutputPath>new\path\to\obj2</IntermediateOutputPath>
As you can see IntermediateOutputPath
is coming up as IntermediatePath
. 如您所见,
IntermediateOutputPath
即将成为IntermediatePath
。 So you can use 所以你可以使用
var config = project.ConfigurationManager.ConfigurationRow("Debug").Item(1) as Configuration;
config.Properties.Item("IntermediatePath").Value
Edit-1 - .NET standard project Edit-1 - .NET标准项目
Edit-2 - 12-Aug-2017 编辑-2 - 2017年8月12日
So after digging more into the issue I found out the property is a MSBuild property as such and not a CSProject related property. 因此,在深入研究问题之后,我发现该属性是一个MSBuild属性,而不是CSProject相关属性。 That is why you don't see it in the Properties attribute.
这就是为什么你没有在Properties属性中看到它。 This requires a bit different direction to get the value using
IVsBuildPropertyStorage.GetPropertyValue
这需要一个不同的方向来使用
IVsBuildPropertyStorage.GetPropertyValue
获取值
private IVsBuildPropertyStorage GetBuildPropertyStorage(EnvDTE.Project project)
{
IVsSolution solution = (IVsSolution)ServiceProvider.GetService(typeof(SVsSolution));
IVsHierarchy hierarchy;
int hr = solution.GetProjectOfUniqueName(project.FullName, out hierarchy);
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
return hierarchy as IVsBuildPropertyStorage;
}
private string GetBuildProperty(string key, IVsBuildPropertyStorage Storage)
{
string value;
int hr = Storage.GetPropertyValue(key, null, (uint)_PersistStorageType.PST_USER_FILE, out value);
int E_XML_ATTRIBUTE_NOT_FOUND = unchecked((int)0x8004C738);
// ignore this HR, it means that there's no value for this key
if (hr != E_XML_ATTRIBUTE_NOT_FOUND)
{
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
}
return value;
}
And then later use these methods to get the value 然后使用这些方法获取值
var project = proj as EnvDTE.Project;
IVsBuildPropertyStorage storage = GetBuildPropertyStorage(project);
string outputPath = GetBuildProperty("IntermediateOutputPath", storage);
And this gives me the correct value of the property 这给了我正确的财产价值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.