Laden...

Forenbeiträge von Alf Ator Ingesamt 764 Beiträge

17.08.2011 - 11:00 Uhr

Meine Lehre besteht aus 2 Jahren Schule (Wirtschaft und Informatik) und 2 Jahre Praktikum (Engineering).

Gleichzeitig, oder nacheinander?

15.08.2011 - 15:25 Uhr

Ok, dass erklärt einiges.

Also das Problem ist erstmal, dass ein Netzlaufwerk benutzerspezifisch gebunden wird. D.h. das es für den Windows-Dienst eh nicht sichtbar ist und er dementsprechend nicht drauf zugreifen kann.
Dein Dienst muss also per UNC-Pfad zugreifen. Auf die Freigabe zugreifen kann der Dienst mittels 'WNetAddConnection2'. Damit kannst du dann auch direkt den entprechenden Benutzer mit angeben.

Hier ist ein entsprechender Thread dazu: Zugriff auf Netzwerk Folder per Service

15.08.2011 - 13:25 Uhr

Also änder doch mal den Pfad auf deine Datei testweise auf eine lokale Datei. Wenn das geht, dann hat dein Program logischerweise keinen Zugriff auf das Netzlaufwerk.
Ist dein Program denn ein Windows-Dienst? Ich lass hier auch nochmal das Stichwort 'WNetAddConnection2' fallen.

15.08.2011 - 11:17 Uhr

Mit den wenigen Infos kann ich leider nur raten. Ich rate mal: Dein Program läuft unter einem anderem Benutzerkontext.

12.08.2011 - 10:37 Uhr

Also der Weg per IXmlSerializable könnte etwa so funktionieren. Da müsste dann noch das ganze Serialisieren händisch gemacht werden. Vielleicht geht es aber auch automatisch.


static void Main(string[] args)
{
    Person p = new Person();
    p.Name = "Alf";
    p.Alter = 31;
    p.TestVar = "test";

    XmlSerializer<Person>.Serialize(p, @"c:\data.xml");
}

public class Person : AlfSerialzer //: MsSer.IXmlSerializable 
{
    [XmlAllow]
    public string Name { get; set; }
    [XmlAllow]
    public int Alter { get; set; }
    public string TestVar { get; set; }
}

public class AlfSerialzer : IXmlSerializable
{

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        //...
    }

    public void WriteXml(XmlWriter writer)
    {
        System.Reflection.PropertyInfo[] pis = typeof(Person).GetProperties();
        foreach (System.Reflection.PropertyInfo pi in pis)
        {
            var x = pi.GetCustomAttributes(typeof(XmlAllowAttribute), false);
            if (x.Length > 0)
            {
                if (x[0] is XmlAllowAttribute)
                {
                    writer.WriteStartElement(pi.Name);
                    writer.WriteString(pi.GetValue(this, null).ToString());
                    writer.WriteEndElement();
                }
            }
        }
    }
}

Übrigens ist das generische Serializieren, wie es der Zufall will, von gfoidl.

Der andere Weg über DataContractSerializer:


static void Main(string[] args)
{
    Person p = new Person();
    p.Name = "Alf";
    p.Alter = 31;
    p.TestVar = "test";

    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
    xmlWriterSettings.Indent = true;
    xmlWriterSettings.OmitXmlDeclaration = true;
    XmlWriter w = XmlWriter.Create(@"c:\data.xml", xmlWriterSettings);
    DataContractSerializer ser = new DataContractSerializer(typeof(Person));
    ser.WriteObject(w, p);
    w.Close();
}

[DataContract]
public class Person
{
    [DataMember]
    public string Name { get; set; }
    public int Alter { get; set; }

    [DataMember]
    public string TestVar { get; set; }
}

Dafür muss dann immer System.Runtime.Serialization eingebunden werden um die Attribute bekannt zu machen.

11.08.2011 - 15:28 Uhr

Danke ihr beiden, ich werde mir beides anschauen und dann die Ergebnisse hier posten.

11.08.2011 - 14:31 Uhr

Hallo zusammen!

Ich möchte Objekte serialisieren. Dabei kann mich mit XmlIgnore bestimmte Properties auslassen.
Ich würde jetzt aber gerne den umgekehrten Weg gehen und dabei alle Properties, bis auf Markierte (XmlAllow?), auslassen. Die zu serialisierende Klasse könnte ich dann z.B. mit XmlIgnoreAll markieren.

Bevor ich mich an die Arbeit mache, wollte ich hier nochmal nachfragen, ob es sowas oder eine bessere Lösung schon gibt.

Grüße, Alf

Edit: Felder -> Properties

11.08.2011 - 13:21 Uhr

Hallo HerrOli,

