WPF Image laden wenn Programm von ein Dienst gestartet wurde
-
Hi NullBockException
nein eine Exception wird nicht ausgelöst
was mir noch aufgefallen ist das wenn ich die Anwendung über den Dienst starte dann hängt auch der GC dies konnte ich aber lösen -> https://social.msdn.microsoft.com/Forums/vstudio/en-US/835db88e-db51-4f83-bd4f-a10d126effa6/gc-does-not-work-in-console-application-with-stathread-specified?forum=clr
leider konnte ich das nur auf den Dienst abschnitt anwenden sobald ich versuche etwas mit einer GUI zu starten über
Thread t = new Thread(delegate() { MainWindow mw = new MainWindow (); mw.Show(); }); t.Start();
dann bekomme ich eine System.InvalidOperationException
-
Hmm .. ich kann nur mal vermuten, dass du versuchst ein WPF Window in einem WindowsService Kontext anzuzeigen!?!? Ich bin mir nich sicher ob das geht.. da du hiefür eine WPF Applikation brauchst...
Aber nur so ne Idee-
-
Er hat doch geschrieben dass das Service sein Programm mittels CreateProcessAsUser startet. Und dass er das WPF Fenster sieht, bloss kein Bild darin.
@PMGZED
Bist du ganz ganz sicher dass keine Exception geworfen wird?
Hast du ne Log-Ausgabe in einemfinally
versucht?
Wenn da nämlich keine Exception fliegt, und auch nix geloggt wird, dann müsste das Programm innew BitmapImage
hängen. Und dann müsste dein GUI Fensterli hängen. Und davon hast du ja nix geschrieben.
Also: vermutlich Exception.
-
Das Programm an sich stürzt nicht ab auch im Ereignisslog taucht auch nichts auf
das Programm funktioniert auch so ohne Probleme eben nur das die Bilder fehlen.Leider kenn ich mich mit WPF noch nicht so gut aus kann es sein das es bei WPF ein Thread gibt der sich um das laden der Bilder kümmert der eventuell nicht gestartet wird da das ganze aus den Systemaccount mit einen Benutzertoken heraus gestartet wird
das Problem scheint an WPF zu liegen ich habe ein neues "Projekt" erstellt und in die Zeile eingefügt
<Image Grid.Column="0" Grid.RowSpan="2" x:Name="icon" Margin="2" Source="http://www.golem.de/staticrl/images/logo-g.png" HorizontalAlignment="Left"/>
wenn ich das Programm dann mithilfe von psexec /i /s Programmname.exe
starte tritt der Fehler auf (https://technet.microsoft.com/de-de/sysinternals/bb897553.aspx)
psexec mit /i /s startet das angegebene Programm als Dienst/Systemaccount auf den Benutzerdesktop starte ich das Programm per Doppelklick funktioniert esMein Programm macht an sich das selbe wie psexec
Das Programm läuft als Dienst und wenn der Benutzer ein Information angezeigt bekommen soll wird vom Dienst in der Benutzersitzung ein WPF Programm gestartet was die Info ausgibt
Ich hole mir mit WTSQueryUserToken den Benutzertoken und starte das Programm dann mithilfe von CreateProcessAsUserEine variante womit es funktioniert hat
byte[] fileBytes = new byte[1]; using (WebClient wc = new WebClient()) { try { fileBytes = wc.DownloadData(url); } catch { return new BitmapImage(); } } MemoryStream memoryStream = new MemoryStream(fileBytes); BitmapImage ret = new BitmapImage(); ret.BeginInit(); ret.StreamSource = memoryStream; ret.CacheOption = BitmapCacheOption.OnLoad; ret.EndInit(); ret.Freeze(); return ret;
aber die variante wo ich einfach ein Binding auf die URL des Bildes mache wäre mir lieber
-
Wird dir das Rumraten nicht langsam fad?
Bitte mach doch einfach in den Property-Getter nen try-catch rein und logge da drinnen auftretende Exceptions.
Oder debugge es gleich. Ist ja net schwer, einfach ne MessageBox vor dem Start des eigentlichen Programms anzeigen, und während diese angezeigt wird mit dem Debugger draufhängen.
Dann so einstellen dass er bei jeder geworfenen Exception sofort unterbricht (egal ob sie gefangen wird oder nicht), dann die MessageBox wegklicken und gucken was passiert.Ist wirklich nicht so schwer, und wird dir vermutlich viel mehr verraten als irgendwie irgendwas rumzuraten und rumzubasteln.
-
Hi hustbaer, hi NullBockException
Danke für eure GeduldIch habe das jetzt mit
public BitmapImage IMAGE { get { global_program_information.LOG.add_warning("Starte laden: "); BitmapImage ret = new BitmapImage(); try { ret = new BitmapImage(new Uri("http://www.golem.de/staticrl/images/logo-g.png", UriKind.Absolute)); } catch (Exception e) { global_program_information.LOG.add_warning("Fehler: " + e.ToString()); } finally { global_program_information.LOG.add_warning("Fertig"); } return ret; } }
und es kommt die exception
Fehler: System.Runtime.InteropServices.COMException (0x80070078): Diese Funktion wird vom System nicht unterstützt. (Ausnahme von HRESULT: 0x80070078) bei System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) bei System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode) bei MS.Win32.WinInet.get_InternetCacheFolder() bei System.Windows.Media.Imaging.BitmapDownload.BeginDownload(BitmapDecoder decoder, Uri uri, RequestCachePolicy uriCachePolicy, Stream stream) bei System.Windows.Media.Imaging.LateBoundBitmapDecoder..ctor(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy requestCachePolicy) bei System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache) bei System.Windows.Media.Imaging.BitmapImage.FinalizeCreation() bei System.Windows.Media.Imaging.BitmapImage.EndInit() bei System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource, RequestCachePolicy uriCachePolicy) bei System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource)
-
Hallo
laut dem ersten Link im Nachfolgenden Eintrag sollte es helfen, wenn du das Bild auf die Root des Webservers legst:
Mfg Marco
-
Hm.
Also irgendwas geht beim Starten deines Prozesses gröber daneben. Bist du sicher dass der Prozess unter dem Account des eingeloggten Users läuft? Ich beginne schön langsam zu vermuten dass NullBockException recht hat, und du versuchst das Ding mit dem Service-User laufen zu lassen. Was nicht hinhauen wird. Es geht zwar sehr sehr viel wenn man alsSYSTEM/NetworkService/...
läuft, aber eben nicht alles.Denn...
Wenn du dir
MS.Win32.WinInet.get_InternetCacheFolder
mit dem IL Disassembler/Decompiler deiner Wahl anguckst, dann siehst du dass da drinnen bloss eine Funktion aufgerufen wird, und zwarGetUrlCacheConfigInfo
.
Der Fehlercode dieser Funktion wird dann in einHRESULT
eingewickelt, und damit die Exception geworfen.
DerHRESULT
Code ist wie wir sehen können0x80070078
. Wickeln wir den Win32 Error Code wieder aus, dann bekommen wir0x78
aka.120
aka.ERROR_CALL_NOT_IMPLEMENTED
.Und wenn wir uns die MSDN Seite zu
GetUrlCacheConfigInfo
angucken...
https://msdn.microsoft.com/en-us/library/windows/desktop/cc817578(v=vs.85).aspx
...dann steht daNote WinINet does not support server implementations. In addition, it should not be used from a service. For server implementations or services use Microsoft Windows HTTP Services (WinHTTP).
Bevor du nen Workaround baust, nur um dann gleich über die nächste Sache zu stolpern die nicht funktioniert weil du nicht mit einem normalen Userkonto läufst, würde ich empfehlen das Starten deines GUI Prozesses umzuschreiben. So dass er mit dem eingeloggten Userkonto läuft.
Dazu brauchst du vermutlich einen Hilfsprozess, den du per Autostart starten lässt. Zumindest ist (bzw. war) das die übliche Art es zu machen.ps
add_warning("Fehler: " +
-
ps2:
Ich bin allerdings nicht sicher was hier mit "server implementations" gemeint ist. Server Windowse sind sicher nicht gemeint. Aber was dann?
-
Laut Taskmanager stimmt der Benutzer und die SitzungsID
Aber OK an sich war das ganze Thema ganz intersannt aber ich denke ich werde es dann doch so wie MS den Standardweg vorgibt über den Regestryautostart-Key erledigen.Ich danke euch für die gute Unterstützung
-
Was genau hast Du den vor? Du willst eine UI für deinen Service oder? Wenn Ja:
Dann bau dir ein WCF Service in deinen Win-Service, und eine UI Host mit der du dich auf den Service verbinden kannst!
Wenn nein: Vergiss den letzen Absatz;)=