Windows-Tipp: Ersetzen von Dateien mit „Nein, alle“ bestÄtigen, beim Kopieren von Dateien im Windows-Explorer

Wenn Ihr mehrere Dateien/Ordner mit dem Windows-Explorer kopieren wolle und eine Datei/ein Ordner bereits vorhanden ist, kommt folgende Meldung:

Was mir da immer gefehlt hat war eine „Nein, alle„-Schaltfläche, die alle Dateien überspringt die schon vorhanden sind und nicht mehr nachfragt.

Und tatsächlich, es ist ein Mechanismus eingebaut der das ermöglicht:

Wenn Ihr die Umschalttaste gedrückt haltet während Ihr mit der Maus auf die „Nein“-Schaltfläche klickt, dann entspricht das einem „Nein, alle“.

Ein paar XSLT-Snippets

Hauptsächlich für mich selbst, nachfolgend eine wachsende Sammlung von XSLT-Code-Snippets:

1.) Ein XML-Dokument 1:1 an die Ausgabe weiterreichen:

<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output
        method="xml"
        indent="yes" />
    
    <xsl:template match="*">
        <xsl:element name="{name()}">
    
            <!-- all attributes. -->
            <xsl:for-each select="@*">
                <xsl:attribute name="{name()}">
                    <xsl:value-of select="current()" />
                </xsl:attribute>
            </xsl:for-each>

            <!-- recurse. -->
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

2.) Eine verschachtelte Struktur in eine flache Struktur umwandeln

Antwort auf meine Frage in einer Newsgroup dazu.

Die Sammlung wird wachsen.

Vorsicht bei „Debug.Assert“-Aufrufen in ASP.NET (2.0)-Webanwendungen!

Über vier Manntage hat mich insgesamt das folgende (in meinen Augen falsche) Verhalten von ASP.NET gekostet.

Beschreibung

  • Eine ASP.NET 2.0-Webanwendung läuft in der Testumgebung ganz normal und auch im Echtbetrieb.
  • Zu nicht-vorhersehbaren Zeiten „hängt“ die Anwendung auf einmal. D.h. die Anwendung reagiert für den Benutzer einfach nicht und der Browser lädt ewig.
  • Wenn ich dann den entsprechenden „w3wp.exe“ kille (ich habe extra einen AppPool nur für die eine Webanwendung gemacht), dann wird sofort automatisch ein neuer w3wp.exe gestartet und die Anwendung läuft wieder normal.

Ursache

Ein Aufruf von Debug.Assert in einer von der Webanwendung verwendeten DLL hat den Prozess zum Hängen gebracht.

  • Debug.Assert direkt in einer
    Webanwendung ausgeführt hält den „w3wp.exe“ nicht an, sondern wird
    schlicht ignoriert.
  • Debug.Assert indirekt
    in einer DLL, die von der Webanwendung verwendet wird, hält den
    w3wp.exe an und kann nur durch killen des „w3wp.exe“ beendet werden.

Lösung

Als schnellen Workaround habe ich jetzt alle Debug.Assert-Aufrufe in der DLL auskommentiert. Natürlich könnt Ihr auch schlicht alles im Release-Modus kompilieren, das ist aber in meinem Fall nicht nötig gewesen (keine Performance-Verbesserungen).

Den Microsoft Scripting Host in C# verwenden

Nachfolgend ein paar Anmerkungen zum den Erlebnissen und Erkenntnissen die ich beim Einbinden des Microsoft Scripting Host in eine C#-Windows Forms-Anwendung hatte.

Ressourcen

Zunächst sind folgende Ressourcen hilfreich:

  • Das Dr. Dobb’s Journal hat einige Artikel dazu veröffentlicht. Fragmente dazu stehen noch im Netz und sind bei Google zu finden.
  • Das Weblog von Eric Lippert enthält gute Infos zum Scripting Host im Allgemeinen.
  • Die Usenet-/Google-Group „microsoft.public.scripting.hosting“ enthält ebenfalls gute Infos.
  • Die eigentliche Schnittstellen-Definition ist z.B. im Platform-SDK-Ordner „c:\Programme\Microsoft SDK\Include\ActivSP.idl“ (so heißt er bei mir) zu finden.

Fehlermeldung „Klasse unterstützt keine Automatisierung“