mach eine neue Liste, und geh die alte mit foreach durch und fügst die Werte der neuen Liste hinzu. Für Basis21-24 machst du dir ne Variable, ob das schonmal da war. Wenn ja, dann soll der (zum Beispiel zweite Basis21) Wert nicht geadded werden.

Ein guter Ansatz zum Lösen solcher Probleme, ist es, sich mit Zettel und Stift hinzusetzen und das Problem händisch zu lösen. So wie man es auf dem Papier macht, kann es auch das Programm machen.

Gruß, Alf

10.08.2011 - 14:16 Uhr

Hallo Flohen,

ich vermute, dass bei dir GUI und Anwendungslogik nicht vernünftig voneinander getrennt sind. Suche im Forum und über google nach entsprechenden Stichworten.

Du solltest nur soviel Anzeigen, wie es sinnvoll ist. 2400 Nachrichten/sec kann kein Mensch nachvollziehen.

10.08.2011 - 13:57 Uhr

Das hatte ich mal so ausprobiert. Es traten aber einige Probleme auf:*die Haushälterin reagierte nicht ordnungsgemäß auf Befehle
der Befehl putze! mit Übergabe eines Putzlappens führe dazu, dass
dieser mir um die Ohren gehauen wurde

*ich muss gigantische Telefonrechnungen bezahlen *inzwischen muss ich die Kommandos der Haushälterin befolgen X(

10.08.2011 - 13:25 Uhr

Probier doch mal "user" anstatt "Benutzer".

09.08.2011 - 16:40 Uhr

Du könntest über das user-Verzeichnis gehen. Da müsstest du imho eh rein, um den Firefox zu konfigurieren.

09.08.2011 - 14:53 Uhr

Bei den Snippets kann man dann mit 'Tab' jeweils zum nächsten veränderlichen Wert des Snippets springen und das direkt überschreiben, ganz ohne markieren, klicken, auswählen etc. Ich benutz das gerne.

05.08.2011 - 12:47 Uhr

Es gibt auch jede Menge 'hübschere' TabControls. Z.B. bei CodeProject.

05.08.2011 - 09:28 Uhr

Ich fürchte eine andere (praktikable) Möglichkeit als die von winSharp93 vorgeschlagene wird es nicht geben.

03.08.2011 - 09:11 Uhr

Exceptions brauch ich an der Stelle nicht. Ich werde bei gfoidls Lösung bleiben. Wichtig war mir vor allem, zu verstehen, was es für Möglichkeiten gibt und wie diese funktionieren. 👍

01.08.2011 - 17:18 Uhr

Also ich will mich ja ein weiterbilden und Verstehen was es für Lösungen gibt, deswegen auch die Frage. Für mich war es erstmal schwierig zu verstehen, dass sich der ganze Klumbatsch auf eine kleine Zeile reduzieren lässt.
Auf jeden Fall sind jetzt erst mal alle Klarheiten beseitigt und ich hab einiges zum Lesen. Vielen Dank 😃

01.08.2011 - 16:20 Uhr

Über den Beitrag ValidationRules und Attribute zur Validierung bin ich auf System.ComponentModel.DataAnnotations gestoßen.

Musste ich natürlich gleich ausprobieren. Leider ist die Dokumentation etwas dürftig ausgefallen (oder ich bin einfach zu doof). Passende Tutorials etc für einen guten Überblick habe ich auch nicht gefunden. Viele benutzen wohl eines der zahlreichen anderen Validation Framworks.

Meine Frage: Habe ich das in folgendem Code richtig gemacht? Das erscheint mir halt doch reichlich umständlich.


string Test()
{
    Person p = new Person();
    string tmp = "vielzulangername";
    try
    {
        p.Name = tmp;
    }
    catch (ValidationException ex)
    {
        p.Name = tmp.Substring(0, 5);
        Console.WriteLine(ex.Message);
    }
    return p.Name;
}

class Person
{
    string name;

    [StringLength(5)]
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            Validator.ValidateProperty
                (
                    value, new ValidationContext(this, null, null)
                    {
                        MemberName = "Name"
                    }
                );
            name = value;
        }
    }
}

29.07.2011 - 14:44 Uhr

Hallo inflames2k,

es gibt eine Eigenschaft dafür, die musst du von true auf false setzen.

Bitte beachte [Hinweis] Wie poste ich richtig? Punkte 1.1 und 1.1.1

29.07.2011 - 11:23 Uhr

Hi,

beim starten erhalte ich folgende Fehlermeldung:


---------------------------
Fehler beim erstellen der Dateien.
---------------------------
System.IO.DirectoryNotFoundException: Ein Teil des Pfades "C:\Digital-Reports\Digitaler Ausbildungsbericht.Net\NHunspell.dll" konnte nicht gefunden werden.
   bei System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   bei System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   bei System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   bei System.IO.File.WriteAllBytes(String path, Byte[] bytes)
   bei å.Main()
