Laden...
S
Stu42 myCSharp.de - Member
Softwareentwickler Aus dem Norden Dabei seit 15.10.2006 506 Beiträge
Benutzerbeschreibung

Forenbeiträge von Stu42 Ingesamt 506 Beiträge

28.05.2021 - 23:02 Uhr

Ich glaube zu unprofessionell trifft es ganz gut 🙂

Aber ich muss auch sagen, dass wenn man quasi alleine entwickelt, man schon so ausgelastet ist, das man vom ökosystem nicht viel mitbekommt. Aber wie du schon sagst, es lohnt sich das ökosystem zu kennen.

So ein CI könnte man natürlich auch schnell mit einem Batch-Script implementieren: Pullen/Auschecken, Compilieren, VSTest-Ausführen, Dateien-Kopieren und Setups builden...

28.05.2021 - 10:23 Uhr

Danke für eure Antworten.

Ich habe ein Tool gefunden (rcedit), mit dem man die FileDescription und das Icon im nachhinein noch ändern kann. Das Ändern der FileDescription führt dazu, dass sich der Name im TaskManager ändert, egal wie der Name der exe ist. Somit komme ich erstmal um die Umbennenung der exe herum.

Für CI und automatische Buildprozesse fehlt hier bei mir leider die Infrastruktur. "Wir sind dafür zu klein". Schade eigentlich.

Ich muss gestehen, dass .NET 5.0 bisher an mir vorbeigezogen ist. Ich arbeite noch mit VS2017 und wenn man nicht immer upgraded, dann gibt es erstmal keine unterstürzung für die neuen Sachen. Das ist schon verrückt, wie sich technologien während der Entwicklung ändern. Ich habe jetzt eine WPF-Anwendung, welches jetzt erstmals an Kunden ausgeliefert wird - und diese Basiert auf einer technologie die nicht mehr weiterentwickelt wird (.net 4.8). An Migration habe ich erstmal nicht gedacht, weil MS ja sagt, dass man nur für neue Projecte .NET Core nutzen sollte und Bestehende weiterhin 4.8 targeten konnen. Aber immerhin gut, das .NET Core jetzt auch WPF kann.

Auf AppDomainen werde ich wohl verzichten können. Ich habe die Applikation jetzt in einen GUI und einen Steuerungsteil unterteilt. Stürzt die GUI ab, so kann ich diese einfach neustarten und der Steuerungsteil bleibt aktiv. Sowas kann man natürlich auch mit unterschiedlichen *.exe-Dateien realisieren.

27.05.2021 - 10:11 Uhr

Ja das Umbenennen der exe geht ja gerade nicht, wegen dem problem mit den App-Domains.

Den Titel im TaskManager kann ich mit [assembly: AssemblyTitle("XXXX")] beinflussen. Aber dann müsste ich für jeden Kunden der die Software unter seinem Namen wiederverkaufen will die AssemblyInfo.cs mit präprozessordirektiven anpassen um den AssemblyTitle zu ändern. Das probiere ich irgendwie zu vermeiden, da ich nicht für jeden OEM-Kunden die Software immer neu erstellen will.

Warum Kunden die Software unter einem eigenen Namen vertreiben möchten verstehe ich auch nicht wirklich - das beudeutet nur mehr arbeit für mich. Aber der Kunde ist nunmal König 🙂

27.05.2021 - 09:44 Uhr

Hallo!

Die Software soll für OEM unter einen anderen Namen laufen. Hierfür möchte ich auch gerne die Applikations.exe umbenennen.
Nach dem Umbenennen funktioniert das Programm leider nicht mehr.

Grund: Ich starte die GUI aus einer separaten AppDomain heraus. Die neue AppDomain kann das in der *.exe enthaltene Assembly nicht auflösen, weil die Datei ja umbenannt wurde. Die urpsrungs AppDomain, die entsteht wenn die umbenennte *.exe gestartet wird, enthällt jedoch das Assembly der *.exe.

Jetzt dachte ich mir, ich könne ja die *.exe-Assembly einfach die in die neue AppDomain im vorfeld einladen, z.B. so


guiDomain = AppDomain.CreateDomain("XXXXGui",
                                                    AppDomain.CurrentDomain.Evidence,
                                                    AppDomain.CurrentDomain.SetupInformation);
guiDomain.Load(File.ReadAllBytes(Assembly.GetEntryAssembly().Location));

Aber auch dies führt dazu, dass das Assembly aus der *.exe in der neuen AppDomain nicht aufgelöst werden kann.