Diese Fehlermeldung habe ich erhalten, als ich eigene C#-Klassen via IActiveScript.AddNamedItem hinzufügen wollte und diese Klassen nicht public waren oder nicht das ComVisible( true )-Attribut gesetzt hatten.

Als einfache Lösung also einfach schauen, dass die Klassen (inklusive aller Basisklassen) ComVisible( true ) und public sind.

Fehlermeldung „FatalExecutionEngineError“

FatalExecutionEngineError was detected
Message: Die Laufzeit hat einen schwerwiegenden Fehler entdeckt. Fehleradresse: „0x7a0b2d09“ in Thread „0x29c“. Fehlercode: 0xc0000005. Bei diesem Fehler könnte es sich um ein Problem in der CLR oder in den unsicheren oder nicht verifizierbaren Teilen des Benutzercodes handeln. Übliche Ursachen dieses Bugs sind Marshallerfehler für COM-Interop oder PInvoke, die den Stapel beschädigen können.

Diese Fehlermeldung habe ich erhalten, weil ich einen falschen Parameter für die Funktion IActiveScript.AddNamedItem übergeben hatte.

Und zwar habe ich das Flag „SCRIPTITEM_ISSOURCE“ angegeben. Als ich das Flag weggelassen habe, lief alles korrekt.

Dieses Flag gibt laut MSDN-Dokumentation an, dass das hinzugefügte Objekt als Senke für Skript-Ereignisse agieren soll. Scheinbar geht das nicht oder zumindest nicht so wie ich es gedacht habe.

Macht aber nix, brauche ich in meinem Fall nicht. Deshalb habe ich einfach das Flag weggelassen und gut war’s.

Generische Typen in COM verwenden

Klassen die direkt von generischen Basisklassen ableiten sind nicht in COM (also in Skripten im Windows Scripting Host) sichtbar. Es kommen dann seltsame Fehler wie „Method not found“ beim Aufruf von Methoden solcher Klassen.

Deshalb Klassen die von COM aus ansprechbar sein sollen immer von nicht-generischen Basisklassen ableiten.

Was bei mir funktioniert hat ist, wenn solche Klassen generische Schnittstellen implementieren (z.B. IComparable<T>). Die Klasse selbst ist also nicht generisch, nur eine implementierte Schnittstelle. Solch eine Klasse konnte ich erfolgreich von COM aus ansprechen.

Hier einige weiterführende Hinweise zu dem Thema:

  • Meine ursprüngliche Anfrage in den MSDN-Foren
  • „Interoperating Using Generic Types“ in der MSDN Library
  • „COM Interop with Whidbey Generics?“, Artikel von 2004 von Sam Gentile in seinem Weblog

Schnittstellendefinition

Weil ich lange gesucht habe, hier der Download der Schnittstellendefinitionen für folgende Schnittstellen und Enumerationen:

  • IActiveScript
  • IActiveScriptParse
  • IActiveScriptSite
  • IActiveScriptError
  • SCRIPTSTATE
  • SCRIPTTHREADSTATE
  • SCRIPTITEMFLAGS
  • SCRIPTINFOFLAGS

C#-Windows Forms-Designer-Fehlermeldungen in Visual Studio.NET 2005

(View this article in Google-translated English)

Dieser Artikel hier soll mein Versuch werden, verschiedene Fehlermeldungen im leider nicht perfekten C#-Windows Forms-Designer von Visual Studio.NET 2005 zu interpretieren und möglichst zu lösen.

Ich werde den Artikel nach und nach um alle im Laufe der Zeit bei mir so auftretenden Fehlermeldungen und möglichst auch Lösungen ergänzen.

1.) Fehlermeldungen aufgrund von Fehlern im eigenen Code

Der Windows Forms-Designer ruft auch während des Designens Code auf den Ihr geschrieben habt (Details habe ich nie erforscht, welchen und was er ausführt, aber zumindest der Konstruktor des Forms wird aufgerufen).

Deshalb kann es vorkommen, dass Code von Euch Ausnahmen werfen, die wiederum im Designer dann sichtbar werden und ein graphisches Arbeiten verhindern. Z.B. nachfolgendes Bildschirmfoto:


Bildschirmfoto 1: Fehlermeldungen im Form-Designer (Klick für Großbild)

Textuell kommt folgende Fehlermeldung:

Object reference not set to an instance of an object.

