Laden...
J
Jelly myCSharp.de - Member
Burden (Luxemburg) Dabei seit 09.09.2007 1.114 Beiträge
Benutzerbeschreibung

Forenbeiträge von Jelly Ingesamt 1.114 Beiträge

27.06.2014 - 12:41 Uhr

Es gibt 2 Arten von Shortcuts: Advertised und Non-Advertised. Und Advertised Shortcuts kann man nicht ändern. Daneben haben solche Shortcuts auch noch den nachteil, dass beim ersten Start vom User nochmals das MSI Paket gebraucht wird. Der User hat aber nicht in allen Fällen Zugriff darauf, und kann somit das Programm noch nicht einmal starten.

Warum Microsoft diesen Weg wählt, weiss ich auch nicht.

Abhilfe jedoch schafft, das MSI kurz mit zB dem Orca Tool ze bearbeiten, und dann in der Property Tabelle den Werten DISABLEADVTSHORTCUTS auf 1 zu setzen.

30.05.2014 - 10:44 Uhr

Hast du dir schon Advanced Installer angeschaut. Die Free Edition unterstützt die Installation vom SQL Server zwar nicht, aber ab der Professional aber dann schon.

22.12.2013 - 12:52 Uhr

auf Knopfdruck wird dann etwas berechnet.

Geht das etwas genauer? Was berechnest du gerne genau. Inwiefern stehen Wohnung 1 + 2 mit dem von dir vorgesehenen Kostenfelder zusammer. Wasserverbrauch, Gas usw. sind doch sicherlich wohnungsabhängig. Da kannst doch, nach meinem Verständnis, dafür nicht ein gemeinsames Feld verwenden.

Aber generell würde ich mir eine Kosten-Klasse bauen, mit den Eigenschaften Name, Cost und Interval. Hast du dann mehrere Kosten (wie Gas, Wasser etc.), einfach nur mehrere Instanzen der Kostenklasse in einer Liste ablegen.

Daneben gäbe es eine Wohnung Klasse mit Name, Personen, Fläche, und eben einer List<Kosten> Referenz.

Speichern kanns du z.B. einfach die Wohnung Klasse indem du sie serialisierst. Kuck dir hierzu mal die generische XmlSerializer Klasse an.

Berechnungen würde ich komplett in einer getrennten Klasse auslageren, die als Parameter wahrscheinlich die Wohnung Klasse benötigen wird.

01.03.2013 - 17:38 Uhr

Einfach mal nach "Project Tracking Software/Systems" suchen. Einige Kandidaten wären z.B. Jira...

Jira nutze ich beruflich und sogar auch privat daheim. Für Teams bis zu 10 Leuten kostet das Ganze 10$. Dazu gibt es noch ganz gute Plugins (Greenhopper z.B. für agiles Programmieren)...

Werden es mehr als 10 Leute wird das Ganze allerdings richtig teuer.

Atlassian Jira

16.09.2011 - 20:11 Uhr

Kannst eventuell mal bei http://www.clickatell.com kucken.

03.03.2011 - 09:06 Uhr

Vielleicht zu spät, aber hier noch ein Vorschlag von mir.

Wie wäre es mit der ganzen Binding Sache unter .NET. Gerade so Dinge wie INotifyPropertyChanged Interface können in Verbindung mit den GUI Komponenten schon ziemlich cool rüber kommen.

09.02.2011 - 16:47 Uhr

Es gibt auch virtuelle Imageprinter. Die kannst du als normale Drucker ansteuern, und erstellen dir dann Bilddateien für jede einzelne Seite. Das über Code sauber anzusteuern ist aber sicherlich auch nicht ganz optimal. Aber als Idee wollte ich es aber trotzdem mal in den Raum stellen.

09.02.2011 - 13:30 Uhr

Eventuell ein gutes Wiki. Wir nutzen Confluence von Atlassian. Imho ziemlich cooles Stück Software.

10.01.2011 - 19:01 Uhr

Hallo Maximilian,

ups, mein Fehler. Die requestElevation Eigenschaft ist natürlich das Flag, das zu setzen gilt 8)

Kannst dir ein Bier bestellen und mir die Rechnung schicken 😄

06.01.2011 - 18:32 Uhr

@Knick,