Frage: Gibt es noch eine andere Möglichkeit, wie ich die AppDomain vor der Ausführung mit der vorhanden Assembly füttern kann?

Hintergrund: Die Umbennung der exe soll eigentlich nur dazu dienen, damit im TaskManager nicht der Ursprungsname der Applikation steht. Doch ich vermute leider, dass die Umbennung der exe nicht zur Umbennung des Prozesses führt.

Best Grüße, Stu

18.05.2018 - 10:09 Uhr

Beispiel-Code ist schwer, weil das über mehrere Projekte geht...
Auf einem anderem Entwicklungsrechner habe ich das Problem nicht und das Assembly wird richtig aufgelöst.

Das mit dem AssemblyResolve ist ein guter tip, da werde ich nochmal schauen.

Danke für eure Antworten.

11.05.2018 - 12:17 Uhr

Hallo!

Ich habe eine Applikation welche dynamisch Assemblies zur Laufzeit lädt. Diese "Module-Assemblies" befinden sich im "Modules" Unterordner der Applikation.
Jedes Modul kann dann noch eine GUI-Extension haben, welche sich dann im Unterordnet "GUI" befindet. Ein GUI-Assembly benötigt jedoch Typdefinitonen aus einem Module Assembly.

Das ist eigentlich kein Problem. Das GUI-Assembly hat eine Reference in VisualStudio auf ein "Module"-Assembly und kennt daher die Typen aus diesem zur compile-time. Im GUI-Ordner der Applikation liegen jedoch nicht die Module-Assemblies. Die Module-Assemblies werden von der Applikation jedoch früher geladen, so dass die Definitionen bereits in der AppDomain geladen sind.

Wenn ich nun eine GUI-Dll aus dem Unterordner laden will, welche auf einen Typ verweist der aus einem Modul-Assembly kommt, so kann die GUI-Dll nicht geladen werden weil der Modul-Typ nicht gefunden wird. Im Debugger liefert der Ausdruck "typeof(modul-type)" null zurück. Ich sehe jedoch dass der Typ in der AppDomain gelistet ist.

Warum kann zur Laufzeit ein bestimmter Typ nicht gefunden werden, obwohl er zuvor in die AppDomain geladen wurde?
Was mache ich falsch?

Liebe Grüße, Stu

31.08.2017 - 08:44 Uhr

Hey! Das ist ein Graphen-Control, ich Layoute damit die verschieden Achsen, die Legende und Items im Graph. Hätte man sicherlich auch mit Grids machen können.

Es war übrigens doch ein InvalidateVisual von mir (ein untergeordnetes Graph-Element). Ein typische Fall von zuviel Kaffee und zu spät am Programmiertag.

Mich würde es aber schon noch Interessieren, ob man die Quelle von einem InvalidateVisual-Aufruf irgentwie herausbekommen kann.

30.08.2017 - 16:36 Uhr

Hallo,

ich habe ein Control welches von Panel erbt und in dem ich MeasureOverride, ArrangeOverride und OnRender überschreibe. Mein Problem ist, dass andauernt ArrangeOverride und OnRender aufgerufen werden (komischer weise OnMeasure nicht).

Ich kann die Ursache dafür nicht finden. Es ist kein InvalidateVisual-Aufruf von einer anderen Stelle.
Das übergeordnete Control bleibt vom Layout her ruhig - dort wird OnRender nicht aufgerufen.
Binde ich das Control in ein Test-Projekt ein, dann tritt dieser "Fehler" nicht auf. In dem richtigen Projekt ist dieses Control in einem komplexeren Layout angeordnet.

Frage: Hat jemand irgendeine klevere Idee wie ich herausfinden kann was die Aufrufe von ArrangeOverride und folgend OnRender verursacht?
Da die Aufrufe ja alle aus dem Dispatcher kommen, kann ich da leider kein Breakpoint setzen.
Könnte man vielleicht die Aufrufe irgendwie profilen?

Mich wundert auch das MeasureOverride nicht aufgerufen wird, was ja zu einem vollständigen Layoutprozess eigentlich dazugehört. Ich meine auch das InvalidateVisual dazu führt, dass das Layout vollständig neu berechnet wird, also MeasureOverride auch mit aufgerufen wird.

Liebe Grüße, Stu

20.02.2017 - 09:46 Uhr

Also das klappt bei mir nicht.


List<ClassicMenuItem<FrameworkElement>> list = new List<ClassicMenuItem<FrameworkElement>>();

list.Add((ClassicMenuItem < FrameworkElement > ) new ClassicMenuModuleButton<PumpModule>());