at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase. DeserializeAssignStatement( IDesignerSerializationManager manager, CodeAssignStatement statement )
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase. DeserializeStatement( IDesignerSerializationManager manager, CodeStatement statement )

Wichtig zu verstehen ist, dass es eine beliebige Fehlermeldung sein kann, nicht nur die hier oben angegebene Null-Referenz-Ausnahme.

In meinem Beispiel war folgendes die Ursache:

Ich habe in dem Form eine eigenes Benutzer-Steuerelement („UserControl“) verwendet, das im Designermodus eine Ausnahme ausgelöst hat, und zwar beim Zuweisen einer Eigenschaft.

Der Grund für diese Ausnahme im Steuerelement war, dass zur Laufzeit gewisse Ereignis-Behandlungsroutinen aufgerufen werden (z.B. das „Load“-Ereignis des Formulars) und in diesen Behandlungsroutinen dann Variablen initialisiert werden.

Im Designmodus werden diese Behandlungsroutinen nun eben nicht aufgerufen und die Variablen eben nicht initialisiert. Deswegen hat dann die Eigenschaft eine Ausnahme ausgelöst.

Auch wenn im Designer-Fenster keine genaue Fehlerposition angegeben wurde, so zeigte die „Error List“ die genaue Position an, und zwar in Form einer „Warning“ (siehe Bildschirmfoto oben).

Ein Doppelklick auf die „Warning“-Liste öffnete dann die „*.designer.cs“-Quelltextdatei und zeigte wo der Fehler war. In meinem Beispiel war das die Zeile

this.imageControl.ImageObjectID = null;

Ein beherzter Rechtsklick mit der Maus auf ImageObjectID und dann „Go to Definition“ öffnete dann den Quelltext der ImageObjectID-Eigenschaft meines Benutzer-Steuerelements im Editor. Darin war also irgendwo der Fehler.

Lösung:

Oftmals war es für mich gar nicht nötig den genauen Fehler zu lokalisieren, da dieser ja nur im Designmodus auftrat; zur Laufzeit verhielt sich die Anwendung korrekt.

Deswegen habe ich mir eine statische Methode geschrieben die prüft, ob ein Steuerelement im Designmodus ist:

/// <summary>
/// Checks whether a control or its parent is in design mode.
/// </summary>
/// <param name="c">The control to check.</param>
/// <returns>Returns TRUE if in design mode, false otherwise.</returns>
public static bool IsDesignMode(
  Control c )
{
  if ( c == null )
  {
    return false;
  }
  else
  {
    while ( c != null )
    {
      if ( c.Site != null && c.Site.DesignMode )
      {
        return true;
      }
      else
      {
        c = c.Parent;
      }
    }

    return false;
  }
}

Diese Funktion, zentral abgelegt, rufe ich immer dann auf, wenn ich einen Codeblock quasi für den Designmodus „auskommentieren“ möchte, also eben nicht ausführen.

Ein Bisschen ein Hack, aber sehr effektiv und funktionierend.

Alternative Lösung:

Wenn Eigenschaften nicht zur Laufzeit gesetzt werden müssen, folgende Attribute an die Eigenschaft anhängen:

[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

Das sorgt dafür, dass der Designer die Eigenschaften komplett in Ruhe lässt.

Falls Ihr nachträglich diese Attribute setzt, müsst Ihr in den Designer-Dateien bereits vorhandene unnötige Zuweisungen zu den Eigenschaftswerten entfernen, damit es im Design-Modus funktioniert.

2.) Ein Form das im Designer geöffnet wird ist leer und zeigt keine Steuerelemente mehr an

Ich hatte einige wenige Male das Phänomen, dass ein bereits funktionierendes Formular mit zahlreichen Steuerlementen auf einmal beim Öffnen im Form-Designer komplett leer war.


Bildschirmfoto 2: Leeres Form im Form-Designer (Klick für Großbild)

Ein Blick in die „*.designer.cs“-Datei des Forms zeigte dann, dass ganz am Ende der Funktion InitializeComponent eine oder beide dieser Zeilen fehlte:

this.ResumeLayout( false );
this.PerformLayout();

Nachdem ich diese ergänzt hatte, das Form wieder geschlossen, neu kompiliert und geöffnet hatte, war alles wieder im Form-Designer vorhanden und auch zur Laufzeit voll funktionsfähig. Manchmal reicht auch schlicht das Ergänzen der fehlenden Zeile, ohne ein Neukompilieren.