warum nennst du hier unterschiedliche DBMS. Das war doch gar nicht die Frage und hilft somit kein wenig weiter. ?(

06.01.2011 - 07:57 Uhr
  1. Der Kollege mit dem ich telefoniert habe, hat gemeint es würden noch Lizenkosten von 17.000€ kommen.

Da hat dein Kolleger dann aber sicherlich von der Enterprise Version gesprochen. Die sollte eigentlich in den meisten Fällen ein absoluter Overkill sein. Denn um da die Performance rauszuziehen (Clustering etc).) wird auch nochmal eine ebenso teure Hardware vorrausgetzt. Es bringt auch nichts, ein Formel 1 Motor in einen Käfer zu stecken. Da kannst du das Potential nicht ausschöpfen.

Kuck dir unbedingt den Link von Talla an, dort findest du eigentlich alles was man braucht aus erster Hand.

Wie umfangreich ist denn eigentlich deine Software. Von welchem Datenvolumen ist die Rede, wieviele Tabelle ungefähr und für wieviele User ist sie gedacht. Wieviele simultane Zugriffe unterschiedlicher User sind zu erwarten?

29.12.2010 - 14:41 Uhr

Hi Maximilian,

kann es sein, dass in der Beta Version ein Setzen des Flags

updateController1.processSafetyLevel = updateSystemDotNet.processSafetyLevel.AskNever;

keine Auswirkungen mehr hat. Jedenfalls poppt bei mir trotzdem das Windows Fenster auf, um das Update mit Admin Rechten auszuführen. Ich möchte das eigentlich unterbinden.

07.12.2010 - 09:29 Uhr

Das liegt am IIS. Die Probleme hatte ich auch mit klassischen Webservices, und hab die eigentlich immer noch. Das Hochsetzen des Timeouts im IIS hat rein gar nichts bewirkt. Wenn 20 Minuten lang keine Anfrage an den Service kam, hat IIS die Instanz gekillt. Der nächste Client hatte dann Pech und musste 20 Sekunden warten. Ich wusste mir wirklich nicht mehr weiter, und habe letztlich einen blöden Dummy Windows Service laufen, der alle 30 Sekunden eine leere Methode im Webservice aufruft. Dadurch wurde der IIS dann gehindert, nach 20 Minuten die Instanz zu killen.

Das war IIS 6. Wie sich das heute beim IIS 7 verhält, weiss ich nicht.

Aber seitdem meide ich IIS zum Hosten meiner Services, und lagere sie selbst direkt in einem Windows Service ab. Läuft seitdem wesentlich flotter. Liegt aber eher am TCP/IP Binding des WCF Service.

Diese Timeout Geschichte beim IIS kann ich sowieso nicht nachvollziehen. Wenn ich einen Dienst starte, ob IIS oder sonst einer, erwarte ich dass er verfügbar ist, und nicht erst alles neu vorkompiliert werden muss beim ersten Aufruf, nur um serverseitig ein paar Resource zu sparen.

12.11.2010 - 09:28 Uhr

Yes... Das Beispiel leuchtet ein. Das Modell erlaubt also nicht nur eine n:1 Beziehung zwischen Child und Parent, sondern eine n:m (mehrere Parents). Das kann in gewissen Situationen durchaus gefordert sein.

Danke für den Einblick.

11.11.2010 - 08:18 Uhr

Auch das Umbennen 😉
Triviales Beispiel: Ein Dateiname enthält einen (Rechtschreib-) Fehler und ein eifriger Mitarbeiter korrigiert das -> die DB wird aber nicht (automatisch) aktualisiert.

Eigentliche alle Operationen am offenen Herzen sind kritisch.
Wenn man wirklich viele solcher Dateien im Filesystem ablegt, tut man gut daran, auch eine Ordnerstruktur einzuführen. Ich hatte mal in der Vergangenheit meine Files einfach in ein Serververzeichnis gepackt. Damals ging es um tägliche Scans. Nach 6 Monaten lagen 50.000 Dateien im Verzeichnis rum. Das macht den Zugriff sicherlich nicht schneller. Also habe ich angefangen, ein Verzeichnis mit dem Jahr anzulegen und 12 Unterverzeichnisse für den Monat. Damit blieb das Ganze überschaubar und auch Backups gestalteten sich wesentlich schlanker... Aber wegen dieser neuen Verzeichnisstruktur kam es dann tatsächlich einmal vor, dass sich ein User kurz verklickt hat und einfach mal so mittels Drag and Drop ein Verzeichnis sonstwo verschoben hat.