ClassicMenuModuleButton ist nochmals von ClassicMenuModuleItem geerbt, aber das tut eigentlich nichts zur Sache.

Ich bekomme die Fehlermeldung dass der Typ nicht konvertiert werden kann. Was ja auch gar nicht so trivial ist, weil es ja tatsächlich auch verschiedene typen sind. Aber vllt gibt es ja noch einen Trick den ich nicht kenne.

20.02.2017 - 09:10 Uhr

Hi!

Ich habe eine Vererbungshierarchie von generichen Klassen und möchte eine Collection vom Grundtypen erstellen (also z.B. IEnumerable<ClassicMenuItem<?>>).


public class ClassicMenuItem<B>
        where B : FrameworkElement
    {
        public B MenuElement { get; protected set; }
    }

    public abstract class ClassicMenuModuleItem<T,B> : ClassicMenuItem<B>
        where T : Module
        where B : FrameworkElement
    {
        public T Module { get; set; }
        public string FunctionName { get; set; }
    }

Die Eigenschaft MenuElement von ClassicMenuItem muss ja mindestenz vom Typ FrameworkElement sein, d.h. es müsste doch eigentlich möglich sein die abgeleiteten Klassen auf ClassicMenuItem<FrameworkElement> casten.

Hat jemand eine Ahnung wie ich diesen Cast hinbekommen?

Schöne Grüße,
Stu

21.12.2016 - 08:41 Uhr

ah, auf der Doku-Seite war ich gestern auch schon... hab ich überlesen, war der tag wohl zu lang 😃

Danke 😃

20.12.2016 - 16:10 Uhr

Hi,

ich habe mal eine grundlegende Frage zur Netzwerkkommunikation.

Da eine TCP-Verbindung ja selbst auf die Daten "aufpasst" brauche ich ja nicht
unbedingt
eine Lesebestätigung von Teildaten in "meinem" protokoll. Wenn ein Fehler in der
Kommunikation auftritt werde ich wohl einen Verbindungsabbruch bekommen.

Mal angenommen ich möchte nun große Daten pro Zeiteinheit auf den NetzwerkStream
schreiben, so rufe ich oft NetworkStream.Write auf.
Meine Frage nun: Blockiert die Write-Methode irgendwann wenn der Sendepuffer voll ist?

Würde ich die Socket-Funktion "send" von Windows aufrufen, würde ich als Rückgabewert
ja die bytes bekommen, welche von der send-Funktion abgenommen wurden. Da
die NetworkStream.Write-Funktion jedoch nicht diesen Rückgabewert hat müsste sie ja blockieren...

Grüße, Stu

14.12.2016 - 09:40 Uhr

Geht denn das "wnd.dgFilterdaten.MouseDoubleClick"-Event wenn du es klassisch mit einer Methode verbindest?

Könnte mir vorstellen dass das MouseDoubleClick einfach nicht aufgerufen wird.

20.10.2016 - 09:03 Uhr

Danke für eure Anregungen.

Der Kommunikationsteil wird vorest nur benutzt wenn die GUI lebt.
Ich schaue mal wie schnell ich mit den AppDomainen weiter komme, aber bisher sieht es nur noch einer kleinen Umstellung aus.

19.10.2016 - 15:33 Uhr

Klappt bei diesem Aufruf leider nicht.

Wenn ich den SplashScreen herausnehme,
bekomme im Haupt ResourceDictionary eine Fehlermeldung, wenn ich ein ResourceDictionary einbinde:


...
 <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/Themes/GenericResources/GenericResources.xaml" />

Exception:

Fehlermeldung:
{"Assembly.GetEntryAssembly() gibt NULL zurück. Legen Sie die Application.ResourceAssembly-Eigenschaft fest, oder verwenden Sie die Syntax &quot;pack://application:,,,/assemblyname;component/&quot;, um die Assembly anzugeben, aus der die Ressource geladen werden soll."}

Wenn ich dann aber den Source-Pfad wie von dir beschrieben abändere, geht es!
Aber beim SplashScreen funktioniert das nicht.

Wahrscheinlich gibt Assembly.GetEntryAssembly() nun mal Null zurück.

Wenn ich den SplashScreen Aufruf aber wie folgt abändere tut es:

SplashScreen splashScreen = new SplashScreen(System.Reflection.Assembly.GetCallingAssembly(), "images/splashscreen.png");

Danke für den Tipp!

Ich hoffe ich mir fliegt diese AppDomain -Umstellung nicht bei viele weiteren Stellen um die Ohren.