Bildschirmfoto 3: Korrekt gefülltes Form im Form-Designer (Klick für Großbild)

Die Ursache warum der Form-Designer den Code gelöscht hat ist mir leider unbekannt.

Bei meinen Fällen war danach auch der Code dauerhaft vorhanden. Jörg hat leider die Erfahrung gemacht, dass nach jedem manuellen Einfügen und Schließen der Datei, der Form-Designer den Code erneut gelöscht hat. Bei Jörg war es ein Formular mit sehr vielen Steuerelementen (ca. 200), ggf. könnte(!) das eine Ursache gewesen sein.

3.) Die Zuordnung der Eigenschaften Form.AcceptButton und Form.CancelButton gehen verloren

Relativ oft passiert es mir, dass ich einem Form im Form-Designer via Eigenschaftsfenster die Werte für Form.AcceptButton und Form.CancelButton zuweise (also die Schaltflächen die beim Benutzen der Eingabetaste bzw. der Escape-Taste ausgelöst werden) und irgendwann die Zuordnungen wieder verschwunden sind.

Die genaue Ursache kann ich leider nicht ermitteln, mir ist aber aufgefallen wenn ich Änderungen im Form-Designer Rückgängig mache (über Strg+Z oder den „Rückgängig“-Eintrag im „Bearbeiten“-Menü), die Zuordnung auch verschwindet. Ggf. hängt das damit zusammen.

Dieser Punkt ist jetzt nicht mission critical, aber dennoch lästig, weil es halt nicht sofort auffällt.

Manchmal bin ich jetzt dazu übergegangen, im Konstruktor eines Form, nach dem automatisch generierten Aufruf zu InitializeComponent() die Zuordnungen manuell hinzuschreiben, so dass diese dauerhaft erhalten bleiben.

4.) Die Schaltflächen (ToolStripItems) einer Werkzeugleiste (MenuStrip) werden nicht mehr dargestellt

Diesen Effekt hatte Kollege Thilo einmal gehabt, mit dem Ergebnis, dass die Werkzeugleiste komplett „leer“ dargestellt wurde.

Es ist nach einem Absturz der Visual Studio .NET 2005-IDE aufgetreten.

Im Endeffekt haben einige Zuordnungen in der „*.designer.cs“-Quelltextdatei gefehlt.

So sahen die relevanten Zeilen direkt nach dem Absturz aus:

...
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripSeparator1,
this.toolStripSeparator2,
this.toolStripSeparator3});
this.toolStrip1.Location = new System.Drawing.Point(0, 24);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(809, 25);
this.toolStrip1.TabIndex = 5;
this.toolStrip1.Text = "toolStripMain";
...

Und so die manuell korrigierte, wieder funktionierende Version:

...
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btnPublish,
this.toolStripSeparator1,
this.btnPGedit,
this.btnPGadd,
this.btnPGdel,
this.toolStripSeparator2,
this.btnAGedit,
this.btnAGadd,
this.btnAGdel,
this.toolStripSeparator3,
this.btnAedit,
this.btnAadd,
this.btnAdel});
this.toolStrip1.Location = new System.Drawing.Point(0, 24);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(809, 25);
this.toolStrip1.TabIndex = 5;
this.toolStrip1.Text = "toolStripMain";
...

Thilo konnte das aus einer Sicherheitskopie (auch „Backup“ genannt) wiederherstellen.

An dieser Stelle mal der erneute Hinweis, wie wichtig Sicherheitskopien sind!

Ich „zippe“ mir immer mal wieder komplette Projektstände und speichere sie mit Datum versehen in einen Ordner (z.B. mit dem Dateinamen „myproject – 2006-07-18.zip“), so dass ich auch mehrere Schritte zurückgehen kann.

Siehe auch: Solving „Exception of type System.ComponentModel.Design.ExceptionCollection was thrown.“ error messages in Visual Studio .NET 2010 Windows Forms Designer

Fehlerhafte Microsoft JET-Installation reparieren

Um eine fehlerhafte Microsoft JET- oder Microsoft MDAC-Installation zu reparieren hat mir heute ein kostenloses Werkzeug geholfen:

CSRepair“ von der Firma Macropool (hier der direkte EXE-Download).

Im konkreten Fall war es der Fehler