Deshalb wiederhol ich mich gern: Operationen am offenen Herzen sind immer kritisch, und die sollte man vermeiden.

Und da ich Verfechter von 3-Tier bin (gfoidl sicher auch 😃 ), sollten Zugriffe von Clients nic direkt auf die DB erfolgen oder direkt Zugriff auf das Filesystem haben. Sicherheit kann man dann vergessen und es passieren so Dinge wie oben geschildert. Ausserdem kann ich nicht einfach mal so einen bestimmten Datensatz für eine Benutzer sperren. Auf DB Ebene geht das veilleicht noch, auf Fileebene wirds schon schwieriger.

Wenn also eine 3-Tier Architektur vorliegt, spielt es imho keine Rolle, wo die Blobdaten abgelegt sind, in der DB oder im FS. Erfolgt der Zugriff direkt vom Client auf die DB, würde ich vermutlich alles in die DB packen.

Wieviel Daten fallen denn so im Monat an, und wie gross sind die einzelnen Files durchschnittlich?

11.11.2010 - 07:56 Uhr

Hallo gfoidl,

danke für den Codeschnippsel. Mir waren die Parameter im DataContractSerializer nicht alle bekannt. So scheint es also zu klappen.

Aber ich frage mich eigentlich, wozu diese Id's im XML benötigt werden? Eigentlich geht doch schon aus der XML Struktur selbst hervor, wer der Parent ist! Ok, du hast die ganzen Child-Nodes nochmals in Children gruppiert, aber der Parent Node ist dem ganzen doch eigentlich übergeordnet.

10.11.2010 - 13:33 Uhr

der XmlSerializer unterstützt keine zyklischen Abhängigkeiten. Mit dem DataContractSerializer wäre das möglich. Falls du den verwenden kannst nimm diesen

Den könnte ich schon verwenden. So direkt ist mir da aber auch nicht bekannt, wie ich dort eine Parent Eigenschaft berücksichtigen kann?

Momentan nutze ich deinen letzten Vorschlag, d.h. nach der Deserialisierung iteriere ich durch meine Collections und setze entsprechend die Parent Eigenschaft. Das find ich aber unschön.

10.11.2010 - 11:08 Uhr

Ich habe ein XML File, mit 2-3 Tiefenebenen. Das Deserialisieren mach ich über die Serialzer Klasse. Das Ergebnis sind dann Klassen mit Unterklassen und Unterunterklassen. Das klappt wunderbar, ist ja auch nix weltberaubendes. Alles was ich brauchte ist eben meine Datenklassen so aufzubauen und mit den XmlAttributen zu versehen, dass das Deserialisieren eben passt (ein xsd Schema liegt mir nicht vor).

Ich habe aber nun das Problem, dass ich die Parent Klasse aus meiner Childklasser heraus brauche. XML Strukturen sind ja immer als Baum zu verstehen, d.h. abgesehen von Root Node haben alle Nodes auch immer einem Parent. Und aus dem Parent Node bräuchte ich aus meiner Childklasse eben die Parentinstanz.

Geht das irgendwie mit Bordmittel beim Deserialisieren oder was muss ich da tun? Ein geeignetes XmlAttribut habe ich dazu jedenfalls nicht gefunden.

09.11.2010 - 15:55 Uhr

Bernd hat dir doch einen Link mit allem Nötigen geschickt. Also wo genau liegt dein Problem. Du hast Connectionstring, du hast deinen Namespace System.Data.SqlClient mit allen nötigen Klassen, und ein Tutorial wie du auf die DB zugreifst. Einziger Unterschied ist, dass es sich um MSSQL und nicht um MySQL wie in Bernds Tutorial handelt.

08.11.2010 - 14:03 Uhr