19.10.2016 - 14:12 Uhr

Hi,

das Programm an dem ich gerade arbeite übernimmt u.a. Steuerungsaufgaben von
angeschlossenen Geräten.
Der Steuerungsprozess läuft dabei in einer eigener AppDomain und kommuniziert mit der WPF-GUI
über MemoryMappedFiles.

Sollte die GUI mal abstürzen, möchte ich nicht das der Steuerungsprozess mit untergeht. Idealer weise würde ich gerne die GUI nach einem Absturz mit Parametern neu starten.

Das Problem ist, dass die WPF-Gui in der ersten AppDomain im Hauptthread läuft.
Wenn die GUI dann abstürzt habe ich leider keine "Überwachungs-App Domain" mehr, welcher die GUI neu starten könnte.

Ich möchte also die GUI in einer eigenen AppDomain ausführen.
Nur wenn ich dies mit folgenden Code mache, können die Resourcedateien nicht geladen werden (ArgumentNullException).


 [STAThread]
        [LoaderOptimization(LoaderOptimization.MultiDomainHost)]
        static void Main()
        {
            AppDomain guiDomain = AppDomain.CreateDomain("Gui");

            guiDomain.DoCallBack(() =>
            {
                SplashScreen splashScreen = new SplashScreen("images/splashscreen.png");
                splashScreen.Show(true);

                App app = new App();
                app.InitializeComponent();
                app.Run();
            });

            /* Der folgende Code wuerde funktionieren
            SplashScreen splashScreen = new SplashScreen("images/splashscreen.png");
            splashScreen.Show(true);

            App app = new App();
            app.InitializeComponent();
            app.Run();*/
        }

Wenn ich den Startup-Code nicht in einer extra Domain ausführe läuft alles.
In dem Domain-Callback kann der SplashScreen bereits nicht auf "images/splashscreen.png"
zugreifen.

Kann es sein, dass am Start Resourcen in den Haupt-AppDomain geladen werden, welche
in einer neuen AppDomain nicht verfügbar sind?

Grüße,
Stu42

30.09.2016 - 14:57 Uhr

Hi,

ich hohle mal diesen Beitrag hervor, weil ich beim kompilieren mit VS2005
wieder folgende Fehlermeldung bekomme:

Fehlermeldung:
Error 4 "C:\Windows\Microsoft.NET\Framework\v2.0.50727\AL.exe" was not found. Either 1) Install the .NET Framework SDK, which will install AL.exe. Or 2) Pass the correct location of AL.exe into the "ToolPath" parameter of the AL task.

Heute hat Windows 10 bei mir ein Anniversary-Update installiert (mit Windows.old-Ordner!).
Noch so einem Update funktioniert immer irgendetwas nicht...

Hat jemand auch das Problem?
Hat mittlerweile jemand ein Tipp wie ich das behben kann?

Schöne Grüße,
Stu

[EDIT]
Letzens hatte ich das Problem durch eine komplette neuinstallation von Windows 10 mit Updates und ein nachträgliche Installation von VS2005 beheben können. Aber das kann ja wohl keine gängige Praxis nach einem Anniversary-Update sein.

07.06.2016 - 14:53 Uhr

Kommst vielleicht über Bindings an ihn heran? (z.B. CommandBinding für Click)

Wenn du selbst nicht von der Klasse erbst, kannst du es mal im Binding mit "RelativeSource Find Ancestor" probieren. Nur so ne idee.

02.06.2016 - 17:44 Uhr

Ich hatte kein NuGet dafür gefunden - wohl nicht gut genug gesucht. Ich werds ändern.

02.06.2016 - 16:01 Uhr

Hi,

anbei eine kleine Klasse zur schnellen Interprozesskommunikation über MemoryMappedFiles.
Die Komponente kann benutzt werden um Daten zwischen verschiedenen AppDomains oder Prozessen einfach und schnell auszutauschen.
Mehrere Teilnehmer teilen sich dabei einen Kanal. Schreibt ein Teilnehmer eine Byte-Nachricht, wird sie von allen anderen Teilnehmer Empfangen.

Anwendungsprogramm:


