|
|
|
Vandens experience [VANDEN HOME] |
|
MDF FILE AUF NETZLAUFWERK Wer es von anderen Datei-Systemen eventuell gewohnt ist direkt auf Datenbank-Dateien zuzugreifen, die auf einem verbundenem Netzlaufwerk sind, und versucht diese Vorgehensweise auch auf *mdf Dateien einer MS SQL Server Datenbank zu übertragen, muss enttäuscht werden. Dies ist nicht im Sinne des Erfinders. C# gibt die Fehlermeldung " Fehler beim Anfügen einer automatisch benannten Datenbank für die Datei G:\usr\c#\dbConnTest\net.mdf. Eine Datenbank mit diesem Namen ist bereits vorhanden, die angegebene Datei kann nicht geöffnet werden, oder sie befindet sich in der UNC-Freigabe. " aus. Ich verwende MS SQL Server 2005 Express Edition und der direkte Zugriff auf beliebige MDF-Dateien funktioniert nur lokal und von einem Benutzer. Sollen sich Benutzer die Datenbank teilen, muss der MS SQL Server irgendwo auf einem Computer im Netz aktiv sein und die ?.MDF Datenbankdatei "attached" werden. Das klappt bequem mit der separaten Datenbankverwaltung "SQL Server Management Studio Express" (File: SQLServer2005_SSMSEE.msi), die bei MS gratis heruntergeladen kann, um die MS SQL Server 2005 Express Edition zu verwalten. Darüber hinaus muss die installierte MS SQL Server Datenbank über Start -> Programme -> MS SQL Server 2005 -> Konfigurationstools -> SQL Server Oberflächenkonfiguration unter "Remote" für einen Netzwerkzugriff aktiviert werden. Die Änderung ist erst aktiv, wenn der Server-Dienst neu gestartet wurde. Das kann zum Beispiel mit Start -> Programme -> MS SQL Server 2005 -> Konfigurationstools -> SQL Server Configuration Manager und einem Rechtsklick auf den obersten Pfad bewerkstelligt werden. Firewall Einstellungen sind zu beachten. Programm "sqlbrowser.exe" und/oder "UDP" benutzen Port 1434! Diese Programme und der Port müssen frei sein. Der ConnectionString braucht dann auch nicht mehr den AttachDBFilename-Parameter, sonder sollte beispielsweise so aussehen: "Server=(local)\SQLEXPRESS;Database=networkdata.mdf;Integrated Security=True;Connect Timeout=30" - Das "Integrated Security=True" bedeutet, dass sich mit der Standard-Windows Authentifizierung an der Datenbank angemeldet wird. Das ursprüngliche User Instance=true musste entfernt werden. Warum? Darum! (Zitat MS): "The User Instance functionality creates a new SQL Server instance on the fly during connect. This works only on a local SQL Server 2005 instance and only when connecting using windows authentication over local named pipes. The purpose is to be able to create a full rights SQL Server instance to a user with limited administrative rights on the computer." |
|
ZUGRIFF VON ANDEREM RECHNER AUF MS SQL SERVER Hier sind die Erlebnisse des ersten Connects mit meiner Datenbank von einem anderen Rechner des Netzwerks aus niedergeschrieben. Ziel war es von einem anderen Rechner in der Domäne einen Datenbankzugriff auf meinem Rechner ausführen lassen. Wenn das C# Programm versucht auf die MS SQL Server 2005 Express Edition zuzugreifen, erfolgte auf dem anderen Client folgende Exception: "Fehler bei der Anforderung des Berechtigungstyps System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089." Die ausgeführte C# Anwendung ?.exe war zu dem Zeitpunkt auf einem Netzlaufwerk! Das sollte im Standard nicht sein! Nachdem die Anwendung lokal auf den Rechner kopiert wurde, wahr diese Fehlermeldung weg. Allerdings tauchte nun der Error 26 auf, dass der SQL Server wahrscheinlich keine Remote Zugriffe akzeptiert. Die Firewall war bei Server, als auch beim Client inaktiv. Der SQL Server war aber für Remote Zugriffe konfiguriert. Das sollte das Problem nicht gewesen sein! Prophylaktisch wurde der DOMÄNE\USER unter "SQL Server Management Studio -> Sicherheit -> Anmeldung -> Neu" hinzugefügt. Dies bezüglich sollte "http://blogs.msdn.com/sql_protocols/archive/2007/05/13/sql-network-interfaces-error-26-error-locating-server-instance-specified.aspx" sehr hilfreich sein. Die Lösung in meinem Fall war unter anderem, dass der Dienst SQLBrowser.exe nicht aktiv war. Dieser muste unter Systemsteuerung -> Verwaltung -> Dienste -> SqlBrowser -> Eigenschaften -> Automatisches Starten eingestellt werden. Ein neuer Test auf dem anderen Rechner in der Domäne war wieder erfolglos. Leider kam nun wieder eine Fehlermeldung, dass meine gewünschte Datenbank networkdata.mdf nicht verbunden werden konnte! Lokal war es kein Problem! Muss die Datenbank auch noch mal explizit mit Remoterechten versehen werden und nicht nur der Datenbank Server? Nun wurde der DOMÄNE\USER des Fremdrechners zusätzlich auch in der networkdata.mdf -> Sicherheit -> Benutzer ergänzt (via Management Studio) mit der Rolle des "db_accessadmin". Man kam langsam weiter. Jetzt erschien der nächste Fehler: "Die SELECT-Berechtigung wurde für das 'Funktionen'-Objekt, 'networkdata.mdf'-Datenbank, 'dbo'-Schema verweigert." Was tun? Hatte nun unter SQL Server -> Sicherheit -> Anmeldungen -> DOMÄNE\USER -> die Standarddatenbank korrigiert auf networkdata.mdf. Zusätzlich hatte ich auch dem Benutzer alle möglichen Rollen vergeben. Auch wenn das letzten Endes nicht ideal ist. Aber um erst einmal grundlegende Erfahrungen zu sammeln und den Fehler einzukreisen, war es wahrscheinlich sinnvoll. Et voila : Es funktionierte. Welche Schemen und Rollen sollten im Besitz des Users sein? In meinem Fall jedenfalls db_datareader und db_datawriter! Bei weiteren Probleme, suksezzive noch Rollen hinzufügen. |
|
"Schnittstelle nicht unterstützt" Hatte in Delphi und C# das Problem eine gewisse COM Schnittstelle einer EXE nicht ansteuern zu können zu der keine detaillierte Beschreibung vorlag. Der Import/Generierung der Type Library war kein Problem. Aber das Erzeugen einer Standard-Instanz via CoKlasse! Der Windows-Com Server antwortete immer, dass die "Schnittstelle nicht unterstützt" wird. Eine umfangreiche Internetrecherche brachte für meinen Fall keine direkten Ergebnisse. Konkreter wurde es in dem C# Testprogramm. Meldung des Debuggers: "Das COM-Objekt des Typs "XXX.ControlClass" kann nicht in den Schnittstellentyp "XXX.IControl" umgewandelt werden. Dieser Vorgang konnte nicht durchgeführt werden, da der QueryInterface-Aufruf an die COM-Komponente für die Schnittstelle mit der IID "{???.XXX.YYY.????.????}" aufgrund des folgenden Fehlers nicht durchgeführt werden konnte: Schnittstelle nicht unterstützt (Ausnahme von HRESULT: 0x80004002 (E_NOINTERFACE))." Was mir erst später auffiel war, dass die TypeLibrary auch eine CoAdapter-Klasse beinhaltete. Die Verwendung der Adapterklasse stellte zur vermeintlichen, naheliegendereren Co-Klasse kein Problem dar und die Fehlermeldung tauchte nicht mehr auf. |
|
C# DRAG AND DROP SIMPLES BEISPIEL In dem Beispiel soll nur der Drop der *.txt-Dateien erlaubt sein. Hier beschränkt sich die Prüfung der *.txt beim eigentlichen Droppen. Eleganter wäre die Prüfung bereits beim DragOver und das da bereits ein verneinendes MouseIcon signalisiert, daß es nicht um eine *.txt Datei handelt. a) In den Eigenschaften des Formulars ALLOWDROP = TRUE setzen. b) Auf Ereignis DRAGOVER reagieren. c) Auf Ereignis DRAGDROP reagieren. Ereigniscode zu b): private void Beispiel_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Link; else e.Effect = DragDropEffects.None; } Ereigniscode zu c): private void Beispiel_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string file in files) { if (file.ToLower().IndexOf(".txt") != -1) DoSomethingWithTxtFile(string); } } } |
|
C# EXPRESS ED. 2005 - CLICKONCE APPLICATION SOLL DESKTOPICON ERSTELLEN Unter PROJEKT -> Projekt EIGENSCHAFTEN -> VERÖFFENTLICHEN -> OPTIONEN : Herausgeber festlegen Dieser Herausgeber-Wert muss in folgender Methode manuel eingefügt werden. Eventuell müssen auch entsprechende Namespaces bei Compilier-Fehlermeldungen hinzugefügt werden. private void createIcon() { string herausgeber = "MeinHerausgeberWert"; //Kann wohl auch eleganter ermittelt werden. Aber einfach den Wert wie oben erwähnt manuel einsetzen. string produkt = Application.ProductName; //Project Properties Eintrag! /*Nationale Bezeichnung für PROGRAMME Ordner holen*/ string programme = System.Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); //im Deutschen heisst der Ordner Programme, im Englischen Programs... - demnach ist der Name ab \StartMenü\... anders! int posi = 0; while ( programme.IndexOf("\\") > -1 ) { programme = programme.Substring(posi + 1); } /*ICON kopieren aus Start Programme Anwendung -> Desktop*/ string source = System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu) + "\\"+programme+"\\"+herausgeber+"\\"+produkt+".appref-ms"; string dest = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + "\\"+produkt+".appref-ms"; File.Delete(dest); if (File.Exists(source)) { try { File.Copy(source, dest); } catch (Exception ex) { MessageBox.Show("Icon konnte nicht auf den Desktop des gegenwärtigen Users kopiert werden!\n(" + ex.Message + ")", "ICON FEHLER"); } } } |