---------------------------
OK   
---------------------------


Der korrekte Pfad ist aber:
C:\Programme\Digital-Reports\Digitaler Ausbildungsbericht.Net

EDIT: Windows XP auf neustem Stand. Direkt nach der Installation. Ich habe den Standard-Installationspfad verwendet.

28.07.2011 - 12:41 Uhr

[Edit: Komplett überarbeitet]
So, ich habe meinen Algorithmus nochmal verbessert. Ich schaffe es jetzt auf durchschnittlich unter 400 Versuche. Diesmal wirklich. 😁

Ich verwende einen Suchbaum der Schritt für Schritt aufgebaut wird. Dabei Teste ich für jeweils die Hälfte des Strings, wie oft jedes Zeichen vorkommt. Davon wieder jeweils die Hälfte, solange bis auf Stringlänge 1 jedes Zeichen zugeordnet ist.
Die Aufträge zum Durchsuchen eines Teilstrings werden in eine Queue gegeben. (Wen's intressiert: Stichwort Breitensuche).


public void FindString()
{
    string zeichensatz = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char z = '.';
    int length = 0;
    char[] result;
    Queue<StringObj> q = new Queue<StringObj>();
    Dictionary<char, int> zCount = new Dictionary<char, int>();

    string countString = "";
    while (stringHider.Ask(countString) < 0)
    {
        countString += z;
    }

    length = countString.Length;
    result = new String(z, length).ToCharArray();

    // Start vorbereiteun
    foreach (char a in zeichensatz) zCount.Add(a, stringHider.Ask(new String(a, length)));
    zCount = SortDict(zCount);
    Start(new StringObj(zCount, 0), ref z, ref length, result, q);

    // solange arbeiten, bis keine neuen Einträge in der Queue erscheinen.
    while (q.Count > 0) Start(q.Dequeue(), ref z, ref length, result, q);
}

public class StringObj
{
    public int i = 0;
    public int l = 0;
    public Dictionary<char, int> d;
    public StringObj(Dictionary<char, int> d, int i)
    {
        this.i = i;
        this.d = d;
        foreach (KeyValuePair<char, int> p in d) l += p.Value;
    }
}

Dictionary<char, int> SortDict(Dictionary<char, int> d)
{
    return (from item in d
            where item.Value > 0
            orderby item.Value descending
            select item).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) as Dictionary<char, int>;
}

string DictToString(Dictionary<char, int> d)
{
    string s = "";
    foreach (KeyValuePair<char, int> p in d) s += new String(p.Key, p.Value);
    return s;
}

public void Start(StringObj sobj, ref char z, ref int length, char[] result, Queue<StringObj> q)
{
    if (sobj.l > 1)
    {
        Dictionary<char, int> vorne = new Dictionary<char, int>();
        Dictionary<char, int> hinten = new Dictionary<char, int>(sobj.d);
        int iVorne = sobj.i;
        int iHinten = sobj.i + sobj.l / 2;

        char[] buildstring = new String(z, length).ToCharArray();

        foreach (KeyValuePair<char, int> p in sobj.d)
        {
            for (int i = iVorne; i < iHinten; i++) buildstring[i] = p.Key;
            vorne.Add(p.Key, stringHider.Ask(new String(buildstring)));
        }

        foreach (KeyValuePair<char, int> p in vorne)
        {
            hinten[p.Key] -= p.Value;
        }

        vorne = SortDict(vorne);
        hinten = SortDict(hinten);

        if (vorne.Count > 0) q.Enqueue(new StringObj(vorne, iVorne));
        if (hinten.Count > 0) q.Enqueue(new StringObj(hinten, iHinten));
    }
    if (sobj.l == 1)
    {
        foreach (KeyValuePair<char, int> p in sobj.d) result[sobj.i] = p.Key;
        if (!result.Contains(z))
        {
            if (stringHider.Ask(new String(result)) == -2)
            {
                q.Clear();
            }
        }
    }
}

PS:
Die gesuchten Strings sind bei jedem durchlauf gleich. Wenn man zufällige Strings verwendet, braucht mein Programm kurioserweise durchschnittlich mehr Versuche. (Genauso verhält es sich mit meinem anderen Algo)


int seed = DateTime.Now.Millisecond; 
if (value != null)
{
    foreach (char a in value)
    {
        seed += a;
    }
}
value = "";
...
Random r = new Random(seed);
...

27.07.2011 - 15:26 Uhr

Hallo Kroxus,

das hier: [FAQ] Kommunikation von 2 Forms sollte dir weiterhelfen. Ausserdem solltest du Überlegungen hinsichtlich 'Trennung der GUI von der Anwendungslogik' anstellen. Ich weiss ja nicht, in wie weit das bei deinem Programm schon der Fall ist.