class Program
    {
        static void Main(string[] args)
        {
            IpcMmfTransition participantA = new IpcMmfTransition("TestChannel");
            IpcMmfTransition participantB = new IpcMmfTransition("TestChannel");
            IpcMmfTransition participantC = new IpcMmfTransition("TestChannel");

            participantA.DataAvailable += (transition, bytes) =>
            {
                Console.WriteLine("A received: " + Encoding.ASCII.GetString(bytes));
            };
            participantB.DataAvailable += (transition, bytes) =>
            {
                Console.WriteLine("B received: " + Encoding.ASCII.GetString(bytes));
            };
            participantC.DataAvailable += (transition, bytes) =>
            {
                Console.WriteLine("C received: " + Encoding.ASCII.GetString(bytes));
            };

            participantA.Run();
            participantB.Run();
            participantC.Run();

            while(participantC.GetNumberOfParticipants() < 3)
                Thread.Sleep(1);

            participantA.Transmit(Encoding.ASCII.GetBytes("A says Hello"));
            participantB.Transmit(Encoding.ASCII.GetBytes("B says Hello"));
            participantC.Transmit(Encoding.ASCII.GetBytes("C says Hello"));

            Thread.Sleep(500);

            participantA.Dispose();
            participantB.Dispose();
            participantC.Dispose();

            Console.ReadKey();
        }
    }
}

Das Programm mit dem benötigten Microsoft.Diagnostics.Runtime-Assembly befindet sich im Anhang.
Da ich die Komponente auch in meinen aktuellen Projekt einsetze, nehmen ich Fehler und anregungen gerne entgegen.

Liebe Grüße,
Stu

Edit: Mit NuGet

Schlagwörter: Interprozesskommunikation; Memory Mapped Files

02.06.2016 - 15:23 Uhr

Danke für eure Tipps!

Ich habe es jetzt so gelöst, dass ich mir die process id und die thread id im mmf speichere. Dauert eine Übertragung dann länger, wird überprüft ob alle beteiligten Prozesse (bei verschieden Prozessen), bzw. alle beteiligten Threads (bei einem Prozess und mehrere AppDomains), noch leben.

Die managed Threads hohle ich mir, wie von Abt schon erwähnt, aus einem Debug dump, welcher mit Microsoft.Diagnostics.Runtime (https://github.com/Microsoft/clrmd) wie folgt erstellt wird:


  using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 1000, AttachFlag.Passive))
                    {
                        ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
                        foreach (ClrThread thread in runtime.Threads)
                        {
                         //..
                        }
                    }

Da ein Kommunikationsabbruch der Fehlerfall ist, hoffe ich das die Lösung mit dem Debug-Dump in der Praxis nicht zu weiteren Fehlern führt.

Falls interesse an der kleinen IPC-Klasse besteht, kann ich diese gerne hier mit kleinem Beispiel mit einfügen.

02.06.2016 - 10:08 Uhr

Danke für deine Antwort!
Über die Funktion


System.Diagnostics.Process.GetCurrentProcess().Threads

bekomme ich zwar Id´s, die beziehen sich jedoch auf unmanaged Threads. Meine managed Threads sind da leider nicht enthalten.

An die ProcessId hab ich auch schon gedacht, das gibt aber Probleme wenn ich aus dem gleichen Process, aber mit unterschiedlichen AppDomains, arbeite. Aber vielleicht könnte ich ja beides, also sowohl die ManagedThreadID als auch die ProcessId speichert.

02.06.2016 - 09:23 Uhr

Hallo,

ich habe eine Klasse entwickelt welche eine Interprozesskommunikation über MemoryMappedFiles realisiert.

Problem: Wenn ein Prozess sich nicht richtig beendet und abstürzt, bekommen das die Kommunikationspartner nicht mit, wodurch die Kommunikation stehen bleibt (weil gewartet wird bis jeder die aktuelle Nachricht empfangen hat).

Nun dachte ich mir, ich könnte das Problem einfach lösen, wenn jeder Kommunikationsteilnehmer seine ManagedThreadId registriert. Bleibt die Kommunikation stehen, so mein Plan, wird nachgeschaut ob alle regestierten Threads leben und wenn nicht, gibt es eine Fehlerbehandlung.

Schwierigkeit: Wie kann ich alle ManagedThreadId von einen Process abrufen?

Grüße, Stu

13.04.2016 - 11:11 Uhr

Synchronisierung von Eigenschaften bekommt man mit Bindings hin.

Das Label passt sich aber eigentlich der größe des Inhaltes an, sofern das übergeordnete Panal das erlaubt.

Das Label hat im default Style ein Padding. Wenn du die Labelgröße manuell auf die Größe des TextBlocks setzt, wird das Padding stören in dem es das innere Control abschneidet. Probier mal das Padding auf 0 zu setzen.

13.04.2016 - 09:05 Uhr