Das COM-Objekt mit der CLSID {DE88C160-FF2C-11D1-BB6F-00C04FAE22DA} ist ungültig oder wurde nicht registriert

Nach dem Ausführen des Werkzeugs war der Fehler behoben.

Update 27.04.2017

Die Links oben zu CSRepair sind tot, deshalb habe ich sie entfernt. Eventuell hilft dieses Tool von Microsoft weiter.

Siehe auch meinen Artikel zum Reparieren von JET-Dateien.

System.TypeLoadException in C++/CLI-MFC-Anwendung

Beschreibung

Beim Umstellen einer MFC-Anwendung auf C++/CLI kam nach erfolgreicher Kompilierung beim Start eine .NET-Fehlermeldung System.TypeLoadException, mit Fehlercode 0x80131522.

Ursache

Genau kenne ich die Ursache nicht, verschiedene Berichte/Postings deuten darauf hin, dass es ein Fehler mit dem Assembly Loader ist, der die Anwendung initial startet.

Scheinbar gibt es eine Begrenzung diverser Ressourcen in der Sektion globaler Symbole. Dass dies tatsächlich ein Grund sein könnte zeigte die riesige Dateigröße von 66 MB für die eigentliche Anwendung (früher, ohne C++/CLI war diese 30 MB groß).

Lösung

Die eigentliche, für mich passende, Lösung wurde hier beschrieben:

Ich habe das sogenannte „String Pooling“ in meinen Visual C++-Projekteinstellungen aktiviert. Danach war die kompilierte Anwendung noch 8 MB (statt 66 MB) groß und der Fehler trat beim Laden nicht mehr auf.

Weitere ggf. nützliche Ressourcen:

Fehlermeldung beim Aktualisieren einer SQL Server 2000-Tabelle äber einen Verbindungsserver

Beschreibung

In einem Szenario hatten wir 2 Microsoft SQL Server 2000 (Server A und B). der eine hat den anderen als Verbindungsserver („Linked server“) eingebunden.

Wenn nun von einer Datenbank auf Server B eine SELECT-SQL-Abfrage auf eine Tabelle in einer Datenbank auf Server A ausgeführt wurde, so hat dies korrekt funktioniert.

Wurde jedoch eine UPDATE-SQL-Abfrage ausgeführt, so kam eine Fehlermeldung.

Die auszuführende Abfrage war in etwa:

UPDATE [MyTable]
SET [Credit Limit Block]=2
WHERE [No.]=’000102628521′

(also eine Abfrage auf Spaltennamen mit Leerzeichen).

Als Fehlermeldung erschien dann:

Server: Nachr.-Nr. 8180, Schweregrad 16, Status 1, Zeile 1
Statement(s) could not be prepared.

Server: Nachr.-Nr. 170, Schweregrad 15, Status 1, Zeile 1
Line 1: Incorrect syntax near ‚Limit‘.

Ursache

Scheinbar hat der SQL Server 2000 bei bestimmten Konfigurationsparametern Probleme bei UPDATE-Abfragen über einen Verbindungsserver, wenn Feldern mit Leerzeichen beteiligt sind.

Dies waren die ursprünglichen Einstellungen des Verbindungsservers:

Verbindungsserver-Einstellungen die in meinem Fall die UPDATE-Anweisung fehlschlagen ließen
Fehlgeschlagen

Damit kam die Fehlermeldung.

Bei Google habe ich unter anderem folgende Zitate gefunden:

…If I was to remove the space from (my colum name) [f 1] and use [f1] it would work fine…

Und

I’ve seen this before, and I’m quite sure that I have reported it to
Microsoft. However, it does not seem have been fixed in SQL 2000. The
error is that when the query is submitted to the remote server, the
brackets are missing.

Lösung

Da ich ein anderes, fast gleichwertiges, System hatte, auf dem die UPDATE-Abfrage korrekt funktionierte, habe ich die Einstellungen des Verbindungsservers verglichen und die Option gefunden, die in meinem Fall die Lösung war:

Verbindungsserver-Einstellungen die in meinem Fall die UPDATE-Anweisung erfolgreich ausführen ließen
Erfolgreich

Ich habe also schlicht die Option „Remotesortierung verwenden“ deaktiviert. Danach funktionierte meine Abfrage.

Ob das in jedem Fall eine praktikable Lösung ist, weiß ich leider nicht, jedoch in meinem Fall war dies ausreichend.