Gruß, Alf

27.07.2011 - 14:12 Uhr

Mach ne Liste mit Referenzen, auf andere Fragen, an jede Frage.

26.07.2011 - 09:56 Uhr

Vielleicht denkst du doch nochmal übers Layout nach. Eine Möglichkeit wäre vielleicht auch eine DropDownBox zu verwenden.

25.07.2011 - 15:29 Uhr

Ich schaffs in ~1220 Versuchen, wer schafft weniger?

Edit:
Wie man sich nen Ast abbricht und dann liegts an ner Kleinigkeit.. Kopf -> Tisch.
Bin jetzt bei 675 mit einem optimierten naivem Ansatz. Ich denke, wer das überbieten will, muss einen Suchbaumalgo oder etwas in der Richtung verwenden.
Das hat mir aber einiges an Kopfzerbrechen bereitet und habs jetzt erstmal aufgegeben. Also viel Erfolg xD

Edit2:
Da nachgefragt wurde, poste ich jetzt auch mal meine Lösung. Dabei ist zu beachten, dass myUnderTakeR und Daniel B. vor mir ihren Code gepostet haben.
Ich ermittel zunächst die Länge des Strings, und dann, wie oft jedes Zeichen im String vorkommt. Mit den Vorraussetzungen verringert sich der Aufwand beträchtlich.


public void FindString()
{
    #region variables
    string zeichensatz = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string tmp = new String('a', 50);
    int length = 0;
    Dictionary<char, int> zCount = new Dictionary<char, int>();
    char[] tmpa;
    char[] tmpb;
    bool charFound;
    #endregion variables

    #region länge ermitteln
    while (stringHider.Ask(tmp) < 0)
    {
        tmp = tmp + "a";
        stringHider.Ask(tmp);
    }
    length = tmp.Length;
    #endregion länge ermitteln

    #region anzahl jedes zeichens ermitteln
    foreach (char a in zeichensatz)
    {
        zCount.Add(a, stringHider.Ask(new String(a, length)));
    }
    #endregion anzahl jedes zeichens ermitteln

    #region position jedes zeichens ermitteln
    tmpa = tmp.ToCharArray();
    tmpb = tmp.ToCharArray();
    for (int i = 0; i < length; i++)
    {
        charFound = false;
        foreach (char a in zeichensatz)
        {
            if (zCount[a] > 0)
            {
                tmpa[i] = a;
                if (stringHider.Ask(new String(tmpa)) == 1)
                {
                    tmpb[i] = a;
                    zCount[a]--;
                    charFound = true;
                }
                tmpa[i] = 'a';
                if (charFound) break;
            }
        }
    }
    #endregion position jedes zeichens ermitteln

    stringHider.Ask(new String(tmpb));
}

20.07.2011 - 16:40 Uhr

Du könntest immer nur den Teil einfärben, der angezeigt wird und/oder du startest einen Hintergrundprozess, der alles einfärbt.

20.07.2011 - 10:09 Uhr

Schliess beide Montore an einen Computer an und greife auf den anderen PC mit Remotedesktop, oder VNC, etc zu.

18.07.2011 - 14:25 Uhr

Also ich hab das mal getestet und kann den Fehler nicht reproduzieren.

14.07.2011 - 16:31 Uhr

Neue Aufgabe:

  • zwei MovingObjects erstellen (Ship & Asteroid)
  • ein 3. MovingObject erstellen, dass vom Schiff aus, den Asteroiden trifft
  • der vorgegebene Code darf beliebig verändert werden
  • Viel Spaß!

public class MovingObject
{
    public int x, y;    // Position
    public int r;       // Radius
    public int dx, dy;  // Bewegungsrichtung

    public MovingObject(int x, int y, int r, int dx, int dy)
    {
        this.x = x;
        this.y = y;
        this.r = r;
        this.dx = dx;
        this.dy = dy;
    }

    public static MovingObject GenerateRandomObject()
    {
        System.Threading.Thread.Sleep(156);
        Random rnd = new Random(DateTime.Now.Millisecond);
        return new MovingObject(rnd.Next(0, 10), rnd.Next(0, 10),
                                rnd.Next(1, 4), rnd.Next(0, 10),
                                rnd.Next(0, 10));
    }
}

14.07.2011 - 15:04 Uhr

fast alles. 🙂

Arrrrghhh 👅

Ich akzeptiere die Lösung trotzdem als korrekt. Du bist dran, die nächste Aufgabe zu stellen.

Puh! Das war aber auch ne knackige Aufgabe.

Eine Frage hab ich noch dazu:

Als Parametertyp kann man statt String [] besser IEnumerable<String> verwenden. Das wird hiermit ausdrücklich erlaubt und empfohlen. Es wird außerdem erlaubt, die Methode als Erweiterungsmethode von IEnumerable<String> zu definieren.