Die TAN Idess ist gängig in gesicherten IT Systemen. Um sich einzuloggen, braucht man demnach 2 Dinge: Ein Login und Passwort (Wissen) und eine TAN Liste (Haben). Einzeln sind sie nicht zu gebrauchen. D.h. verliere ich meine Liste, kann ein Dritter damit alleine nichts anfangen. Erschnüffelt er mein Passwort (z.B. durch ein Hooktool o.ä.), fehlt ihm die TAN Liste. Das Prinzip des Wissens und Habens. Gänge Systeme, die genau diese Art an Sicherheit bieten sind z.B. Token geschützte VLAN Zugänge (siehe z.B. RSA, und Zertifikate im allgemeinen auch (Hier brauch ich al User mein Zertifikat (Haben) und mein Passwort um es zu nutzen (Wissen)).

Mit diesem Verfahren ist man alleine schon auf der sicheren Seite, dass sich kein Dritter als einen selbst ausgeben kann. Wenn ich mich in ein System einlogge mit meinem Login, Passwort und einmal gültigem TAN, so kann das Gegenüber schons sicher sein, dass es sich tatsächlich um mich handelt. Einzige Möglichkeit wäre den Datenstrom abzufangen, und gar nicht an den Server weiterzuleiten.

Deshalb sollte natürlich die gesamte Verbidnung idealerweise auch noch verschlüsselt sein. Das ist aber nicht in allen Anwendungsfällen überhaupt nötig.

08.11.2010 - 12:11 Uhr

Hängt von ab. Aber um deine User 100% zu authentifizieren, und auch die gesamte kommunikation zu verschlüssen, bleibt dir wohl nur ein Zertifikat übrig.

Wenn die Kommunikation selbst jedoch nicht verschlüsselt zu sein muss, dann gibt es auch andere Möglichkeiten. Passwörter würde ich natürlich nicht im Klartext übermitteln, aber ich dachte da eher an eine Art TAN Liste für deine User, d.h. eine Liste mit Code (z.B. Guids) die nur innerhalb einer Session ihre Gültigkeit haben und danach verfallen... Nur mal so als Idee um dem Murks mit den Zertifikaten aus dem Weg zu gehen.

08.11.2010 - 11:56 Uhr

Für wen soll der Service denn erreichbar sein. Internet oder nur intern. Wenn nur intern, kannst du nicht über Active Directory deine Anwender authentifizieren?

Falls Internet, so besteht der einzige sichere Weg über Zertifikate. Das zu implementieren ist in der Tat nicht trivial. Da hab ich mich ebenfalls schon einmal rangewagt und habs dann irgendwann aufgegeben.

29.10.2010 - 08:20 Uhr

Ich würde eine Installer Klasse in mein Projekt einfügen, dess Aktion beim Installieren des Setups durchgeführt wird. Den gleichen Code kannst du theoretisch auch nutzen, um später aus deinem Programm heraus dein Dialog nochmals aufzurufen.

Aber Vorsicht: Silent Installationen werden somit nicht mehr komplett im Hintergrund durchgeführt.

29.10.2010 - 07:59 Uhr

lag wohl wirklich daran, das FTP und HTTP getrennt waren. Ist mir nicht klar gewesen. Vielleicht könntest du ja in dem neuen Update da irgendwie drauf hinweisen, um dem nächsten User so eine Plackerei zu ersparen

Ich denke, das sollte eigentlich jedem klar sein, oder?
Wenn ich es per FTP irgendwo hochlade, und später über HTTP darauf zugreife, ist doch aber wohl klar dass das nur gehen kann, wenn du auf den gleichen Path auf dem gleichen Server verweist.

29.10.2010 - 07:55 Uhr

Danke für das Zitat.

Wichtig zu wissen ist es allemal.

Wie ich das sehe gibt es also 3 Möglichkeiten wann ein OnWay Aufruf trotzdem blockieren kann:[1.]Verbindung zum Client kann nicht hergestellt werden
[2.]Zu grosse Objekte werden zum Client verschickt
[3.]Der Server kann irgendwelche Informationen nicht schnell genug lesen

zu 1.:
Die Verbindung sollte eigentlich stehen, es sei denn es gab mal einen Netzwerkaussetzer o.ä. Das kann natürlich immer mal passieren.

zu 2.: Da ich eigentlich den Client vom Server nur anstupse um ihm mitzuteilen, da ist was das dich interessiert, kann das bei meinen Fällen nicht eintreten

zu 3.: Auch das tritt nicht ein, da ja lediglich ein besseres Ping zum Client geschickt wird.

Punkt 1. kann aber allerdings in der Tat zu einem Problem führen.

28.10.2010 - 16:45 Uhr

Dauert das Enqueue zu lange könnte auch ein Timeout auftreten - aber ich denke das ist i.d.R. sehr selten.

Kannst du mir ein Scenario schildern, bei dem ein Enqueue Probleme macht. Ich hatte zumindest noch keine negativen Erfahrungen damit.

28.10.2010 - 15:43 Uhr

Um diesem Problem aus dem Weg zu gehen sind Operationen in meinen Callback Verträge immer mit dem IsOneWay Attribut versehen. Dadurch funktioniert der Server nach dem Prinzip "Fire and Forget". Timeouts treten somit in meinen nicht auf.

28.10.2010 - 15:33 Uhr
Application.OpenForms;

ist wohl das was du suchst.

28.10.2010 - 15:31 Uhr

Stimmt, so gesehen natürlich völlig nachvollziehbar.

Meine Signatur besagt also letztlich nur, dass ich die Software signiert habe, und sie so dem Kunden gegeben habe. Ein anderer kann ja meine Signatur nicht anhängen, dazu fehlt ihm der private Key und das zugehörige Passwort.

Ich hatte da wohl einen Querdenker 😁
Danke für die Aufklärung

28.10.2010 - 15:06 Uhr

Ich hab da mal eine Konzeptfrage.

Ich besitze ein Class 2 Zertifikat zum Signieren von EXE, DLL und MSI. Damit ist also der Ursprung der Software beim Kunden als glaubwürdig eingestuft.

Mir ist jetzt aber aufgefallen, dass ich mit meinem Zertifikat nun jede andere bereits VON MIR NICHT signierte Anwendung, also fremde Anwendung, diese Signatur durch die meinige ersetzen kann.

Das kann mir vielleicht mal einer erklären. Somit kann ich doch Software als meine vorgaukeln, obwohl sie gar nicht von mir ist.

Das kann doch aber nicht Sinn und Zweck von digitalen Codesignaturen sein?

27.10.2010 - 16:31 Uhr

Dies hat bei uns an der Schule auch immer funktioniert, obwohl wir Schüler keine Admin-Rechte hatten.

Dann hattest du eventuell lokale Adminrechte, oder die Kiste war einfach zu offen konfiguriert.

Unter XP und später sollte ein normaler Benutzer nicht so ohne weiteres in der Lage sein, irgendein Dienst unter dem System Konto abzuschiessen.

27.10.2010 - 13:07 Uhr

Wobei werden die Rechte angefordert? Ist es deine Anwendung oder nur das Setup an sich?

26.10.2010 - 08:03 Uhr

Ich bin leider noch in VS2008 unter .NET 3.5 unterwegs 😦
Aber das wär ein Argument ein Upgrade in Betracht zu ziehen.

26.10.2010 - 00:11 Uhr

In WCF hab ich es noch gar nicht implementiert.

Meine Frage habe ich deshalb so gestellt, weil ich diese Antwort von dir erahnte.

Wie gfoidl schon schreibt, würd ich mir erstmal nicht allzu sehr Gedanken darüber machen, ob denn WCF in der Lage ist, für deinen Fall 10 (oder auch 50) Clients zu handeln. Es ist natürlich immer eine Frage des Umfangs deines WCF, aber in der Regel sollte die Performance ausreichen.

Und gleich mal ein Stichwort vorweg, bevor du irgendwann an Probleme stösst, wie du die Kommunikation vom Server zum Client herstellst: sowas geht unter WCF mit Callback Verträgen. Ist im Grunde genau das Gegenstück zu dem, was du jetzt schon über WCF kennst, denn hier übernehmen deine Clients die Rolle des Servers, und der wirkliche Server kann somit dessen Methoden jeweils aufrufen. Er muss dafür nur eine Liste der verbundenen Clients verwalten.

Die meiste Arbeit liegt in der Konfiguration bei WCF. Die Implementierung ist eigentlich immer relativ leicht und genial zugleich.

25.10.2010 - 13:42 Uhr

Ich teile die Überlegung von gfoidl.

Ich packe immer alle Methoden des ServiceContract in eine Wrappe Klasse für den Client. Diese Klasse ruft die eigentlichen Methoden am WCF auf. Ich kapsle clientseitig alle Aufrufe wie folgt:

protected void ExecuteChannelCommand(Action command)
{
    try
    {
        if (BeforeCommandExecute != null)
        {
            CancelEventArgs e = new CancelEventArgs();
            BeforeCommandExecute(this, e);
            if (e.Cancel)
                return;
        }

        stopwatch.Reset();
        stopwatch.Start();

        if (channel == null)
            Connect();

        try
        {
            command();
        }
        catch (CommunicationObjectFaultedException)
        {
            try
            {
                ConnectionStatus = ConnectionStatus.Disconnected;
                Connect();
                command();
            }
            catch
            {
                ConnectionStatus = ConnectionStatus.Error;
                throw;
            }
        }
        finally
        {
            stopwatch.Stop();
            if (CommandExecuted != null)
                CommandExecuted(this, new CommandExecutedEventArgs(stopwatch));
        }
    }
    finally
    {
        if (FinallyCommandExecute != null)
            FinallyCommandExecute(this, EventArgs.Empty);
    }
}

Ein Aufruf in einer konkrete Wrapper Methode sähge dann so z.B. aus:

public Int64 NewTransactionId()
{
        Int64 res = 0;

        ExecuteChannelCommand(() =>
        {
            res = Channel.NewTransactionId();
        });

        return res;
}

Die Methode im Contract heisst NewTransactionId().

Bei diesem Aufruf wird gegebenfalls eine neue Connection zum Host aufgebaut, falls die alte nicht mehr exsitiert.

Darüber hinaus habe ich noch Events definiert, so dass ich vom Endclient heraus sogar noch andere Informationen aus einem Aufruf rausziehen kann (z.B. Dauer des Aufrufs).

Ich hoffe das hilft

25.10.2010 - 13:34 Uhr

Der Client sendet Daten an den Server, der Server teilt anderen angemeldeten Clients diese Daten mit?

Läuft jede Session dann in einem eigenen Thread?

Wie hast du denn die Kommunikation Server zum Client implementiert?

25.10.2010 - 08:02 Uhr

Eben nicht. Wenn du dein Service so definierst, wie Pico es vorgeschlagen hast, bist du zwar komplette im Multithreading unterwegs, aber die Synchronisation liegt unter deiner Verantwortung. Das liegt insbesondere an seinem InstanceContextMode.Single.

Ich tendiere in den meisten Fällen zu InstanceContextMode.PerSession. Somit läuft jeder deiner Clients in einem eigenen Context, und kommt sich somit nicht mit den anderen Clients in die Quere.

Der ConcurrencyMode.Multiple gibt an, dass für eine Session mehrere Threads auf die Session zugreifen darf. Auch hier muss du, wenn du also clientseitig mit Threads arbeitest, selber aufpassen. Du kriegst zwar keinen Huddel mit den Nachbarn, aber eventuell mit dir selbst. Genau das wird verhindert durch ConcurrencyMode.Single, was auch die Defaulteinstellung ist. Erhält der Server von einem Client 2 parallele Aufrufe, so wird durch ein internes Lock Mechanismus dafür gesorgt, dass die beiden Aufrufe schön nacheinander durchgeführt werden.

Pico's Vorschlag kann Vorteile mit sich bringen. Aber in meiner bisherigen Erfahrung hat mir die interne Synchronisationsverwaltung von WCF (PerSession, Single) immer völlig gereicht.

14.10.2010 - 09:54 Uhr

Process.WaitForExit an (in einem separaten Thread).

WaitForExit blockiert dir die Gui, was unschön ist. Und wenn du den Prozess in einem separatem Thread startest, wie vorgeschlagen, bleibt dein Gui erreichbar, und der User kann weiterhin Aktionen darauf ausführen.

Aber die Process Klasse besitzt ein schönes Event, das abonniert werden kann, und das beim Start und Beenden des startenden Prozess gefeuert wird. Also einfach im OnStart die Form z.B. disablen, und wieder enabled wenn der Fremdprozess beendet ist.

Das wäre zumindest mein Vorschlag.

12.10.2010 - 11:30 Uhr

Ich sehe das genauso wie Herbivore. Halte dir die Flexibilität, gerade bei so Systemen die später in unterschiedlichen Anwendungen zum Einsatz kommen werden.

12.10.2010 - 08:00 Uhr

Die Überprüfung MUSS imho im BL stattfinden. Wenn der Check lediglich im Gui gemacht wird, kann man trotzdem, z.B. über eine eigene Gui, die Funktionen im BL aufrufen. Wenn ich also verhindern will, dass jemand die Methode SaveArticle() aus dem BL aufruft, dann muss das auch in dieser Methode geprüft werden.

Und richtige Sicherheit erzielt man so, wenn BL und Gui physikalisch getrennt sind, und sich der BL in einer Middleware befindet. In dem Fall hat der Anwender null Chancen, trotzdem an die SaveArticle() Methode zu gelangen.

Und die Überprüfung SOLL ebenfalls, aus Benutzerfreundlichkeit, im Gui stattfinden, um eben direkt entsprechente Gui Element zu disablen oder auszublenden.

Ich nutze hier ein eigenes UserManagment, das ich immer in all mein BL nutze, die ich wiederrum in einer Middleware hoste, und meine Clients über WCF anbinde.

Im BL gibt es dann eine Methode EnsurePolicy(string name). Die überprüft, ob der Client Rechte hat, und schmeisst eine Exception wenn dies nicht der Fall ist. In jedem OperationContract meines WCF steht dann in der ersten Zeile ein Aufruf von EnsurePolicy().

Weiter biete im Contract die Methode CheckPolicy(string name) an, über die der Client GUI-seitig prüfen kann, ob er das Recht besitzt, eine Methode im BL aufzurufen oder nicht.

CheckPolicy wird im BL durch ein CheckPolicy in meinem Usermanagement System durchgeführt.

Mit dieser Logik habe ich eigentlich bislang ganz gute Erfahrungen gemacht. Ein geeignetes Usermanagement System ist dafür natürlich auch Vorraussetzung.

05.10.2010 - 13:56 Uhr

Probiers mal mit

DBNull.Value;
28.09.2010 - 10:31 Uhr

Vereben ja, aber nicht bis zum Exzess.
Wenn A von B ableitet, dann muss man immer den Satz "A ist B" widerspruchslos formulieren können. Ein üblich genanntes Beispiel: Du kanns einen Klasse Quadrat von Rechteck ableiten, da die Formulierung "Quadrat is ein Rechteck" Sinn macht. Wenn du jetzt aber denkst, Quader könntest man von Quadrat ableiten (ist ja irgendwie auch was qadratisches), so stimmt die Aussage "Quader ist ein Quadrat" nicht mehr.

In solchen Fällen gibt es andere Beziehungen, die durchaus mehr Sinn machen und wesentlich flexibler sind. In diesem Zusammenhang seien Design Patterns genannt. Eine recht gute Einführung findest du z.B. hier

Vielleicht kannst du mal namentlich deine 7 Klassen schreiben, daraus kann man eventuell schon was ableiten.

07.09.2010 - 08:25 Uhr

Das hat den Vorteil, das man nicht wie wild umher casten muss. Man muss nur wissen, in welcher Spalte was liegt.

Der Vorteil liegt ja nicht nur dabei, dass man sich das Casten spart. Man fängt sich ja dafür die Problematik ein, dass man halt wissen muss, über welche Spalte man filtert. Der Programmieraufwand wird dadurch natürlich nicht geringer.

ABER: Wenn nicht gecastet wird, dann greifen auch die Indizes über die Spalten. Wenn nur 100 Record in der Tabelle, mag das irrelevant sein. Bei grösseren Tabellen stösst man so aber sehr schnell an Performanceprobleme da immer ein Fulltable Scan durchgeführt werden muss.

Als Grundsatz sollte man immer berücksichtigen, dass ein Cast in einer Where Clause immer eine schlechte Idee ist. Besser geeignete Datentypen wählen.

06.09.2010 - 15:41 Uhr

Warum legst du gerne 3 Datentypen in einem einizigen Feld ab. Mach 3 Spalten draus: int, DateTime und varchar, und setze die entsprechende Bedingung.

Beim Casten greift kein Index mehr, d.h. früher oder später wird das Ganz arschlahm. Davon abgesehen kannst du bei einem varchar(MAX) sowieso kein Index legen...

26.08.2010 - 10:57 Uhr

Auf Anhieb nicht, aber die MSDN sollte zu ProcessIdToSessionId mehr liefern.

26.08.2010 - 08:01 Uhr

Hiermit kannst du feststellen, ob ein Prozess unter dem lokal angemeldeten User läuft, oder unter einer Terminalsession wie Citrix oder mstsc.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

    public class TerminalSession
    {
        [DllImport("kernel32.dll")]
        private static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId);

        private Process process;
        public Process Process
        {
            get
            {
                return process;
            }
        }

        public TerminalSession(Int32 processId)
        {
            this.process = Process.GetProcessById(processId);
        }

        public TerminalSession()
        {
            this.process = Process.GetCurrentProcess();
        }

        public TerminalSession(Process process)
        {
            this.process = process;
        }

        public SessionMode SessionMode
        {
            get
            {
                uint pSessionId = 0;
                bool ok = ProcessIdToSessionId((uint)Process.Id, out pSessionId);
                if (!ok)
                    throw new COMException("Error in Kernel32.dll call to ProcessIdToSessionId Function");

                if (pSessionId == 0)
                    return SessionMode.Local;
                else
                    return SessionMode.Terminal;
            }
        }
    }


    public enum SessionMode { Local, Terminal }