Die <%@ Page %>-Direktive in ASP.NET 2.0 um benutzerdefinierte Attribute erweitern

Im Artikel „Obscure but cool feature in ASP.NET 2.0“ schreibt Scott Guthrie darüber, wie die Page-Direktive um eigene Attribute erweitert wird.

Z. B.

<%@ Page 
	Language="C#" 
	Message="My Test Message String"
	Inherits="BasePage"%>

Dabei ist das „Language“-Attribut und das „Inherits“-Attribut ein eingebautes Attribut, das „Message“-Attribut ist ein benutzerdefiniertes.

Ich habe das mit der RTM-Version (also der endgültig freigegebenen Version) von ASP.NET 2.0 probiert, so wie von Scott beschrieben, bin aber erst mal auf den Fehler gelaufen:

Build (web): Fehler beim Analysieren des Attributs message: Der Typ System.Web.UI.Page hat keine öffentliche Eigenschaft mit dem Namen message.

Da Scott den Artikel mit der Version Beta 1 von ASP.NET 2.0 geschrieben hat, hat sich da wohl was geändert intern. Er schreibt das auch in einem entsprechenden Kommentar zu seinem Artikel, verschweigt aber wie genau das gemacht wird.

Nun, die Lösung ist ganz einfach (wie immer, wenn man weiß wie:

Das „CodeFileBaseClass„-Attribut muß auch in der Page-Direktive angegeben werden, und zwar mit dem Namen der Basisklasse, und nicht mit dem Namen der CodeBehind-Klasse.

Z. B.

<%@ Page 
	Language="C#" 
	CodeFileBaseClass="BasePage" 
	Message="My Test Message String"  
	Inherits="BasePage"%>

Dann sollte es korrekt funktionieren. In einem konkreten Fall habe ich folgendes erfolgreich geschrieben:

<%@ Page 
	Language="C#" 
	MasterPageFile="~/StandardMaster.master" 
	Inherits="Pages_ConfigurationAssetList" 
	CodeFile="ConfigurationAssetList.aspx.cs" 
	CodeFileBaseClass="PageBase" 
	Title='Anlagenliste' 
	TitleImageFileName="CheckBook.png" %>

Wobei „PageBase“ die Basisklasse war und „TitleImageFileName“ mein neu hinzugefügtes Attribut.

Microsoft Indexing Service findet (scheinbar) nicht vorhandene Suchbegriffe

Beschreibung

Beim Suchen nach Suchbegriffen mit dem Indexing Service von Microsoft (auch „Index Server“ genannt) tritt das Phänomen auf, daß auch Dokumente gefunden werden die den Suchbegriff scheinbar gar nicht enthalten.

Beispielsweise wurde nach „preisliste“ oder „kombinationsbeispiel“ gesucht und eben solche scheinbar falschen Dokumente gefunden. Hingegen haben Suchanfragen nach Wörtern wie „haus“ oder „auto“ nur korrekte Dokumente geliefert.

Ursache

Ich vermute sehr, dass der Indexing Service bei zusammengesetzten Wörtern die Wörter aufteilt und sucht als wäre es eine Suche nach den einzelnen Wörtern (gibt es da in der Grammatik Regeln um dies automatisch durchzuführen?).

Also beispielsweise bei der Suche nach „preisliste“ führt der Indexing Service eine Suchanfrage aus nach Dokumenten die „preis“ oder „liste“ oder „preisliste“ als Suchbegriffe enthalten.

Deswegen werden scheinbar auch „falsche“ Dokumente gefunden.

Lösung

Als einzigen Workaround habe ich die sogenannten „Content Queries“ gefunden.

Wenn mit einem Suchbegriff nun statt beispielsweise nach „preisliste“ über die erweitere Syntax nach „{phrase} preisliste {/phrase}“ gesucht wird, so werden tatsächlich auch nur Dokumente gefunden die direkt den Begriff „preisliste“ enthalten.

Ich bin mir unsicher ob das ein sauberes Vorgehen ist oder eher ein „geht so, ist aber eigentlich für was anderes gedacht gewesen“. Aber es funktioniert in allen bisherigen Tests :-).

Ergänzung 2006-03-03: Im Artikel „Creating Search Pages with Index Server and .NET“ auf CodeProject schreibt Heath Stewart über die „CONTAINS“- und „FREETEXT“-Prädikate. Ggf. auch eine Alternative.