Virtualisierung ist aktiviert, ich schaue mal nach wie gut das geht, bisher aber keine Probleme.
Anscheinend benutzt VS2015 ja auch Vektorgrafiken, welche man übrigens auch in der VS2015 Image Library einsehen kann.

Danke für eure Antworten.

11.04.2016 - 13:06 Uhr

Man kann ja z.B. Illustrator-Dateien auch als XAML speichern, die Ausgabe ist dann ein Resource-Dictionary mit "einigen" Elementen.
Ich hätte jetzt gedachte, dass das Rendern von diesen Vektorgrafiken noch viel länger dauert und mehr Speicher einnimmt.

11.04.2016 - 12:35 Uhr

Hallo,

mit welcher Icongröße würde man performant ein Programm bebildern, welches auch auf
einem 4k-Bildschirm, bzw. bei höherer dpi gut aussieht?

Normalerweise binde ich Bilder in 96 dpi in meine WPF Programme ein. D.h wenn ich ein 32 wpf-unit Icon "Slot" habe, nehme ich ein 32 px icon.

Wenn ich nun aber möchte, dass das eingebundene Bild auf höheren DPI-Einstellungen gut aussieht, müsste ich ja ein Bild mit höherer Auflösung bzw. einfach mehr Pixeln nehmen.
Also z.B. für ein 16 wpf-unit icon ein 64 px icon.

Das Problem ist dann nur, dass wenn das WPF-Programm auf 96 dpi läuft, das zu große Bild herunterskaliert wird, was je nach qualität performance benötigt.

Wenn ich nun z.B. ein Tree-View mit viele Elementen (z.B. 5000) habe, wobei jedes Item ein Bild enthällt, ist es dann ratsam größere Bilder zu verwenden die man dann runterskalieren lässt?

Schöne Grüße, Stu

31.03.2016 - 16:12 Uhr

Probier mal folgendes:
Nimm kein TemplateBinding, sonder ein Binding mit RelativeSource self.

z.B.: ..="{Binding Path=(local:Attached.Test), RelativeSource={RelativeSource Self}}"

31.03.2016 - 15:59 Uhr

Wenn du das Binding im Code-Behind erstellt und dort die Source auf ein Objekt setzt, wie soll er das denn überhaubt speichern können? Im Xaml kann man doch auch nicht einfach ein Objekt als Source angeben.

31.03.2016 - 10:29 Uhr

Du kannst einfach mal schauen was du alles für Fensterhandles bekommst.
Standard Windows-Controls sind auch Fenster.

Wenn du ein ListBox-Handle hättest könntest du probierem mit diesem über Window-Messges
zu interagieren (z.B. GETITEMDATA).

Edit:
Klar, eine Windows-Applikation benutzt die Windows-Api, die Frage ist nur wie viel davon.
Zum erzeugen eines Fensters wird die WinApi benötigt. Was dann auf dem Fenster zu sehen
ist, ist dann nochmal eine andere Geschichte. Dort könnten wieder "Unterfenster"-plaziert sein
oder "eigene Zeichnungen".

31.03.2016 - 09:29 Uhr

Sowas geht eigentlich nur vernünftig wenn die Applikation dafür eine Schnitstelle bereitstellt. Alles andere ist meist unbefriedigend.

Wenn du Glück hast benutzt deine Applikation die standard Window-Api. Dann kannst du probieren das Fensterhandle zu ergattern, wie du schon meintest.

29.03.2016 - 12:44 Uhr

Lies dir mal etwas über das Zweierkomplement durch.

29.03.2016 - 12:33 Uhr

Die Value-Property kannst du doch im Code behind einfach abfragen - glaube ich Verstehe nicht genau was du meinst.

21.03.2016 - 15:20 Uhr

Angebunde CLR-Eigenschaften konnte ich soweit nicht finden.

Ich habe ein recht komplexes WPF-Control, welches ich zur Laufzeit
erzeuge und dann einer DependencyProperty zuweise.

Im XAML habe ich dann einen ContentPresenter, dessen Content
an die DependencyProperty mit dem WPF-Control gebunden ist.

Wenn ich das Control dann löschen will, setze ich die DependencyProperty
zu null. Das Control verschwindet auch von der GUI.

Schaue ich mir dann den Heap an, ist das Objekt noch da. Die Liste der
Referenzen auf der Objekt ist riesig, darunter aber auch viele GUI-Elemente.
Viele Referenzen kommen aber von Untergeordneten-Elementen, welche
nach meinem Verständniss den GC aber nicht aufhalten sollten.