Was hattest du dabei denn im Hinterkopf? Eine eigene Liste implementieren, die die Funktion RemoveDuplicates anbietet?

So, ich werde mir mal Gedanken über eine neue Aufgabe machen. 🤔

14.07.2011 - 13:17 Uhr

Du solltest eine Lösung nur dann posten, wenn du selber davon ausgehst, dass sie korrekt ist.

Sorry X(


public static List<String> Remove(List<String> inputStringList, RemoveDuplicatesOptions removeDuplicatesOptions)
{
    List<String> resultList = new List<string>();
    HashSet<String> hash = new HashSet<string>();
    string tmp = "";
    foreach (string line in inputStringList)
    {
        tmp = ProcessString(line, removeDuplicatesOptions);
        if (tmp.Equals("") || tmp.Equals(" "))
        {
            // evt. sollen Blanklines entfernt werden
            if (removeDuplicatesOptions.HasFlag(RemoveDuplicatesOptions.RemoveBlankLines))
                continue;
            // evt. sollen Blanklines erhalten werden
            if (removeDuplicatesOptions.HasFlag(RemoveDuplicatesOptions.KeepBlankLines))
            {
                resultList.Add(line);
                continue;
            }
        }
        if (hash.Add(tmp)) resultList.Add(line);
    }
    return resultList;
}

public static string ProcessString(string x, RemoveDuplicatesOptions options)
{
    if (options.HasFlag(RemoveDuplicatesOptions.IgnoreCase))
    {
        x = x.ToLower();
    }
    if (options.HasFlag(RemoveDuplicatesOptions.IgnoreLeadingTrailingSpace))
    {
        x = x.TrimStart(" \t".ToCharArray());
        x = x.TrimEnd(" \t".ToCharArray());
    }
    if (options.HasFlag(RemoveDuplicatesOptions.IgnoreSpaceChange))
    {
        x = System.Text.RegularExpressions.Regex.Replace(x, "[ \t]+", " ");
    }
    if (options.HasFlag(RemoveDuplicatesOptions.IgnoreAllSpace))
    {
        x = System.Text.RegularExpressions.Regex.Replace(x, "[ \t]+", "");
    }
    return x;
}

Ich hab jetzt versucht, alles bisherige zu beachten. Diesmal passt alles 8)

14.07.2011 - 12:19 Uhr

Hallo herbivore, du lässt mir ja kein gutes Haar 😁

du bist wieder näher dran. Und darüber, dass die Blankline-Abfragen in dem Fall, dass eine Leerzeile ein oder mehrere Spaces enthält und zusätzlich zu einem Blankline-Flag nur das Flag IgnoreSpaceChange gesetzt ist, nicht richtig funktionieren, weil ProcessString für diese Zeilen (in sich korrekt, aber für die Abfrage nunmal unpassend) " " und nicht "" liefert, hätte ich sogar hinweggesehen.

Ist " " eine Blankline? Und wie schauts mit "\t" aus oder " \t \t"; Hier habe ich mich für den einfachsten Weg entschieden und definiert das nur "" = Blankline ist.

Doch was nützt KeepBlankLines, wenn du dabei HashSet.Add verwendest, welche doppelte Zeilen eben nicht doppelt hinzufügt? Hier bräuchtest du List.Add.

Da hast du mich eiskalt erwischt. Das war mir natürlich bewusst, aber ich hatte noch keine Lösung gefunden. Ich hätte eine Liste anlegen können und die Blanklines hinzufügen können und später dann das HashSet hinzufügen. Das würde aber die Reihenfolge durcheinander bringen. Oder ich füge jedesmal wenn ein String ins HashSet passt diesen String (oder dann das Original) in die List ein.

Die größten Auswirkungen hat aber der Fehler, dass du HashSet.ToList zurückgibst, denn darin sind ja (an sich korrekt, aber für die Rückgabe nunmal unpassend) die aufbereiteten Zeilen und nicht die Originalzeilen. Da wundert mich schon ein bisschen, dass das beim Testen nicht aufgefallen ist. Meiner Ansicht nach brauchst du eine Liste und ein Hashset.

Das ist mir natürlich aufgefallen. Die Frage ist halt, in welcher Form ein String zurückgegeben werden muss. In der Form, wie er als erstes aufgefunden wurde? Es gibt ja auch noch die Duplikate, die evt. andere Schreibweisen haben. Auch hier hab ich's mir einfach gemacht und angenommen, dass ein aufbereiteter String zurückgegeben werden kann.

Dass du eine Zeile immer noch bis zu dreimal aufbereitest, tut der Linearität zwar keinen Abbruch (konstanter Faktor). Schöner wärs aber, wenn du das vermeiden würdest. Und tempx kannst du dir eigentlich komplett sparen. Spätestens da sind wir aber endgültig bei den Stilfragen angekommen.

