Hallo community,
ich habe eine Visual Studio Extension (VSIX) mit einem Command geschrieben. Auf Knopfdruck passiert im Command im Wesentlichen folgendes:
DatenManager datenManager = new DatenManager();
DatenManager.holDaten();
Dieses Command kann vom VS Nutzer zu einem beliebigen Zeitpunkt ausgelöst werden - direkt nach dem Start, noch bevor ein Projekt ausgewählt oder angelegt wurde, oder auch Mitten in der Arbeit an einem Projekt.
Nun möchte ich das datenManager-Objekt innerhalb eines Projekts zugänglich machen, sodass der Programmierer zu Lebzeiten der VS-Instanz die im Datenmanager enthaltenen Daten nutzen kann.
Sinngemäß also sowas:
VisualStudioInstance.GlobalObjectCache.add(datenManager) // das würde noch im Command passieren
...
...
try{
DatenManager dm = (DatenManager)VisualStudioInstance.GlobalObjectCache.GetObject("datenManager")
}
// ab hier wird dann innerhalb eines Projekts mit den Daten aus dem Datenmanager gearbeitet
...
Überall ist zu lesen, dass VS absolut erweiterbar und konfigurierbar ist, also gehe ich davon aus, dass es einen realen Gegenpart zu meinem erfundenen "VisualStudioInstance.GlobalObjectCache" geben muss.
Kann mich bitte jemand aufschlauen.
Kannst Du mal ganz neutral erklären, was Du wirklich tun willst - ohne hier vom expliziten Code zu sprechen?
Also: was willst Du tun? Wozu die Extension?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hi Abt,
die Extension implementiert ein Command, einen Button in der Werkzeugleiste von VS. Wird dieser Button gedrückt, wird eine Liste von Strukturen aus einer nicht statischen Quelle geladen, wobei jede Struktur aus einem string "Name" und einer List<string> "Werte" besteht. Der Ladevorgang für diese Strukturen, die geladenen Strukturen und einiges mehr, sind implementiert in einem Singleton-Objekt den ich in meinem Eingangspost "datenManager" genannt habe. Das ganze geschieht unabhängig davon ob und welche Art von Projekt in VS gerade bearbeitet wird. Bis hierhin Funktioniert alles wie gewünscht.
Eine Anwendung für die geladenen Strukturen soll sein:
Mein Problem ist, dass ich zum Zeitpunkt 3. nicht auf den "datenManager" zugreifen kann, den ich bei der Ausführung des Commands initialisiert habe. Aus dem Bauch heraus stelle ich mir eine Lösung vor, bei der ich das "datenManager"-Objekt nach der Initialisierung in einem "VisualStudio-globalen" Bereich ablege und von dort abrufe. Ich bin da aber sehr ahnungslos und deshalb offen für andere Vorschläge.
Nochmal die Bitte: kannst Du mal neutral formulieren, was Du tun willst?
Keiner hier, kann was mit Datenmanager anfangen.
Es ist nicht ersichtlich, was das sein soll.
Was genau eine Extension einer Entwicklungsumgebung dann inhaltlich mit einer Anwendung zutun haben soll: es erschließt sich - zumindest mir - null.
Natürlich kann man in einem .NET Programm nicht auf "irgendwelche" Objekte einer anderen Anwendung zugreifen; jedenfalls nicht einfach so.
Selbstverständlich kann daher eine .NET Anwendung niemals ein Objekt kennen, das in einer Visual Studio Extension läuft. So funktioniert kein .NET und im Endeffekt überhaupt Windows auch nicht.
Visual Studio - auch mit einer Extension - hat null mit der .NET Applikation am Hut, die Du in dem Editor entwickelst.
Visual Studio ist eben NUR ein Editor. Das solltest Du verstehen.
Du kannst genauso jedes .NET Programm mit Nodepad und Kommandozeile entwickeln.
Daher nochmal: was genau hast Du vor?
PS: und von Gedanken wie "globalen Objekten" solltest Du ganz ganz weiteren Abstand nehmen.
That's evil!
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Warum möchtest du diese Daten schon im Entwurfsmodus für die Eigenschaften festlegen?
Macht es nicht mehr Sinn, diese zur Laufzeit zu laden (z.B. aus einer XML-Datei o.ä. - Stichwort: Serialisierung)?
@Abt
Ich versuche mal nachher an einem Beispiel zu demonstrieren um was es mir geht. Vielleicht wird es dann klarer.
@Th69
Es ist halt so gefordert, dass die Daten an dieser Stelle verfügbar sein müssen. Der Entwickler des Forms soll zu dem Zeitpunkt wenn er ein Control plaziert auch die betreffenden Eigenschaften händisch festlegen. Dabei soll er aus einer festgelegten Menge an Werten auswählen. Die Werte werden bei bei jedem Bearbeitungsvorgang, von einem anderen System neu geladen.
Ok, die zip mit den Projekten ist zu groß, deshalb hänge ich hier die zwei relevanten .cs Dateien an.
using System.Runtime.InteropServices;
using EnvDTE;
und das was in der Methode Execute() passiert:
private void Execute(object sender, EventArgs e)
{
DTE dte = (DTE)Marshal.GetActiveObject("VisualStudio.DTE.15.0"); // bei VisualStudio 2017
//DTE dte = (DTE)Marshal.GetActiveObject("VisualStudio.DTE.14.0"); // bei VisualStudio 2015
Globals globals = dte.Globals;
string s = "";
try
{
s = (string)globals["meinGlobalVar"];
MessageBox.Show("Der Wert meiner globalen Variable ist: " + s);
}
catch(Exception ex)
{
globals["meinGlobalVar"] = "los gehts";
MessageBox.Show("Meine globale Variable wird mit 'los gehts' initialisiert");
}
}
Diese Extension erweitert mein VisualStudio um die Option "Invoke MeinCommand" im "Extras" Menü (in der englischen Version ist es das Tools Menü). Durch einen Click auf diese Option wird die Methode "Execute" ausgeführt.
static void Main(string[] args)
{
DTE dte = (DTE)Marshal.GetActiveObject("VisualStudio.DTE.15.0");
Globals globals = dte.Globals;
string s = globals["meinGlobalVar"];
MessageBox.Show(s);
globals["meinGlobalVar"] = "zweiter Schritt";
}
Diese Konsolenanwendung starte ich direkt aus VS.
Das ist im Grunde die Funktionalität auf die ich aus bin - nur solle statt Strings beliebige Objekte geteilt werden.
Auf das DTE.Globals Interface bin ich erst heute im Tagesverlauf gestoßen. So ganz bin ich da noch nicht durchgestiegen, aber es scheint so ziemlich das zu sein, was ich mir als Lösung für mein Problem vorstelle. Mir ist aber noch nicht gelungen beliebige Objekte über dieses Interface hin und her zu schieben (so wie die strings im obigen Beispiel).
Für eure konstruktive Beiträge bin ich weiterhin dankbar.