2017-10-03 11 views
9

J'ai un nouveau fichier de projet csproj qui remplace IntermediateOutputPath. Il ressemble à ceci:Comment obtenir IntermediateOutputPath à partir de l'extension Visual Studio et du nouveau format csproj

<PropertyGroup> 
    <TargetFramework>netstandard1.6</TargetFramework> 
    <IntermediateOutputPath>new\path\to\obj</IntermediateOutputPath> 
</PropertyGroup> 

Le problème est, mon extension Visual Studio ne peut pas accéder à la propriété IntermediateOutputPath. Project.Properties semble avoir beaucoup moins de choses par rapport à l'ancien format de projet.

J'ai également essayé project.ConfigurationManager.ActiveConfiguration.Properties avec le même succès.

Est-il possible d'obtenir ces informations à partir de l'extension Visual Studio?

+0

Can vous partagez un exemple de projet sur github.com qui peut être débogué? –

+0

Il n'y a pas beaucoup de code à partager. Fondamentalement, vous créez un exemple d'extension Visual Studio VSIX. Dans l'extension, obtenez l'objet 'DTE' comme ceci' var dte = (DTE) GetService (typeof (SDTE)); 'Ensuite, lors du débogage de votre nouvelle extension, vous pouvez accéder à une solution et énumérer ses 'Projets'. Auparavant, je pouvais lire toutes les propriétés MSBuild à partir de là, mais plus maintenant. – ionoy

+0

J'ai tout l'installation fait mais pas capable de mettre cette option? Comment puis-je le définir? L'ajouter manuellement crée une erreur lors du chargement du projet –

Répondre

3

Je créé une simple extension d'imprimer toutes les propriétés

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); 
      } 
     } 
    } 

Et cela a donné ci-dessous la sortie

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 

Dans le projet CS j'avais ajouté

<IntermediateOutputPath>new\path\to\obj2</IntermediateOutputPath> 

Comme vous peut voir IntermediateOutputPath est à venir comme IntermediatePath. Vous pouvez donc utiliser

var config = project.ConfigurationManager.ConfigurationRow("Debug").Item(1) as Configuration; 
config.Properties.Item("IntermediatePath").Value 

Edit-1 - projet standard .NET

Output

Edition-2 - 12 août-2017

Alors après avoir creusé plus en le problème que j'ai découvert la propriété est une propriété MSBuild en tant que telle et pas une propriété liée à CSProject. C'est pourquoi vous ne le voyez pas dans l'attribut Propriétés. Cela nécessite un peu différent direction pour obtenir la valeur en utilisant 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; 
    } 

Et puis utiliser plus tard ces méthodes pour obtenir la valeur

var project = proj as EnvDTE.Project; 
IVsBuildPropertyStorage storage = GetBuildPropertyStorage(project); 
string outputPath = GetBuildProperty("IntermediateOutputPath", storage); 

Et cela me donne la valeur correcte de la propriété

+0

Êtes-vous sûr de vouloir charger un nouveau format csproj? Par nouveau, je veux dire celui qui a la plupart des propriétés et du contenu définis implicitement. – ionoy

+0

Je viens de créer un nouveau projet dans Visual Studio 2017. Comment puis-je en créer un avec le plus de propriétés? –

+0

Vous pouvez créer un projet NetStandard. Il devrait certainement utiliser le nouveau format. – ionoy