Find ich auch unschön so. X(

Im Sinne des Dazulernens sind solche Iterationen vermutlich nicht schlecht. Dadurch steigt allerdings die Gefahr, dass dir doch noch jemand zuvorkommt. Auf die Idee, dass man durch diese Aufgabe viel lernen kann, sind bestimmt schon andere gekommen. 🙂

Einen habe ich hier schon in der Streckbank..

14.07.2011 - 11:07 Uhr

So, mein zweiter Versuch:


public class RemoveDuplicates
{
    [Flags]
    public enum RemoveDuplicatesOptions
    {
        IgnoreCase = 0x01,
        IgnoreLeadingTrailingSpace = 0x02,
        IgnoreSpaceChange = 0x04,
        IgnoreAllSpace = 0x08,
        RemoveBlankLines = 0x10,
        KeepBlankLines = 0x20
    }

    public static List<String> Remove(List<String> inputStringList, RemoveDuplicatesOptions removeDuplicatesOptions)
    {
        HashSet<String> hash = new HashSet<string>();
        foreach (string line in inputStringList)
        {
            // evt. sollen Blanklines entfernt werden
            if (removeDuplicatesOptions.HasFlag(RemoveDuplicatesOptions.RemoveBlankLines) && (ProcessString(line, removeDuplicatesOptions).Equals(""))) continue;

            // evt. sollen Blanklines erhalten werden
            if (removeDuplicatesOptions.HasFlag(RemoveDuplicatesOptions.KeepBlankLines) && (ProcessString(line, removeDuplicatesOptions).Equals("")))
            {
                hash.Add(line);
                continue;
            }
            hash.Add(ProcessString(line, removeDuplicatesOptions));
        }
        return hash.ToList<string>();
    }

    public static string ProcessString(string x, RemoveDuplicatesOptions options)
    {
        string tempx = x;

        if (options.HasFlag(RemoveDuplicatesOptions.IgnoreCase))
        {
            tempx = tempx.ToLower();
        }
        if (options.HasFlag(RemoveDuplicatesOptions.IgnoreLeadingTrailingSpace))
        {
            tempx = tempx.TrimStart(" \t".ToCharArray());
            tempx = tempx.TrimEnd(" \t".ToCharArray());
        }
        if (options.HasFlag(RemoveDuplicatesOptions.IgnoreSpaceChange))
        {
            tempx = System.Text.RegularExpressions.Regex.Replace(tempx, "[ \t]+", " ");
        }
        if (options.HasFlag(RemoveDuplicatesOptions.IgnoreAllSpace))
        {
            tempx = System.Text.RegularExpressions.Regex.Replace(tempx, "[ \t]+", "");
        }
        return tempx;
    }
}

11.07.2011 - 14:58 Uhr

Sehr gut! 👍

Ich habe nun dank deiner Hilfe auch eine Lösung. Auf pinvoke.net habe ich Beispiele zu wnetaddconnection2 gefunden. Das dritte Beispiel kann man direkt so verwenden, ich habe es aber noch um zwei statische Methoden erweitert. So hat man Zugriff ohne ein Laufwerk binden zu müssen.


public static int ConnectNetworkShare(string unc, string user, string password)
{
    NETRESOURCE myNetResource = new NETRESOURCE();
    myNetResource.dwScope = ResourceScope.RESOURCE_GLOBALNET;
    myNetResource.dwType = ResourceType.RESOURCETYPE_DISK;
    myNetResource.dwDisplayType = ResourceDisplayType.RESOURCEDISPLAYTYPE_SHARE;
    myNetResource.dwUsage = ResourceUsage.RESOURCEUSAGE_ALL;
    myNetResource.lpLocalName = null;
    myNetResource.lpRemoteName = unc;
    myNetResource.lpProvider = null;
    int result = WNetAddConnection2(myNetResource, password, user, 0);
    return result;
}


[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int flags, bool force);

public static int DeleteNetworkShare(string unc)
{
    int result = WNetCancelConnection2(unc, 0, true);
    return result;
}

08.07.2011 - 16:27 Uhr

Hier meine Lösung zu herbivores Aufgabe:


public class RemoveDublicatesComparer : IEqualityComparer<string>
{
    RemoveDublicates.RemoveDuplicatesOptions options = new RemoveDublicates.RemoveDuplicatesOptions();

    public RemoveDublicatesComparer(RemoveDublicates.RemoveDuplicatesOptions options)
    {
        this.options = options;
    }

    public bool Equals(string x, string y)
    {
        string tempx = "";
        string tempy = "";
        bool isMatch = false;

        isMatch = Regex.IsMatch(x, y);

        if(options.HasFlag(RemoveDublicates.RemoveDuplicatesOptions.IgnoreCase) && !isMatch)
        {
            isMatch = Regex.IsMatch(x, y, RegexOptions.IgnoreCase);
        }
        if (options.HasFlag(RemoveDublicates.RemoveDuplicatesOptions.IgnoreLeadingTrailingSpace) && !isMatch)
        {
            tempx = Regex.Replace(x, "^[ \t]+|[ \t]+$", "");
            tempy = Regex.Replace(y, "^[ \t]+|[ \t]+$", "");
            isMatch = Regex.IsMatch(tempx, tempy);
        }
        if (options.HasFlag(RemoveDublicates.RemoveDuplicatesOptions.IgnoreSpaceChange) && !isMatch)
        {
            tempx = Regex.Replace(x, "[ \t]*", " ");
            tempy = Regex.Replace(y, "[ \t]*", " ");
            isMatch = Regex.IsMatch(tempx, tempy);
        }
        if (options.HasFlag(RemoveDublicates.RemoveDuplicatesOptions.IgnoreAllSpace) && !isMatch)
        {
            tempx = Regex.Replace(x, "[ \t]*", "");
            tempy = Regex.Replace(y, "[ \t]*", "");
            isMatch = Regex.IsMatch(tempx, tempy);
        }
        return isMatch;
    }

    public int GetHashCode(string obj)
    {
        throw new NotImplementedException();
    }
}

public class RemoveDublicates
{
    [Flags]
    public enum RemoveDuplicatesOptions
    {
        IgnoreCase = 0x01,
        IgnoreLeadingTrailingSpace = 0x02,
        IgnoreSpaceChange = 0x04,
        IgnoreAllSpace = 0x08,
        RemoveBlankLines = 0x10,
        KeepBlankLines = 0x20
    }

    public static List<String> RemoveDuplicates(String[] lines, RemoveDuplicatesOptions options)
    {
        List<String> resultStringList = new List<string>();
        RemoveDublicatesComparer comparer = new RemoveDublicatesComparer(options);

        foreach (string line in lines)
        {
            if (options.HasFlag(RemoveDublicates.RemoveDuplicatesOptions.RemoveBlankLines) && comparer.Equals("", line))
                continue;

            if (options.HasFlag(RemoveDublicates.RemoveDuplicatesOptions.KeepBlankLines) && comparer.Equals("", line))
            {
                resultStringList.Add(line);
                continue;
            }
            if (!resultStringList.Contains(line, comparer))
            {
                resultStringList.Add(line);
            }
        }

        return resultStringList;
    }
}

Sehr intressante Aufgabe. Habe viel dabei gelernt. Zerreisst mich bitte in der Luft, damit ich noch mehr lernen kann (Stichwort: Coding Horror)

Viele Grüße

PS: Das komplette Test-Programm gibts auf Anfrage

edit: Ok, Datei angehängt. 😁

08.07.2011 - 13:16 Uhr

Genau. Wir mussten den Rechner mit in die Domain hängen, da sonst der Domain-Nutzer lokal nicht verfügbar ist. Äusserst unbefriedigend...

08.07.2011 - 12:56 Uhr

Als User im Service mit vorangestelltem Domainname.

edit:
In der Diensteverwaltung lässt sich der User für einen Dienst einstellen. Nach einigem rumprobieren lief es dann mit dem Domain-Adminkonto.

Bin wie gesagt immer noch auf der Suche nach einer richtigen Lösung und möchte natürlich auch verstehen warum es nicht auf normalem Wege funktioniert hat.

08.07.2011 - 12:26 Uhr

Ich habe das gleiche Problem. Es hat geklappt, als ich als User den Domain-Admin eingegeben habe. Das läuft jetzt als Zwischenlösung.

06.07.2011 - 13:21 Uhr

Hallo gfoidl, muchas muchas gracias! 😁

Ich kann das jetzt so:


var files = from file in (new DirectoryInfo(sourceDirectory)).EnumerateFileSystemInfos(
                        "*" + sourceFileExtension, SearchOption.AllDirectories)
            where file.Attributes.HasFlag(FileAttributes.Archive)
            select file;

oder so:


var files = from file in Directory.EnumerateFiles(sourceDirectory,
                "*" + sourceFileExtension, SearchOption.AllDirectories)
            where File.GetAttributes(file).HasFlag(FileAttributes.Archive)
            select file;

machen.

06.07.2011 - 12:16 Uhr

Hallo,

ich möchte aus einem großen Haufen kleiner Log-Dateien, zur statistischen Auswertung, diejenigen herausfinden, bei denen das Archiv-Flag noch nicht gestetzt ist.

Nun, Dateien suchen kann ich mit Directory.GetFiles(). Das kann bei sehr vielen Dateien aber recht lange dauern, weil das eine sehr großes string[] gibt.
Leider lässt sich GetFiles() nicht direkt mit File.GetAttributes() verbinden. Oder doch?

Meine Idee dazu händisch die ganzen Unterverzeichnisse durchzugehen und mir die passenden Files rauszusuchen. Über Ideen oder Anregungen dazu wäre ich sehr dankbar.

Viele Grüße 🙂

01.07.2011 - 16:15 Uhr

Du kannst die Generierung (egal ob DGV oder Picture) auch in einen Thread auslagern. Habe ich mal bei einem großen DGV mit > 10k Datensätzen gemacht.
Wenn du eine Stunde für die Generierung brauchst, muss was faul sein. Ich habe für mein DGV < 1 Min gebraucht und das waren nicht nur Nullen und Einsen.

So, hab jetzt aber Wochenende. Wünsche euch Allen ein eben so Schönes wie mir selber. 8)