Frage: Könnte es sein dass die GUI-Element von WPF selbst nicht freigegeben werden
und dadurch mein Object nicht gelöscht wird?
Oder wird es auf jeden Fall an meinen Referenzen liegen?

18.03.2016 - 11:35 Uhr

Ah das ist guter Hinweis. Ich überprüfe jetzt mal ob ich an normale CLR Eigenschaften binde.

17.03.2016 - 15:30 Uhr

Ahja, hatt mir schon sowsa gedacht, war mal wieder nur etwas verwirrt
da ich gerade auf der Suche nach Speicherleaks bin.

Danke für eure Antworten.

17.03.2016 - 15:21 Uhr

Hallo,

ich arbeite seit längeren an einer etwas größeren WPF-Applikation,
bei der ich jetzt Memoryleaks feststelle.

Ich habe in der Heap-Ansicht auch eines der Objekte gefunden die
vom GC nicht freigegeben werden. Der Grund ist, dass in der GUI,
noch Bindings auf das Objekt bestehen, obwohl die GUI nicht mehr
angezeigt wird.
Das Objekt implementiert übrigens INotifyPropertyChanged. Wenn ich die
Properties auf die gebunden wird zu Null setze, wird das Objekt vom
Heap gelöscht.

Es kann doch aber nicht sein, dass ich alle gebunden Eigenschaften wieder
zu Null setzen muss, nur damit vom GC aufgesammelt werden, oder?

Grüße, Stu

17.03.2016 - 15:06 Uhr

Hallo,

ich hatte das Problem das ein Objekt vom GC nicht aus dem Heap entfernt
wurde.
Damit ich das besagte Objekt besser im VisualStudio Diagnosic Hub identifizieren konnte,
habe ich diesem ein 50 mb großes byte array angehängt.

Bei erzeugung des Objektes geht der Process-Memory schlagartig herauf, ich kann
das Objekt auf dem Heap sehen.
Wenn das Objekt vom Heap gelöscht wird, sehe ich dass sich der Heap um etwas
weniger als 50 mb verkleinert hat. (Warum nicht mindestens 50 mb?)
Das Objekt kann ich dann auch nicht mehr auf dem Heap finden.

Soweit so gut...
Aber warum geht der Process-Memory nicht runter?

Jetzt könnte man natürlich auf die Idee kommen dass der Speicher einfach vom
Programm behalten wird. Aber wenn ich wieder ein neues Objekt erstelle, geht der
Speicherverbrauch erneut hoch.

Im angehängten Bild habe ich drei Speicher-Snapshots erstellt:
Einen vor dem Erzeugen des Objektes, einen nach dem Erzeugen und
einem nach dem Löschen.
Man sieht dass sich die Heap-Größe ändert, der Processspeicher wird aber nicht viel weniger.

Liebe Grüße,Stu

22.01.2016 - 17:05 Uhr

Könnte man meinen, aber das Windows habe ich aber komplett neu installiert.
Bin mir da nicht 100% sicher, aber ich glaube einiges updates erstellen auch diesen Ordner.

22.01.2016 - 15:24 Uhr

Da muss wohl durch ein WindowsUpdate irgendwas durcheinander gekommen sein.
Es gab wohl ein größeres Windows-Update bei mir am 20.01, und zwar so groß dass ein "Windows.old" - Ordner angelegt wurde.

Ich habe den Rechner formattiert, und eine neue Windows 10 Version aufgespielt (mit vorinstallierten Updates), wieder VS2005 und vs 2015 installiert, und nun geht es wieder.

20.01.2016 - 16:02 Uhr

Hallo,

ich habe folgendes Problem bei dem ich nicht weiterkomme.

Ich habe hier mehrere Rechner auf denen Window 10 mit VS2005 und VS2015 Update 1
installiert ist. VS2005 wird noch für ein älteres Projekt benutzt. Heute wollte ich wieder eine
Änderung an dem älteren c#-Projekt vornehmen und bekomme beim kompilieren folgende Fehlernmeldung (auch bei anderen vs2005 projekten):

Fehlermeldung:
"The specified task executable location "c:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\AL.exe" is invalid."

Das komische: bis vorgestern ging es bei mir noch und heute morgen gab es bei mir windows update...
Erste dachte ich, dass es nur bei mir so ist, aber bei einem anderen windows 10-Rechner gibt es das gleiche Problem.

In dem ToolSet-Path c:\Program Files\Microsoft SDKs\Windows gibt es auch keine Version "v6.0A".

