I want to get a reference to the current solution, using the DTE object with C# in Visual Studio 2015.
using System;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
namespace TemplatesExample
{
class Program
{
static void Main(string[] args)
{
IVsSolution solution = Package.GetGlobalService(typeof(DTE)) as IVsSolution;
Console.WriteLine(solution.ToString());
Console.ReadKey();
}
}
}
But when I use this, my solution object is always NULL.
So how do I get to my current solution object in VS2015 using C# on .net framework 4.6?
Try this sample. Up and running on VS2015.
( This method is valid only for the same solution ).
using EnvDTE;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public class DTEHandle
{
//EnvDTE.Project proj;
//EnvDTE.Configuration config;
//EnvDTE.Properties configProps;
//EnvDTE.Property prop;
EnvDTE.DTE DTE = Marshal.GetActiveObject("VisualStudio.DTE.14.0") as EnvDTE.DTE;
public EnvDTE.Project GetProject(String Name)
{
foreach (EnvDTE.Project item in DTE.Solution.Projects)
{
if (item.Name == Name)
{
return item;
}
}
return null;
}
}
public Form1()
{
InitializeComponent();
EnvDTE.DTE DTE = Marshal.GetActiveObject("VisualStudio.DTE.14.0") as EnvDTE.DTE;
DTEHandle h = new DTEHandle();
EnvDTE.Project proj = h.GetProject("Test");
foreach (EnvDTE.ProjectItem item in proj.ProjectItems)
{
if (item.Name == "Program.cs")
{
TextSelection s = item.Document.Selection as TextSelection;
s.SelectAll();
MessageBox.Show(s.Text);
}
}
}
}
}
Related
I already create new custom field for screen Fixed Asset. The following code is my DAC extension:
using PX.Data;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.EP;
using PX.Objects.FA;
using PX.Objects.GL;
using PX.Objects;
using System.Collections.Generic;
using System;
namespace SGLCustomizeProject
{
public class FALocationHistoryExtension : PXCacheExtension<PX.Objects.FA.FALocationHistory>
{
#region UsrKodeArea
[PXDBString(50)]
[PXUIField(DisplayName = "Kode Area")]
[PXSelector(typeof(Search<KodeAreaMaster.roomCD,
Where<KodeAreaMaster.status,
Equal<statusActive>,
And<KodeAreaMaster.buildingID,
Equal<Current<FALocationHistory.buildingID>>>>>),
typeof(KodeAreaMaster.roomCD),
typeof(KodeAreaMaster.roomDescription),
typeof(KodeAreaMaster.buildingID),
typeof(KodeAreaMaster.status))]
public virtual string UsrKodeArea { get; set; }
public abstract class usrKodeArea : IBqlField { }
#endregion
#region UsrDeskripsiArea
[PXDBString(75)]
[PXUIField(DisplayName = "Deskripsi Area")]
public virtual string UsrDeskripsiArea { get; set; }
public abstract class usrDeskripsiArea : IBqlField { }
#endregion
}
}
I need to fill the selected value into another additional field in the current screen, please see the following screenshot:
I need to fill value of Deskripsi Area from selector field (pop up) into Deskripsi Area field.
I have tried the following code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using PX.Common;
using PX.Data;
using PX.Objects.CS;
using PX.Objects.CR;
using PX.Objects.CM;
using PX.Objects.GL;
using PX.Objects.AP;
using PX.Objects.EP;
using PX.Objects.IN;
using PX.Objects.FA.Overrides.AssetProcess;
using PX.Objects;
using PX.Objects.FA;
namespace SGLCustomizeProject
{
public class AssetMaint_Extension : PXGraphExtension<AssetMaint>
{
public virtual void _(Events.FieldUpdated<FALocationHistory, FALocationHistoryExtension.usrKodeArea> e)
{
var row = e.Row;
var ext = row.GetExtension<FALocationHistoryExtension>();
e.Cache.SetValue<FALocationHistoryExtension.usrDeskripsiArea>(row, ext.UsrKodeArea);
}
}
}
This code above has been worked, but the result is when I choose Kode Area field, it also fill into Deskripsi Area field. My goal is to fill Deskripsi Area with the same field (Deskripsi Area) from selector field.
I tried to change code above with the following code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using PX.Common;
using PX.Data;
using PX.Objects.CS;
using PX.Objects.CR;
using PX.Objects.CM;
using PX.Objects.GL;
using PX.Objects.AP;
using PX.Objects.EP;
using PX.Objects.IN;
using PX.Objects.FA.Overrides.AssetProcess;
using PX.Objects;
using PX.Objects.FA;
namespace SGLCustomizeProject
{
public class AssetMaint_Extension : PXGraphExtension<AssetMaint>
{
public virtual void _(Events.FieldUpdated<FALocationHistory, FALocationHistoryExtension.usrKodeArea> e)
{
var row = e.Row;
var ext = row.GetExtension<FALocationHistoryExtension>();
e.Cache.SetValue<FALocationHistoryExtension.usrDeskripsiArea>(row, ext.UsrDeskripsiArea);
}
}
}
But it doesn't work. Any step that I forget ?
Change the ALocationHistoryExtension_UsrKodeArea_FieldUpdated to ALocationHistory_UsrKodeArea_FieldUpdated
protected virtual void FALocationHistory_UsrKodeArea_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
{
if (e.Row is FALocationHistory)
{
sender.SetDefaultExt<FALocationHistoryExtension.usrDeskripsiArea>(e.Row);
}
}
To Override an Event Handler
use xxx_fieldUpdated event
In your aspx page check, that you have commitchanges set to true
[ as usually optional ] sometime is necessary to set autorefresh = true
Starting from 2017 R2 you can also use this approach:
public virtual void _(Events.FieldUpdated<FALocationHistory, FALocationHistoryExtension.usrKodeArea> e)
{
var row = e.Row;
var ext = row.GetExtension<FALocationHistoryExtension>();
e.Cache.SetValue<FALocationHistoryExtension.usrDeskripsiArea>(row, ext.UsrKodeArea);
var KodeAreaMaster =
PXSelect<KodeAreaMaster, Where<KodeAreaMaster.roomCD, Equal<Required<KodeAreaMaster.roomCD>>>>
.Select(Base, ext.UsrKodeArea).First().GetItem<KodeAreaMaster>();
e.Cache.SetValueExt<FALocationHistoryExtension.usrDeskripsiArea>();
}
I used the following code to provide my goal. Thanks for everyone for all the respons. :)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using PX.Common;
using PX.Data;
using PX.Objects.CS;
using PX.Objects.CR;
using PX.Objects.CM;
using PX.Objects.GL;
using PX.Objects.AP;
using PX.Objects.EP;
using PX.Objects.IN;
using PX.Objects.FA.Overrides.AssetProcess;
using PX.Objects;
using PX.Objects.FA;
namespace SGLCustomizeProject
{
public class AssetMaint_Extension : PXGraphExtension<AssetMaint>
{
public virtual void _(Events.FieldUpdated<FALocationHistory, FALocationHistoryExtension.usrKodeArea> e)
{
var row = e.Row;
var ext = row.GetExtension<FALocationHistoryExtension>();
if (ext.UsrKodeArea != null)
{
e.Cache.SetValue<FALocationHistoryExtension.usrDeskripsiArea>(row, ext.UsrKodeArea);
var kodeAreaMaster = PXSelect<KodeAreaMaster,
Where<KodeAreaMaster.roomCD,
Equal<Required<KodeAreaMaster.roomCD>>>>
.Select(Base, ext.UsrKodeArea).First().GetItem<KodeAreaMaster>();
e.Cache.SetValueExt<FALocationHistoryExtension.usrDeskripsiArea>(row, kodeAreaMaster.RoomDescription);
}
}
public virtual void _(Events.FieldUpdated<FALocationHistory.buildingID> e)
{
var row = e.Row as FALocationHistory;
var ext = row.GetExtension<FALocationHistoryExtension>();
if (row.BuildingID != null)
{
if (ext.UsrKodeArea != null)
{
var kodeAreaMaster = PXSelect<KodeAreaMaster,
Where<KodeAreaMaster.roomCD,
Equal<Required<KodeAreaMaster.roomCD>>>>
.Select(Base, ext.UsrKodeArea).First().GetItem<KodeAreaMaster>();
if (row.BuildingID == kodeAreaMaster.BuildingID)
{
return;
}
else
{
e.Cache.SetValueExt<FALocationHistoryExtension.usrKodeArea>(row, null);
e.Cache.SetValueExt<FALocationHistoryExtension.usrDeskripsiArea>(row, null);
}
}
}
else
{
e.Cache.SetValueExt<FALocationHistoryExtension.usrKodeArea>(row, null);
e.Cache.SetValueExt<FALocationHistoryExtension.usrDeskripsiArea>(row, null);
}
}
}
}
I want to find all PropertyChangedEventHandler events in my solution, and then find all listeners added to those events. But I can't seem to get a list of the events.
This is all the code in the solution being analyzed:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RoslynTarget
{
public class Example : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public void DoNothing() { }
}
}
And this is my code for analyzing it. references.Count == 1 and r.Locations.Count == 0, but exactly one location should be found. What's going on here?
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.MSBuild;
namespace RoslynTest
{
class Program
{
static void Main(string[] args)
{
const string solutionPath = #"C:\Users\<user>\Code\RoslynTarget\RoslynTarget.sln";
const string projectName = "RoslynTarget";
var msWorkspace = MSBuildWorkspace.Create(new Dictionary<string, string> { { "CheckForSystemRuntimeDependency", "true" } });
var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
var project =
solution.Projects
.Where(proj => proj.Name == projectName)
.First();
var compilation = project.GetCompilationAsync().Result;
var eventType = compilation.ResolveType("System.ComponentModel.PropertyChangedEventHandler").First();
var references = SymbolFinder.FindReferencesAsync(eventType, solution).Result;
foreach (var r in references)
{
foreach (var loc in r.Locations)
{
// ...
}
}
}
}
}
Extensions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
namespace RoslynTest
{
public static class Extensions
{
public static IEnumerable<INamedTypeSymbol> ResolveType(this Compilation compilation, string classFullName)
{
return new IAssemblySymbol[] { compilation.Assembly }
.Concat(compilation.References
.Select(compilation.GetAssemblyOrModuleSymbol)
.OfType<IAssemblySymbol>())
.Select(asm => asm.GetTypeByMetadataName(classFullName))
.Where(cls => cls != null);
}
}
}
Recently I've done similar thing where I was trying to find the reference of a method in complete solution.
To use FindReferenceAsync you have create symantic model first and find the symbol from there. Once you have the symbol you can use the FindReferenceAsync.
Here's the snippet that I used and it's working:
var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
foreach (var project in solution.Projects)
{
foreach (var document in project.Documents)
{
var model = document.GetSemanticModelAsync().Result;
var methodInvocation = document.GetSyntaxRootAsync().Result;
InvocationExpressionSyntax node = null;
try
{
node = methodInvocation.DescendantNodes().OfType<InvocationExpressionSyntax>()
.Where(x => ((MemberAccessExpressionSyntax)x.Expression).Name.ToString() == methodName).FirstOrDefault();
if (node == null)
continue;
}
catch(Exception exception)
{
// Swallow the exception of type cast.
// Could be avoided by a better filtering on above linq.
continue;
}
methodSymbol = model.GetSymbolInfo(node).Symbol;
found = true;
break;
}
if (found) break;
}
foreach (var item in SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result)
{
foreach (var location in item.Locations)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Project Assembly -> {0}", location.Document.Project.AssemblyName);
Console.ResetColor();
}
}
Here's the complete working code. If you want to visualize the Roslyn tree then you can try using Roslyn tree visualizer to see code structuring.
Update
As per discussion in comments with OP Installing Roslyn SDK fixed the issue. Assuming that there might be some updates in SDK to generate Symbols information as compared to Nuget dlls when using GetCompilationAsync.
Even using an example from the Documentation, I still can't find a way to successfully serialize to a file.
Code:
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using System.Threading;
namespace TestProject
{
class Program
{
static void Main(string[] args)
{
Item i = new Item
{
Username = "user",
Email = "user#user.com",
Password = "password"
};
File.WriteAllText(#"C:\users\user1.json", JsonConvert.SerializeObject(i));
using (StreamWriter file = File.CreateText(#"C:\users\user1.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, i);
}
}
}
}
Item.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestProject
{
public class Item
{
public string Email { get; set; }
public string Password { get; set; }
public string Username { get; set; }
}
}
When I run Program.cs, it shows no errors, but the JSON does not show in the file.
When I run your code I get a an exception writing to the users folder. Changing to my home folder works fine. I suspect this is your problem.
Addtionally, you're writing the file twice. The first time is showing an example of using the SerializeObject method to get a string back which is used with WriteAllText. The second block of code is using a StreamWriter. For your purposes, both are equivalent and you only need to use one or the other.
using (StreamWriter file = File.CreateText(#"C:\users\user1.json"))
{
var jsonResult = JsonConvert.SerializeObject(i);
file.WriteLine(jsonResult);
}
I have a promblem with run-time compiled classes. I have something like this 2 classes:
first class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Program.Bullet {
public class Class1{
private int i;
public Class1(int j){
i=j;
}
}
}
and second class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Program.Bullet;
namespace Program.Object {
public class Class2{
public Class2(){
Class1 c1 = new Class1(5);
}
}
}
This two classes I would like to compile in run-time and use them in my project. So I have function to compile it (XmlNode has data about fullPath etc):
private ModuleBuilder moduleBuilder;
private List<string> isCompiled;
private void Compile(XmlNode compileingClasses) {
foreach (XmlNode compileingClass in compileingClasses) {
string fullPath = compileingClass.Attributes["path"].InnerText;
string type = compileingClass.Attributes["name"].InnerText; ;
if (!isCompiled.Contains(type)) {
isCompiled.Add(type);
var syntaxTree = SyntaxTree.ParseFile("../../File1/File2/" + fullPath);
var comp = Compilation.Create("Test.dll"
, syntaxTrees: new[] { syntaxTree }
, references: metadataRef
, options: comilationOption
);
// Runtime compilation and check errors
var result = comp.Emit(moduleBuilder);
if (!result.Success) {
foreach (var d in result.Diagnostics) {
Console.WriteLine(d);
}
throw new XmlLoadException("Class not found " + fullPath);
}
}
}
}
Is it possible to get the reference on Class1 to Class2?
Edit: Better question
Is it possible to create MetadataReference on compiled Class1?
Something like:
string fullName = bullet.Attributes["fullName"].InnerText;
var o = moduleBuilder.GetType(fullName);
metadataRef.Add(new MetadataFileReference(o.Assembly.Location));
This throw NotSupportedException
You're trying to reference the assembly which is currently being built and I don't think Roslyn can do that.
What you can do instead is to create a single Compilation from all your classes (probably having a separate SyntaxTree for each class). If you do that, you won't need any references.
I'm trying to create a simple service using the code provided but i don't understand why have an exception when binding.
10-19 11:42:09.148 I/mono-stdout( 1622): MvxBind:Error: 10.40 Exception thrown during the view binding
MvxBindingLayoutInflatorFactory Line 133!
I need some help please :)
My Source:
DataStore Interface:
using Core.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
namespace Core.Interfaces
{
public interface IDataStore
{
void UpdateFeed(FeedModel feedModel);
void DeleteFeed(FeedModel feedModel);
void CreateFeed(FeedModel feedModel);
FeedModel GetFeed(Uri uri);
ObservableCollection<FeedModel> Feeds { get; }
}
}
DataStore Class:
using System;
using System.Collections.Generic;
using System.Linq;
using Core.Interfaces;
using System.Collections.ObjectModel;
using Cirrious.MvvmCross.Interfaces.ServiceProvider;
using Cirrious.MvvmCross.Interfaces.Platform;
using Cirrious.MvvmCross.Interfaces.Localization;
using Cirrious.MvvmCross.ExtensionMethods;
using Core.Helpers;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.IO;
namespace Core.Models
{
public class DataStore
: IDataStore
, IMvxServiceConsumer<IMvxSimpleFileStoreService>
, IMvxServiceConsumer<IMvxResourceLoader>
{
public DataStore()
{
Load();
}
public void UpdateFeed(FeedModel feedModel)
{
var toUpdate = this.m_feeds.First(feed => feed.Url == feedModel.Url);
toUpdate.CloneFrom(feedModel);
Save();
}
public void DeleteFeed(FeedModel feedModel)
{
this.m_feeds.Remove(this.m_feeds.First(feed => feed.Url == feedModel.Url));
Save();
}
public void CreateFeed(FeedModel feedModel)
{
this.m_feeds.Add(feedModel);
Save();
}
public FeedModel GetFeed(Uri uri)
{
return this.m_feeds.First(feed => feed.Url == uri);
}
private void Load()
{
var fileService = this.GetService<IMvxSimpleFileStoreService>();
if (!fileService.TryReadBinaryFile(LocationDataService.StoreFileName, LoadFrom))
{
var resourceLoader = this.GetService<IMvxResourceLoader>();
resourceLoader.GetResourceStream(LocationDataService.ResourceFileName, (inputStream) => LoadFrom(inputStream));
}
}
private bool LoadFrom(Stream inputStream)
{
try
{
var loadedData = XDocument.Load(inputStream);
if (loadedData.Root == null)
return false;
using (var reader = loadedData.Root.CreateReader())
{
var list = (List<FeedModel>)new XmlSerializer(typeof(List<FeedModel>)).Deserialize(reader);
this.m_feeds = new ObservableCollection<FeedModel>(list);
return true;
}
}
catch
{
return false;
}
}
private void Save()
{
var fileService = this.GetService<IMvxSimpleFileStoreService>();
fileService.WriteFile(LocationDataService.StoreFileName, (stream) =>
{
var serializer = new XmlSerializer(typeof(List<FeedModel>));
serializer.Serialize(stream, m_feeds.ToList());
});
}
private ObservableCollection<FeedModel> m_feeds;
public ObservableCollection<FeedModel> Feeds
{
get { return this.m_feeds; }
}
}
}
BaseViewModel:
using Cirrious.MvvmCross.Commands;
using Cirrious.MvvmCross.ExtensionMethods;
using Cirrious.MvvmCross.Interfaces.Commands;
using Cirrious.MvvmCross.Interfaces.ServiceProvider;
using Cirrious.MvvmCross.ViewModels;
using Core.Interfaces;
namespace Core.ViewModels
{
public class BaseViewModel
: MvxViewModel
, IMvxServiceConsumer<IDataStore>
{
protected IDataStore DataStore
{
get { return this.GetService<IDataStore>(); }
}
}
}
FeedManagerViewModel:
using Cirrious.MvvmCross.Commands;
using Cirrious.MvvmCross.Interfaces.Commands;
using Core.Controls;
using Core.Models;
using System;
using System.Collections.ObjectModel;
namespace Core.ViewModels
{
public class FeedsManagerViewModel
: BaseViewModel
{
public ObservableCollection<FeedModel> Feeds { get { return this.DataStore.Feeds; } }
...
}
}
View xml:
<Mvx.MvxBindableListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="{'ItemsSource':{'Path':'Feeds'}, 'ItemClick':{'Path':'DisplayItemCommand'}}"
local:MvxItemTemplate="#layout/feedlist_viewmodel" />
This is most likely an error in your XML... but it's hard to tell from just that one line of trace.
What version of MvvmCross are you running?
The tip version of both Master and vNext show line 133 as
MvxBindingTrace.Trace(MvxTraceLevel.Error, "Exception during creation of {0} from type {1} - exception {2}", name, viewType.FullName, exception.ToLongString());
So hopefully if you use the tip, then that should give you a lot more information about what is going wrong.
Beyond that, you can always try setting a breakpoint on the offending line to extract more information.
If the exception is on line 99 then change the error logging there from:
MvxBindingTrace.Trace(MvxTraceLevel.Error, "Exception thrown during the view binding ", exception.ToLongString());
to:
MvxBindingTrace.Trace(MvxTraceLevel.Error, "Exception thrown during the view binding {0}", exception.ToLongString());
The error will be in there somewhere :)
Another good debugging technique is to comment out lines one-by-one until the problem goes away - this helps identify where the problem is.
You've got a working development environment and a really powerful debugger - using it is a good skill to learn. 'Code Complete' is one of my favourite books ever :)