30.06.2011 - 15:04 Uhr

Oh mein Gott wie einfach.... kopfklatsch

Du hast einfach Latitude & Longitude vertauscht..

30.06.2011 - 13:05 Uhr

Tja, ich habe das auch mal ausprobiert und komme auf das selbe Ergebnis wie du. X(

edit: Übrigens ist Rechnen mit int-Zahlen immer ein bisschen Problematisch imho. Also besser so: return x * PIx / 180.0; damit klar ist, dass es sich um double handelt, und nicht intern in int konvertiert wird.

27.06.2011 - 15:55 Uhr

Hallo m00ni,

es wäre noch interessant, wieviel und was für Daten ausgetauscht werden sollen.

Ein paar Stichworrte zu möglichen Methoden zum Austausch:

  • MessageQueue
  • Zyan
  • IPC/NamedPipes
  • Tcp-Sockets

Viele Grüße

27.06.2011 - 15:47 Uhr

Hallo zusammen. Also vielen Dank nochmal für die Antworten.

MessageQueue's sind im Prinzip ein einfacher und guter Weg, allerdings muss unter Umständen der MessageQueueServer unter Windows installiert werden. Das würde die Installation beim Kunden wieder komplizierter machen.

Zyan ist ein sehr mächtiges Tool, dass relativ einfach zu implementieren ist. Hätte ich wahrscheinlich verwendet, wenn ich nicht schon anders vorgegangen wäre.

Von NamedPipes habe ich wieder Abstand genommen und stattdessen den einfacheren Weg über Tcp-Sockets genommen.

Viele Grüße

27.06.2011 - 09:02 Uhr

@Alf Ator: Ebenfalls danke für deine Antwort. Mir geht es allerdings nicht darum, den Benutzer auf irgend eine Weise zu kontaktieren. Es muss umsverrecken so ein Popup sein 😉.

Die Schwierigkeit ist nur die Kommunikation Dienst->Benutzer. Das Ballon ist dann ja über die WindowsForms-Anwendung ohne weiteres möglich: "System Tray Icon"

24.06.2011 - 13:23 Uhr

So, ich habe mich jetzt dafür entschieden eine zusätzliche Monitoring-Anwendung zu schreiben. Diese wird einen NamedPipe-Server laufen lassen. Der Windows-Service kann dann so Nachrichten an die Anwendung schicken.
So kann ich gleich das ganze Logging mitnehmen und im Fehlerfall eine dickes rotes etwas auf den Monitor ausgeben. Natürlich nur wenn jemand angemeldet ist.

edit:
Ohje, das mit den Named Pipes ist nicht ohne. Mein Kopp qualmt. 🤔
In Multithreaded NamePipeServer in C# ein Beispiel dazu.

Mehr dazu nach dem WE. 😁

24.06.2011 - 13:19 Uhr

Ich bin grade an genau diesem Thema dran. Näheres dazu in meinem dazu eröffneten Thread: Windows Service soll bei Fehler jemanden benachrichtigen: Auf welche Weise am besten?

17.06.2011 - 13:13 Uhr

Also vielen Dank schonmal für die Antworten. 👍
Ich werd mir jetzt nen Kopf drum machen und dann später hier reinschreiben, wie ich's gelöst habe.

Gruß

17.06.2011 - 11:32 Uhr

Hallo Leute

Mein Windows-Service überwacht einen Ordner und stellt verrückte Sachen mit Dateien an, die darin gespeichert werden. Für den unwahrscheinlichen Fall, dass dabei mal ein Fehler auftreten sollte, soll irgendjemand davon benachrichtigt werden. Ich befürchte nur, dass ein Eintrag in der Ereignisanzeige nicht auffällig genug wäre.

Meine Ideen dazu wären erstmal:

  • Benachrichtigung auf den Bildschirm
  • Email an jemanden verschicken

Irgendwelche anderen Ideen oder so? Ich würd mich freuen.

Grüße