Was ich schon erfolglos probiert habe:

  • Repair VS2005
  • Gelöscht und Neuinstallation von VS2005
  • Probiert die Tookkit Version nach zu installieren.

Wenn ich ein neues Projekt mit vs2005 anlege, dann kommt der Fehler nicht.
Wenn ich das alte Projekt projekt mit vs 2015 öffne (konvertiere) bekomme ich
den gleichen Fehler. Auch wenn ich das TargetFramework ändere!
Ich hab die Projektdateien von einem neuen kompilierbaren Test-Projekt mit den bestehen Projektdateien verglichen und Stückweise angepasst, aber der Fehler bleibt. Dabei steht in beiden ToolsVersion="14.0" drin.

Ich bin ratlos - Hat jemand eine Idee was kaputt ist?

Grüße, Stu

05.05.2014 - 21:35 Uhr

Ahja, das ist ne interessante Optimierung - Dann erspart man sich das Daten senden.

05.05.2014 - 16:25 Uhr

Die Idee mit dem Dienst finde ich ganz gut. Das lässt sich auch einfach in das bestehende Programm einbauen.

Überall wo ich einen Datei-Stream erzeuge, erzeuge ich dann einfach einen Eigenen Stream, der die Daten an den Dienst weiterleitet.
Jetzt muss ich nur noch überlegen wie der Datenaustausch am einfachsten ist. Wahrscheinlich über eine lokale Netzwerkverbindung.

05.05.2014 - 10:38 Uhr

Alles klar, danke für den Hinweis - ich werd an der Stelle dann mal weiter schauen.

05.05.2014 - 10:18 Uhr

Liebe Alle,

gibt es unter Windows eine Möglichkeit, dass eine Datei/Ordner NUR von einer Applikation editiert bzw. gelöscht werden darf?
(Dem Benutzer sollte also das Bearbeiten/Löschen über dem Windows-Explorer bzw. anderen Programmen verwehrt werden)

D.h. der User dürfte quasi keine Dateiberechtigungen haben, aber meine Applikation (welche ja auch unter den Benutzerberechtigungen läuft) schon.
Die Applikation müsste also mehr Berechtigungen als der Benutzer haben.

Ich habe mir schon ACL bzw. die Klasse "FileSystemSecurity" angeschaut, dort fand ich aber wieder nur Berechtigungen für einzelne Benutzer, nicht jedoch für Applikationen.

Hat jemand eine Ahnung oder ein Tipp wie man so etwas hinbekommen könnte?

Liebe Grüße,
Stu

10.08.2012 - 14:09 Uhr

Ah... ich glaube ich habe es verstanden...

Die gemessene Größe wird niemals unterschritten, überschritten aber schon...

10.08.2012 - 14:00 Uhr

Hallo,

bis jetzt dachte ich immer, dass der finalSize-Parameter der ArrangeOverride-Funktion
der selbe ist, der dem Control beim Arrange(...) übergeben wird.

Ich hab folgendes Problem:

In einem eigenen Layouter rufe ich in der MeasureOverride Funktion
die Measure-Funktion eines Child-Elements mit der AvailableSize auf.

Nun stelle ich aber im Arrange fest, dass ich das Child-Element kleiner Anordnen möchte
als es zuvor bemessen wurde.
Dazu rufe ich die Arrange-Funktion des Child-Elementes auf, und übergebe eine andere Größe.

In der ArrangeOverride-Funktion des Child-Element kommt aber ++nicht ++ jene Größe an die ich im Arrange übergeben habe, sonder es kommt die Größe an, welche beim Measure zuvor errechnet wurde.

Was wird mit der Größe gemacht die ich im Arrange übergebe, und wie kann ich das Child-Element dann kleiner anordnen?

Grüße,
Stu

01.03.2012 - 10:48 Uhr

Hallo,

ich habe mir eine eigene ComboBox geschrieben, die als DropDown
eine Form anzeigt.

Problem:
Wenn ich die "DropDownForm" wieder schließe, dann bekommt das Hauptfenster
keinen Focus mehr, weil zuvor die DropDownForm den focus bekommen hat.
(der Fokus wechselt vom Hauptfenster zur DropDownForm)

Ich hab schon einiges probiert um den Focus wieder auf das Hauptfenster zu
bekommen (BringToFront, Activate, Focus), nichts funktioniert.

Was interessant zu wissen wäre, ist wie normale ComboBoxen es schaffen
ein DropDown anzuzeigen ohne das der Fokus vom Hauptfenster geht.

Hat jemand eine Ahnung?

Grüße, Stu