Laden...
Avatar #avatar-3273.gif
Mr. Bart Simpson myCSharp.de - Member
Anwendungsentwickler Mittelfranken Dabei seit 13.03.2004 502 Beiträge
Benutzerbeschreibung

Forenbeiträge von Mr. Bart Simpson Ingesamt 502 Beiträge

28.10.2005 - 19:16 Uhr

@roland

Das ist so ungefähr das was mir auch vorschwebt... aber wie's scheint, muss ich doch öfter mal Controls entwickeln 😉 Ich war bis dato immer der Meinung, dass man sich beim Entwickeln dabei doch um einiges schwerer tut als bei der Entwicklung eines Forms. Naja, mal sehen...

Bart Simpson

27.10.2005 - 20:10 Uhr

Hmm... interessanter Ansatz. Und wie ich sehe gilt mal wieder: Wer lesen kann ist klar im Vorteil 😉 Ein Panel ist ja schon ein ScrollableControl - man muss nur AutoScroll auf true setzen.

Von der Seite betrachtet, sollte es kein Problem sein, irgendwelche Controls aus dem Add-In darauf unterzubringen. Was mich allerdings stört, ist der Ansatz jeweils ein eigenes UserControl zu entwickeln. Das ist nun nicht gerade eine spassige Sache...
Ich denke vielmehr darüber nach, ein simples Form pro Add-In zu erstellen (Das designen ist einfach viel leichter). Es sollte doch eigentlich möglich sein, die Controls aus einer dieser Form-Instanzen zu "klauen" und auf ein Panel zu übertragen?
Das hätte gleichzeitig den Vorteil, dass ich ohne Umstände auch immer einen modalen Dialog zur Konfiguration anzuzeigen.

Gibt's vielleicht noch andere Ansätze, Lösungen, etc.?

Bart Simpson

27.10.2005 - 16:17 Uhr

Ich hab da eine nette Problemstellung und such verzweifelt nach eine Lösung find aber keine wirkliche Lösung...
Das Ganze soll in etwa so ablaufen:
Ich hab ein Form, auf dem sich einige Panels befinden. Dieses Form läd (über einige Hilfsklassen, aber egal) so 'ne Art Add-Ins dynamisch hinzu und verwaltet diese.
Die Add-Ins haben alle ein gemeinsames Interface (welches auch zur Instanziierung genutzt wird). Nun möchte ich in dieses Interface eine Methode integrieren, mit der die Add-Ins in der Lage sind eine Art Konfigurationsdialog anzuzeigen.

Der einfach weg wäre natürlich eine Art ShowDialog() zu implementieren und jeweils eigene Forms in die Add-Ins zu integrieren. Das will ich aber nicht 😉

Ich möchte dass sich die Add-Ins "nahtlos" integrieren, also ihre "Darstellung" z.B. innerhalb eines Panels erledigen.

Frage 1) Wie würdet Ihr das lösen?
Frage 2) Wenn für 1) z.B. ein simples Panel als Container zur Darstellung dient, ergibt sich leider ein Problem: Das HauptForm kennt die Add-Ins natürlich nicht. Folglich weiss es auch nicht, wieviel Platz denn die Add-Ins zur Darstellung gern hätten... Man müsste also das Panel schrollbar machen - geht das überhaupt? Wenn ja, wie?

Danke für jeden Hinweis!

Bart Simpson

21.10.2005 - 11:01 Uhr

Im MS SQL Server geht's auch problemlos ohne Temptabelle(n)... Du must dem Sub-Select nur einen Namen geben:

SELECT COUNT(*) AS Counter, A FROM
(
SELECT A FROM XXX
) AS Temp
GROUP BY A

Bart Simpson

16.10.2005 - 23:42 Uhr

Ich möchte innerhalb einer XML Datei Master-Detail Beziehungen abbilden, versteh aber nicht ob und wenn ja wie das mittels XSD zu definier geht...

Bsp:


<Master>		
		<DataSource>			
			<ID>12345</ID>
			...			
		</DataSource>
		<DataSource>			
			<ID>12346</ID>
			...			
		</DataSource>
		<DataSource>			
			<ID>12347</ID>
			...			
		</DataSource>		
	</Master>
	<Detail>
	  <MasterID>12345</MasterID>
          ...
	</Detail>
	<Detail>
	  <MasterID>12345</MasterID>
          ...
	</Detail>
	<Detail>
	  <MasterID>12346</MasterID>
          ...
	</Detail>
	<Detail>
	  <MasterID>12347</MasterID>
          ...
	</Detail>
	<Detail>
	  <MasterID>12345</MasterID>
          ...
	</Detail>

Die Prinzipielle Struktur zu definieren ist mit XSD ja relativ einfach, aber wie erzwinge ich (wenn überhaupt möglich) dass die ID's im Detail-Bereich auch im Master-Bereich vorhanden sind?

Bart Simpson

16.10.2005 - 23:26 Uhr