20.08.2010 - 14:00 Uhr

Hallo,

das sieht schon echt Klasse aus 👍. Vielen Dank schon mal für den Quellcode. Ich werde das Ganze noch sauber in eine Klasse packen, eventuell par Dinge anpassen (wie Einrückung) und dann wieder hier reinstellen.

20.08.2010 - 08:50 Uhr

Ich hab mir echt einen agegoogelt, aber jetzt stell ich die Frage hier.

Es eigentlich so trivial, dass es sowas schon längst gibt, aber wie gesagt, ich fand nix.

Ich muss eigentlich nur einen bestehenden xml Code so umformatieren, dass die Syntax sauber in HTML dargestellt wird, mit Einrückungen usw, eigentlich so wie der Internet Explorer selbst auch ein xml File darstellt.

Hat da wer einen Link zu. Das Ganze soll natürlich gekapselt in einer Klasse ablaufen, mit xml als Input, und mein Html Code als Output, das ich dann für eine html-Mail einfügen möchte.

17.08.2010 - 15:12 Uhr

Ich will ja gerade nicht das der Dienst interaktiv ist. Jedoch schmiert mir PS weg wenn ich das verweigere.

Es kann durchaus sein, dass Photoshop an sich jedoch zwingend einen Desktop benötigt.

16.08.2010 - 19:19 Uhr

Dein Projekt ist in der Tat sehr interessant, und ähnelt in der Vorgehensweise in gewissen Punkten meinen Ideen. Irgendwie gibt es halt für Problemstellungen meist keine 100 unterschiedliche Lösungen. Abweichungen zu deinem Konzept gibt es bei dennoch einige, die ich nicht vorenthalten will... Vielleicht hilft es dir ja auch an einigen Stellen.

Dabei ist aber bei meinem Projekt zu erwähnen, dass es sich bei mir ausschliesslich um zentrale Softwaredistribution in Windows Active Directory Domänen gehen soll, und dabei in der Regel nicht um Standardsoftware sondern um hauseigene. Insbesondere sollen bei mir die Updates an den Clients gewährleistet sein.

Parallelen:*Speichern der Pakete in einer Datenbank *Einheitliche Bedienung für alle Installationen *Windows Dienst am Client der die Installation durchführt

Abweichungen bzw. weitere Funktionen:*Kein Webcrawler, sondern ein WCF Client der sich mit dem Server verbunden hält, und über Callbacks benachrichtigt werden kann *Es lassen sich nicht nur Installationen durchführen, sondern auch direkt andere Aktionen durchführen (FileCopy,RegistryEinträge, Eventlog Einträge... um nur ein paar zu nennen). Somit sind theoretisch auch Installationen möglich ohne eigenes Setup (was bei uns teilweise der Fall ist) *Die genannten Operationen müssen sich sowohl Hostspezifisch und Userspezifich durchführen. Einige Operationen müssen nun mal im Kontext des eingeloggten Benutzers ablaufen. Diese Operationen dürfen natürlich keine Admin Rechte benötigen *Zentrale Installationen an angeschlossenen Clients nach bestimmten Kriterien. nicht jede Software soll auf jedem Rechner zur Verfügung stehen *Serverseitig getriggerte Installationen im Background an den Clients *Clientseitige manuelle Installation durch einfache Auswahl der Sofwtare aus der ihm zur Verfügung stehenden Liste. Die Installation soll auch durch normale User durchgeführt werden können. Ich möchte diese Funktionalität als Art "Software Shop" anbieten *Patchverteilung um Netzlast zu minimieren. somit werden nur Dateien aktualisiert, die geändert haben bei einem Update.

Nur bin ich leider z.Z. erst beim Konzept. Die verschieden Schichten sind definiert, aber noch nicht implementiert. Ich komm einfach nicht in die Gänge das Ganze zu realisieren bedingt durch Zeitmangel hauptsächlich. Aber vielleicht sind noch ein paar interessante Punkte dabei, an denen du eventuel auch interessiert bist.