Der Titel klingt wohl ein wenig absonderlich - bei genauerer Betrachtung denk ich aber ist es sehr treffend... Mutex steht ja für mutually exclusive, also sich gegenseitig ausschliessend, nur wie definier ich sowas in einem XML Schema?

Ich möchte also, dass z.B. genau folgendes möglich ist

<Parent>
  <Child_A>
     <abc />
  </Child_A>
</Parent>

Oder aber

<Parent>
  <Child_B>
     <xyz />
  </Child_B>
</Parent>

Es soll also entweder Variante 1 oder Variante 2 möglich sein, aber nicht beides (und auch nicht "keines")... Nur wie wird das mit Hilfe von XSD gemacht???

Bart Simpson

27.09.2005 - 22:50 Uhr

versuch's mal mit Application.Exit();

Bart Simpson

11.09.2005 - 13:20 Uhr

Also ich kenne keinen direkten Weg um das zu tun... Aber ich würde mich gerne mal des besseren belehren lassen 🙂

Um das Ganze trotzdem relativ elegant lösen zu können "missbrauch" ich meistens den Query Analyzer:

select 'GRANT SELECT ON [' + [name]+'] TO public' from dbo.sysobjects where xtype = 'U'

Damit lass ich mir alles benötige als Script erzeugen und brauch's dann nur noch auszuführen.

Bart Simpson

07.09.2005 - 23:25 Uhr

Original von norman_timo
Es gibt im INet Tools, die bootbar sind, und dann das vorhandene Administratorpasswort mit einem neuen fixen Passwort überschreiben, also dürfte die Stelle, wo Passwörter gespeichert sind bekannt sein, doch revers kannst Du sie auf keinen Fall auslesen

Naja... so ganz ist das wohl nicht korrekt. Ist nur eine Frage des Aufwands-> siehe L0phtCrack.
Damit wirst Du sehen, dass "unsichere" Passwörter binnen Sekunden oder zum. Minuten rauszukriegen sind!

Bart Simpson

30.08.2005 - 23:25 Uhr

Also SP's als Krücke zu bezeichnen geht dann wohl doch ein wenig weit 😉
Obwohl ich ja im wesentlichen zustimmen muss... Dennoch finde ich sind SP's ein gutes Mittel bei der Entwicklung mehrschichtiger Apps.

Zum Thema Performance: Es gibt noch einen weiteren Vorteil. SP's werden vom Server quasi "compiliert", wohingegen er direkte SQL Kommandos jedesmal neu parsen muss -> Auch die DB-Server-Last kann mit SP's gedrückt werden.

Bart Simpson

29.08.2005 - 23:38 Uhr

...oder noch ein Vorschlag: FreePDF. Das nutzt GhostScript, hat aber den Vorteil einen Druckertreiber mitzubringen.

Bart Simpson

27.08.2005 - 18:55 Uhr

Also ich hab's jetzt nicht geprüft, aber mir fallen in .net nur zwei Wege ein um Blobs mit Binärdaten zu füllen:

  1. Mittels INSERT bzw. UPDATE und Parametern
  2. (Ich müsst erst nachschauen wie das genau geht, aber ich weiss dass es geht) Man kann sich irgendwie 'nen Stream holen, der auf ein Blobfeld in einem (existierenden) Datensatz "zeigt" - das heisst aber, es geht nie gleichzeitig mit einem INSERT.

Wie würdest Du den Binärdaten bei INSERT ohne Parameter schreiben?

Bart Simpson

27.08.2005 - 18:49 Uhr

Also ich persönlich hab (mit meinen Kollegen) quasi meine eigenen Konventionen entwickelt. Allerdings finde ich FxCop immer mal wieder ganz nett um mal schnell über eine Klasse zu schauen - das bringt mich dann oftmals wieder dazu, meinen Stil mal wieder zu "überdenken und freundlich zu korrigieren" 😉
Allerdings ist es sicher kein Schaden sich an den offiziellen Standart (wenn ich mich grad nicht irre heisst das CLS Compliant oder so) zu halten. Und genau das kann FxCop auch prüfen.

Bart Simpson

27.08.2005 - 17:55 Uhr

Wenn Du Dich an die MS-Koventionen halten willst, dann schau Dir doch mal FxCop an.

Bart Simpson

27.08.2005 - 17:43 Uhr

Binärdaten sind ein Beispiel, wo Parameter nötig sind. Was ich allerdings für viel wichtiger halte ist: SICHERHEIT. Mit den Parametern kannst Du sehr schön Probleme wie z.B. SQL Injection lösen. ( siehe z.B. http://www.nextgenss.com/papers/advanced_sql_injection.pdf)

Ausserdem ist i.d.R. die Ausführungsgeschwindigkeit höher, da sich die Abfragen leichter parsen lassen.

Bart Simpson

26.08.2005 - 13:56 Uhr

Also man kann das durchaus in der DB machen und das trotzdem vernünftig skalierbar (ich geh jetzt mal vom MS-SQL aus)...
Worauf man aber achten sollte: Die Files (respektive die Blob's in denen sie liegen) sollten in einer separaten (also nicht der Primary) Filegroup sein.
Das hat dann mehrere Vorteile:

  • Die DB holt sich die Daten nur aus der Filegroup, wenn sie wirklich angefordert werden (hat also keinen großen Einfluss auf die Abrufzeit der anderen Spalten)
  • Die Daten liegen in einer großen Datei zusammengefasst auf der Platte -> Keine Fragmentierung (-> Den Platz auf der Platte brauchst Du so oder so, aber in der DB kannst Du steueren, wieviel "verschwendet" wird)
  • ...die von Dir schon genannten Vorteile

Bart Simpson

17.08.2005 - 19:50 Uhr

Also wenn Du Admin Rechte hast, dann weiss ich auch langsam nicht mehr, woran's noch liegen soll...

Original von Steve1974

Wie bearbeitest Du denn die Gespeicherten Prozeduren? Errinnere ich mich da richtig, dass das über das Kontextmenü der Prozedur im Serverexplorer ging?

Über's Kontextmenü sollt's eigentlich gehen - wobei ich (dank besserem Syntaxhighlighting) eigentlich meistens den SQL Query Analyzer verwende.

Bart Simpson

17.08.2005 - 15:44 Uhr

Hmm... also das Bearbeiten sollte dann eigentlich funktionieren, denn das ist relativ problemlos. (ggf. mal probieren wie's mit Windows-Admin-Rechten aussieht - ist ein Schuss ins blaue, aber man weiss nie...)

Was das Debuggen angeht: Läuft der SQL Server lokal auf dem gleichen Rechner oder irgendwo im Netzwerk?
Bei mir klappt das Debuggen irgendwie nur wenn ich lokal arbeite - remote sollte es zwar eigentlich auch, tat es bei mir praktisch aber nie...

Bart Simpson

17.08.2005 - 12:51 Uhr

Bin mir zwar nicht sicher, würde mich aber nicht wundern wenn der neue Benutzer nicht die Berechtigung zum ändern von Objekten im SQL Server hätte (Rolle "db_ddladmin" oder höher) . Das lässt sich leicht abfragen und könnte deshalb in VS.net implementiert sein...

Bart Simpson

16.08.2005 - 13:09 Uhr

Original von Der Eisbär
Prinzipiell würde ich niemandem, der in Richtung IT-Entwicklung gehen will, ein Unistudium empfehlen, da dies zu theoretisch und praxisfremd ist.

100% ACK

Ich hab 2 Jahre mit 'nem angefangenen Informatikstudium verbracht... Pure Theorie und IMHO völlig veraltet. Mittlerweile gehör ich aber trotzdem zur "Brötchenfraktion" - Der Ausbildung zum Fachinformatiker / Anwendungsentwicklung sei dank.

Für alle die planen auch den Weg über die Ausbildung zu gehen (ja, es ist nicht einfach überhaupt 'ne Stelle zu finden, aber) : Seht Euch die Firma vorher genau an! Ich persönlich hatte richtig Schwein (30 Mann Firma, alle per Du, super Arbeitsklima und v.a. wurde echt was für die Ausbildung getan) - aber einige meiner Berufsschulkollegen/-kolleginnen hatten da echt den Griff ins Klo.

Über Details aus meiner Firma darf ich nichts sagen, deshalb nur soviel:
95% C#, Anbindung an SQL Server, Webservices... Kurzum: .net pur 😉

Bart Simpson

05.08.2005 - 09:15 Uhr

Also ich weiss nun nicht, ob sich was internes an der UDP Implementierung bei SP2 geändert hat - ich glaub aber nicht, dass dem (zumindest für korrekte UDP Datagramms) so ist... schliesslich gibt's UDP schon recht lange in praktisch unveränderter Form (-> Es könnte wenn überhaupt nur ein Bugfix seitens MS sein).

Wenn die Firewall aus ist, liegt's wohl auch nicht daran... Was mich sehr erstaunt ist allerdings die Tatsache, dass Du mit netstat nichts lauschen siehst. IMHO gibt's damit nur zwei Möglichkeiten:
1.) Deine Listener-Klasse ist nicht richtig initialisiert (was aber eher unwahrscheinlich sein dürfte, weil's ja auf W2K läuft, ausser es gibt mir unbekannte Config-Faktoren darin)

2.) (Für mich wahrscheinlicher) Deine Listener-Klasse "läuft", wird aber durch irgendetwas davon abgehalten wirklich die Netzwerkfunktionen von XP zu nutzen. In Frage käme dann z.B. sowas wie herbivore in seinem Posting zitiert hat.

Bin mal gespannt wie sich das weiterentwickelt 😉

Bart Simpson

04.08.2005 - 19:59 Uhr

Keine Garantie, da nicht geprüft - aber: Ich würde mal sehr stark auf die bei SP2 standartmässig aktivierte Windows-Firewall tippen.
Wenn Dein Client läuft und lauscht, dann müsstest Du auf der Kommandozeile mit netstat -n -a sehen dass auf dem Port ein "Listen" ist.
Wenn das nicht so ist, dann liegt's am Programm. Wenn doch, und es kommt einfach nix an, dann ist's (sind's) ziemlich sicher die Firewall(s) (falls z.B. auch noch ein Router mit Paketfilter davorgeschaltet ist.

Bart Simpson

04.08.2005 - 12:38 Uhr

Es sollte sehr wohl möglich sein, das Ganze in der gleichen Klasse zu lösen - aber nicht im Konstruktor, sondern in einer statischen Methode...

Bart Simpson

26.07.2005 - 16:10 Uhr

Genau die automatisch von VS.net erzeugt Proxy-Klasse meine ich...



// Instanz der Proxy-Klasse erzeugen
AnyWebserviceClient c = new AnyWebserviceClient();

//CookieContainer zuweisen 
c.CookieContainer = new System.Net.CookieContainer();

26.07.2005 - 13:55 Uhr

Ich hatte das gleiche Problem-ist ganz einfach, aber schlecht dokumentiert:

Deine Client-Proxy-Klasse hat eine Property die irgendwas mit CookieContainer oder so ähnlich heisst (..hab leider grad keine Doku zur Hand). Diesem musst Du einen CookieContainer zuweisen - sonst geht gar nix.

Bart Simpson

19.07.2005 - 16:23 Uhr

Hmm... ich weiss ja nu nicht, was Du da programmierst (wird doch wohl hoffentlich nichts böses, oder?), aber das Starten des Taskmanagers an sich kannst Du wohl nicht unterbinden (und das ist aus "Windows-Sicht" auch gut so). Was Du aber tun können müsstest ist, dem Taskmanager die Botschaft zu schicken, er möge sich doch bitte beenden... so lässt sich das Ganze "ungehen".

Bart Simpson

10.07.2005 - 13:22 Uhr

Der User den der IIS für anonyme Anmeldungen verwendet hat erst mal nichts mit dem User zu tun, der benutzt wird, wenn die Anmeldung an die DB erfolgt.

->Um einen Report anzuzeigen muss der doch auch eine Datenquelle haben. In dieser wird u.a. die Verbindung zur DB konfiguriert, mithin auch der User der in der DB verwendet werden soll. Wenn Du da das richtige einträgst, dann sollte es auch klappen...

Bart Simpson

08.07.2005 - 10:12 Uhr

Original von Xqgene
kann man deine dll mal zum "spielen" haben?

ich würde gerne deine funktion mal testen.

Wird leider nicht klappen - die Dll tut ohne die zugehörige Hardware gar nichts!
Mal abgesehen von irgendwelchen Zugriffsverletzungen 😉

Und: Ich weiss nicht, ob ich das (aus rechtlichen Gründen) überhaupt dürfte...

Bart Simpson

07.07.2005 - 23:45 Uhr

Von hinten durch die Brust ins Auge 😉 Ich hab jetzt eine Managed C++ Klasse erstellt (naja, sagen wir mal sie ist da-hat aber erst eine Methode...).
Ausserhalb der Klasse, aber im gleichen Modul hab ich dann die aufzurufenden Funktionen als external deklariert. Die kann ich dann wiederrum von Klassenmethoden aus aufrufen, welche zu guter letzt aus meiner C# App aufgerufen werden....

Das klappt tatsächlich und ich kann damit Strings als Parameter übergeben und auch wieder als out-Parameter holen... Aber das kann's ja wohl nicht sein, oder? Das ist ja umständlicher als irgendwas... Und das Beste dran: Warum zur # ist das .net Framework bei Managed C++ offensichtlich "schlauer" als bei der "speziell dafür designten Sprache" C#???
Innerhalb der C++ Klasse gibt's nämlich überhaupt kein Problem mit dem Marshalling (falls man das an der Stelle so nennen kann) - Ich kann direkt System::String* übergeben bzw. zurückgeben (was dann von C#-Seite aus string entspricht) und das an die externen Funktionen als char* übergeben...

@svenson: Noch eine neue Idee - klingt aber noch komplexer. Da muss ich mich ja direkt selbst um den Speicher kümmern... Ist ja fast wie in alten Turbo Pascal Tagen 🙂
Oder sieht das Ganze mittlerweile einfacher (und vor allem "sicherer") aus? Ein kurzes Beispiel wäre nett.

Bart Simpson

05.07.2005 - 10:35 Uhr

Die Dll entstammt einer Hardwaresteuerung von der's den Hersteller leider nicht mehr gibt... Ich muss also wohl oder übel mit dem Leben, was man mir vorgesetzt hat.

Die Idee mal mit managed C++ ran zu gehen klingt interessant - aber kann das was bringen? Ich hab noch nicht mit den managed Extensions gearbeitet, aber gibt's da dann noch char* und so'n Zeug? Ich dachte die CLR übernimmt auch für C++ so Sachen wie Zeigerarithmetik?

Bart Simpson

05.07.2005 - 09:22 Uhr

Also das vorherige Füllen (ich hab's mit ASCII(0) und Space propiert) bringt auch nix... langsam weiss ich echt keinen Rat mehr 😦

Irgendwer noch irgendwelche Konstruktiven Vorschläge? Mittlerweile bin ich auch für die abwegig klingenden offen...

Bart Simpson

04.07.2005 - 14:54 Uhr

Schau Dir doch mal die Doku zu System.IO.DirecoryInfo an. Damit kannst Du die Dateien und Verzeichnisse in einem Verzeichniss abfragen. Musst nur noch rekursiv durch die Struktur gehen und jeweils die Nodes in Deinem Treeview anlegen.

Bart Simpson

04.07.2005 - 14:32 Uhr

Hätt ich vielleicht dazu schreiben sollen: Der Stringbuilder ist natürlich erzeugt und ich geb auch genug Platz mit... Ich hab sogar schon versucht 'nen Stringbuilder mit mehr als 2*len anzulegen, falls es irgendwelche Problem mit ANSI/Unicode oder so geben sollte... Keine Wirkung.

@Programmierhans: Der Stringbuilder gefüllt? Sollte doch wohl nicht nötig sein, oder? Wenn ich das richtig verstanden hab, muss nur die Capacity vom Stringbuilder (sprich: dessen Puffer) groß genug sein. Oder bin ich da auf dem Holzweg?

Ich tippe darauf, dass es wohl am falschen Marshalling des Strings liegt... Aber wie zur Hölle krieg ich raus, welchen UnmanagedType ich denn nehmen muss?
Mittlerweile hab ich in dem (na nennen wir's mal beschönigend🙂 SDK folgendes gefunden:

Eingaben müssen im Zeichensatz ISO 8859-1 übergeben werden. Auch die Ausgaben erfolgen
in diesem Zeichensatz. Sollen in Sonderfällen andere Zeichensätze zum Einsatz kommen (z.B.
MSDOS-Zeichensatz), müssen die Zeichen umgesetzt werden.

Das heisst doch es ist irgendein Nicht-Unicode Zeichensatz, oder? Es müsste also irgenwas wie MarshallAs(UnmanagedType.LPStr) sein, denk ich...
ABER: Bei dem speziellen Beispiel geb ich natürlich nichts mit, es ist ja eine reine Ausgabefunktion - d.h. Unabhängig davon ob ich was sinnvolles krieg oder nur Müll, es müsste doch zumindest klappen und im Puffer des Stringbuilders müsste irgendwas sein. Und vor allem sollte ich nicht die Exception kriegen... verzweifel

Bart Simpson

04.07.2005 - 10:39 Uhr

Ich versuche verzweifelt eine C++ DLL via P/Invoke zu nutzen. Im Prinzip klappt das Ganze auch, aber es gibt da einige Methoden, die char* Parameter benutzen um strings zurückzugeben. Beispiel:

int get_version (int session, char * version, size_t len);

Das wird dann folgendermaßen eingebunden:

public static extern int get_version (int session, System.Text.StringBuilder version, int len);

Ich hab's schon in allen möglichen Variationen probiert z.B. ref auf den Stringbuilder, MarshallAs(...) - Resultat beim Aufruf ist immer das Gleiche: System.NullReferenceException.

Hat irgendwer 'ne Ahnung? Ich hab schon 20 Artikel in der MSDN zum Thema Marshalling von Strings gelesen. Dummerweise war natürlich kein Einziger dabei, der genau das beschreibt was ich bräuchte...

Bart Simpson

27.06.2005 - 11:44 Uhr

... oder über die Windows API:


public enum DriveType
	{
		/// <summary>
		/// The drive type cannot be determined.
		/// </summary>
		Unknown = 0,
		/// <summary>
		/// The root path is invalid. For example, no volume is mounted at the path.
		/// </summary>
		NoRootDir,
		/// <summary>
		/// The disk can be removed from the drive.
		/// </summary>
		Removeable,
		/// <summary>
		/// The disk cannot be removed from the drive.
		/// </summary>
		Fixed,
		/// <summary>
		/// The drive is a remote (network) drive.
		/// </summary>
		Remote,
		/// <summary>
		/// The drive is a CD-ROM drive.
		/// </summary>
		CdRom,
		/// <summary>
		/// The drive is a RAM disk.
		/// </summary>
		RamDisk
	}


	/// <summary>
	/// Retrieves Information about a drive
	/// </summary>
	public class DriveInfo
	{
		private DriveInfo()
		{			
		}

		public static DriveType GetType(string Path)
		{
			DirectoryInfo di = new DirectoryInfo(Path);
			di = di.Root;
			uint res = GetDriveType(di.FullName);
			if ((res>=0)&&(res<7)) return (DriveType)res;
			return DriveType.Unknown;
		}

		public static string GetVolumeName(string Path)			
		{
			DirectoryInfo di = new DirectoryInfo(Path);
			di = di.Root;
			uint serNum = 0;
			uint maxCompLen = 0;
			StringBuilder VolLabel = new StringBuilder(256); // Label
			UInt32 VolFlags = new UInt32();
			StringBuilder FSName = new StringBuilder(256); // File System Name			
			long Ret = GetVolumeInformation(di.FullName, VolLabel, (UInt32)VolLabel.Capacity, ref serNum, ref maxCompLen, ref VolFlags, FSName, (UInt32)FSName.Capacity);
			return VolLabel.ToString();
		}


		public static string GetVolumeSerial(string Path)
		{
			return GetVolumeSerial(Path,"X");			
		}

		public static string GetVolumeSerial(string Path, string Format)
		{
			DirectoryInfo di = new DirectoryInfo(Path);
			di = di.Root;
			uint serNum = 0;
			uint maxCompLen = 0;
			StringBuilder VolLabel = new StringBuilder(256); // Label
			UInt32 VolFlags = new UInt32();
			StringBuilder FSName = new StringBuilder(256); // File System Name			
			long Ret = GetVolumeInformation(di.FullName, VolLabel, (UInt32)VolLabel.Capacity, ref serNum, ref maxCompLen, ref VolFlags, FSName, (UInt32)FSName.Capacity);
			return serNum.ToString(Format);			
		}

		[DllImport("KERNEL32.DLL")]
		private static extern uint GetDriveType(string lpRootPathName);

		[DllImport("kernel32.dll")]
		private static extern long GetVolumeInformation(string PathName, StringBuilder VolumeNameBuffer, UInt32 VolumeNameSize, ref UInt32 VolumeSerialNumber, ref UInt32 MaximumComponentLength, ref UInt32 FileSystemFlags, StringBuilder FileSystemNameBuffer, UInt32 FileSystemNameSize);
	}

Bart Simpson

23.06.2005 - 01:23 Uhr

Wenn Du das Ganze via XmlDocument lädtst - ganz einfach...


XmlDocument doc = new XmlDocument();
			doc.Load("file.xml");
			XmlNode node = doc.CreateNode(XmlNodeType.Element,"FILE","");
			XmlAttribute attr = doc.CreateAttribute("size");
			attr.Value = "12,5";
			node.Attributes.Append(attr);
         // hier gibt's natürlich zig Varianten 
         //um an die richtige Stelle zu "navigieren"...
			doc.DocumentElement.ChildNodes[0].AppendChild(node);


Bart Simpson

22.06.2005 - 17:52 Uhr

Bin mir auf die Schnelle zwar nicht sicher, aber theoretisch müsste es genügen in der Schleife Application.DoEvents(); aufzurufen. Dann sollten die aufgelaufenen Events abgearbeitet werden und das Programm nicht mehr blockieren.

Bart Simpson

22.06.2005 - 17:49 Uhr

Versteh ich Deine Aufgabenstellung richtig? Du willst die Zahlen von 5-25 in zufälliger Reihenfolge, ohne doppelte?
Klingt für mich als gäbe es einen wesentlich effizienteren Ansatz (Ok, bei grade mal 20 Zahlen macht das vielleicht nicht viel aus, aber es geht ja ums Prinzip...):

Einfach die gewünschten Zahlen in 'ne Liste packen und mischen... (Für's Mischen gibt's einen sehr einfachen und effizienten Ansatz, den ich gern auch noch "skizzieren" kann - einfach nachfragen)

Bart Simpson

22.06.2005 - 17:44 Uhr

Also im Prinzip klappt das Debuggen wie Ihr es hier beschreibt schon - ich finde es allerdings äusserst unpraktisch...

Stattdessen verwende ich zum debuggen von Services gerne folgenden "Umweg":

Die eigentliche Funktionalität des Service wird in einer Klasse gekapselt (ggf. auch mehrere, entscheident ist die Start, Stop usw. Methoden in einer Klasse zusammen zu haben). Der eigentliche Service verwendet dann genau diese Klasse (ist also nur eine Art Wrapper drumherum).

Dann mach ich in der Solution einfach noch zusätzlich 'ne kleine Testapp, die über Buttons genau das gleiche wie die Service.exe tut, nämlich starten, stoppen usw. Und das Ganze natürlich mit der gleichen Klasse, die die Arbeit erledigt... Fertig. Die Testapp lässt sich nun direkt starten und debuggen (muss also auch nicht erst via Instalutil installiert werden). Erst wenn die Arbeitsklasse fehlerlos arbeitet mach ich dann einen Build der Service.exe und installier sie...

Das Ganze klingt zwar umständlich - ich find's aber äusserst angenehm (zumindest im Verlgeich mit einem direkten Debuggen)

Bart Simpson

22.06.2005 - 13:11 Uhr

Ich denke dass das nur klappt, wenn Du die eigentliche "Arbeit" in einem 2. Thread ausführen lässt. Dann kann der Hauptthread entweder auf das Ende des 2. warten oder aber bei Tastendruck den 2. Thread abbrechen.

Bart Simpson

16.06.2005 - 10:48 Uhr

Original von S.H.-Teichhof
Mit dem Timer und der Skalierbarkeit hast du zwar grundsätzlich recht aber da tut sich dann schon wieder ein Problem auf wie errechnest du wie schnell ein Server ist bzw. gibt es dann eine Option den Protzes zu beschleunigen

Meiner Meinung nach wäre das Errechnen der Laufzeit für einen Durchlauf (ich denke darauf beziehst Du Dich, oder?) nicht wirklich nötig. Man müsste sich nur "merken" wieviele Threads grade laufen und diesen Werten immer inkrementieren wenn ein neuer Durchlauf startet bzw. dekrementieren wenn er endet - Dann würde bei Überschreiten des Grenzwertes einfach "nichts" gemacht und der erst z.B. das nächste Timer-Event tut wieder was.

Original von herbivore
Wenn mehrere Threads "zusammengeführt" werden sollen, könnte man einen Dienst implementieren. Dieser Dienst nimmt Requests (Remoting) entgehen und speichert diese in einer Queue (aber nicht in der DB, sondern im Speicher). Die Anfragen dieser Queue verteilt er auf seine eigenen Thread, deren Anzahl man ja selbst wählen kann. Diese Threads (evtl. eben genau einer) tun die eigentliche Arbeit. Das Ergebnis wird an den urspünglichen Thread als Rückgabewert der synchronen Request-Methode zurückgegeben.

Hmm... interesanter Ansatz. Aber wozu dann eigentlich den IIS? Dann könnt ich doch auch gleich direkt von den Clients aus auf den Dienst zugreifen, oder?

Original von herbivore
Ich halte es aber eher für ein Gedankenspiel, weil ich denke, dass man die Anzahl der Threads im IIS auch direkt beeinflussen kann.

Aber doch nur die Gesamtzahl der Threads im IIS (ich glaub über die machine.config) - sprich: über alle Webapps hinweg, oder? Und vor allem: Wie reagiert der Webservice-Client auf sowas, wenn der IIS "keinen Thread mehr frei hat"?

Bart Simpson

16.06.2005 - 01:39 Uhr

Wie das genau intern geregelt ist, weiss ich leider nicht und kann's im Moment (bin ein wenig kränklich und "arbeite" nur remote von daheim aus...) auch nicht wirklich rausfinden... Aber das ist eine gute Idee, das mal noch genauer unter die Lupe zu nehmen.

Die Tricksereien die Du im IIS vorschlägst werd ich mal tunlichst unterlassen - wie erwähnt geht's bei dem Ganzem um Hardwarezugriffe, und das muss a) stabil und b) sicher ablaufen - es muss also "sauber" funktionieren.

In der Zwischenzeit hab ich über folgenden Ansatz gegrübelt:

  • Der Webservice-Aufruf läuft (wie Du vorgeschlagen hattest) asynchron
  • Der Webservice trägt alle Requests in eine Queue ein (implementiert z.B. als 'ne Tabelle in 'ner DB)
  • Der Webservice wartetet...

Hier schlägt nun in meinem Ansatz eine Eigenheit zu, die ich noch nicht erwähnt hatte, nämlich die Tatsache, dass der Aufruf der Dll Funktionen ähnlich wie eine Verbindung über z.B. TCP abläuft: Verbindung aufbauen - Aktion1 - Aktion 2 [...] - Verbindung schliessen. Und dabei das wichtigste: Der Overhead zum Auf- und Abbau der Verbindung ist das zeitlich krititschte Element->Wiedervenden der Verbindung kann viel bringen.

  • Der Webservice hat in der Application einen Timer laufen, der pro Auslösung den jeweils höchst priorisierten Eintrag in der Queue abarbeitet
  • Die Arbeitsmethode "trägt das Ergebniss in die Queue ein"
    -> Die Webmethod "bemerkt" das Ergebniss (wie genau sie das bemerkt, weiss ich auch noch nicht...) und gibt es zurück.

Damit würde genau ein (bzw. genau soviele wie ich Timer starte) Thread auf die Dlls zugreifen.

Alternativ hab ich mir überlegt eine Art Singleton Klasse anzulegen, die sich also nur einmal instanzieren lässt und die eigentliche Arbeit erledigt. Dann könnte die Webmethod versuchen, die Hilfsklasse zu instanziieren und legt sich bei einem Fehlschlag quasi schlafen.

Vorschlag 1) hätte den Vorteil sehr simpel skalierbar zu sein, da das Anlegen der Timer (sprich: deren Anzahl) über die Zahl der parallelen Aufrufe entscheidet. Der Haken ist allerdings die recht komplexe und umständliche Art der Rückmeldung an die Webmethod.

Bei 2) ist die Implementierung recht einfach, dafür die Skalierbarkeit nicht so schön machbar...

Weitere Vorschläge? Oder besser gefragt: a) Geht das überhaupt so, wie ich mir das vorstell oder ist ein grundsätzliches Problem zu erwarten?
und noch wichtiger b) Gibt's bessere Ansätze??? Mir gefallen beide nicht wirklich... Irgenwie sieht mir das nach Gefrikel aus 😉

Bin für alle Tips & Ratschläge dankar!!!

Bart Simpson

15.06.2005 - 20:04 Uhr

Sorry für den nichtssagenden Titel - aber ich wusst einfach nicht, wie ich das Problem in einem Satz beschreiben soll 😉

Zum Thema: Ich bin in der Planung eines größeren Projekts. Dabei sollen mehrere Clients per Webservice bestimmte Methoden am Server ausführen. Diese Methoden wiederrum sollen (u.a.) per PInvoke Funktionen aus C/C++ Dlls aufrufen.
Soweit so gut - jetzt wird's spannend...

Die C/C++ Dlls haben ein paar Mechanismen integriert die ähnlich wie ein Lizensierungssystem arbeiten(nein, es geht mir nicht um Verletzung der Lizenzbedigungen o.ä!):

Die Funktionen können nur bis zu einer begrenzten Zahl "instanziiert" werden. (Im Hintergrund geht's da v.a. um Hardware-Resourcen-Management). Es können also zeitgleich immer nur eine begrenzte Zahl von Clients bedient werden - alles was über das Limit geht, bekommt Fehlermeldungen.

Da nun die die Clients das nicht mitkriegen (und auch nicht sollen), der IIS aber jede Client-Verbindung als eigenen Thread laufen lässt steht ich vor einem kleinen Dilema: Die Clients kümmern sich nicht um das Problem - aber der IIS muss...

Ich kenne leider keine tiefergehenden Details zu den Dlls, da diese gekauft sind... V.a. hab ich keine Ahnung wie die Maximale Zahl der Clientzugriffe tatsächlich intern verwaltet wird. Deshalb muss das Ganze wohl oder über im IIS gehandlet werden.

Wie krieg ich die einzelnen Threads des IIS dazu sich quasi zusammenlegen zu lassen - sprich: zu synchronisieren und ggf. in einer Queue die momentan nicht behandelbaren Anfragen zurückzustellen?

Irgendwelche brauchbaren Ansätze? Hat jemand schon mal mit der Problematik zu tun gehabt?

Bart Simpson

15.06.2005 - 11:44 Uhr

In der Reference.cs was zu ändern wäre nicht gut - denn solange du entwickelst musst Du evtl. die Referenz auf den Webservice aktualisieren, und dann wäre das wieder weg...

Nein der Weg ist viel simpler: In der Reference.cs wird ja genau die Proxy Klasse erzeugt...


			yournamespace.yourwebservice ws = new yournamespace.yourwebservice();
			ws.Url = System.Configuration.ConfigurationSettings.AppSettings["Key"];

Damit erzeugst Du die Instanz und weisst die URL aus der App.config mit dem definierten Key zu.

Bart Simpson

15.06.2005 - 11:07 Uhr

Weshalb sollte die Referenz neu eingebunden werden müssen? Du änderst doch nichts am Webservice selbst, sondern der Service zieht quasi um. Genau dafür gibt's die Property Url. Die tatsächliche Url kannst Du z.B. in einem config-file speichern. Alles was Du zun musst ist dann die Client-Proxy-Klasse neu zu initialisieren wenn sich die Adresse ändert.

Bart Simpson

11.06.2005 - 17:03 Uhr

Also wenn ich das richtig seh, dann fehlt in Deiner URL der Servername.
Probier's mal mit http://localhost/WebApplication1 oder http://server/WebApplication1 , je nachdem ob Du den Server lokal betreibst oder es ein anderer Rechner ist...

Bart Simpson

10.06.2005 - 13:04 Uhr

Hat zwar nicht direkt mit Deiner Frage zu tun, aber vielleicht hilft's Dir trotzdem irgendwie weiter:

Ich hatte vor einiger Zeit das gleiche Dilemma, aber nicht die Zeit (und zugegebenermasen auch nicht die Lust) das ganze programmiertechnisch zu lösen. Ein bisschen Googlen brachte mich dann zu einem kleinen Tool namens "OutlookClickYes" (genau Schreibweise bin ich mir nicht ganz sicher) und dieses nette Programm macht auch genau das, was der Name verspricht 🙂

Bart Simspon

10.06.2005 - 12:58 Uhr

Das direkte verwenden des SqlClient über's Web würde ich nicht empfehlen - denn das heisst, der SQL Server ist "frei" im Netz erreichbar... Ich erinner da mal nur an SQL-Slammer 😉

Die Verwendung von XML erzeugt natürlich einen gewissen Overhead, den ich persönlich aber gerne in Kauf nehmen würde. Allerdings würde ich dann keine XML Dateien downloaden, sondern eine direkte Kommunikation via Webservice einrichten (Den Webserver brauchst Du so oder so, egal ob zum Download oder zum Ausführen des Webservice).

Bart Simpson

09.06.2005 - 15:35 Uhr

Einfach (aber sicher nicht perfomant) wäre einfach die Bilder in ein Image-Objekt zu laden und dann die entsprechenden Properties daraus auszulesen.

Bart Simpson