Laden...

Profil von silversurger

myCSharp.de - Member Mitglied seit

Alle Beiträge

Ich habe es nun zunächst aus Zeitgründen so gelöst, dass ich den Stream als Attribut meinem Object zuweise... ich weiß nicht, ob das eine saubere Lösung ist, aber so habe ich zumindest auf den ersten Blick das Verhalten, das ich mir wünsche...

und

Die Daten kommen aus der App und sterben dort auch wieder

habe ich damit m.E. auch erfüllt.

Das ganze mit Intrerfaces/Events/Rechteverwaltung zu lösen werde ich mir bei Gelegenheit mal zu Gemüte führen...

Vielen Dank für eure Tipps!

Auch den FileSystemWatcher werde ich mir mal anschauen, jedoch glaube ich nicht, dass der für diese Aufgabe geeignet ist, da nicht mein Programm auf Änderungen im Betriebssystem reagieren soll, sondern das Betriebssystem darauf reagieren soll, dass mein Programm eine Datei verwendet...

Grüße,
silversurger

Ich möchte eigentlich verhindern, dass mein funktionaler Code (d. h. Object und App) von meinem GUI-Code irgendwelche Kenntnis besitzt...

Aber ich könnte doch jedem ObjectView den zugehörigen Stream als Referenz übergeben... Dann müsste der Stream doch über die Dispose-Funktion auch geschlossen werden, oder?

Hallo jaensen,

danke erstmal für deine Antwort.

Ich meine damit zum Beispiel ein Verhalten wie MS Word. Wenn man eine Datei in Word geöffnet hat und versucht, diese Datei über den Explorer zu löschen, teilt einem Windows mit:

"Datei xx kann nicht gelöscht werden. Die Datei wird von folgendem Programm verwendet:

Microsoft Word for Windows

Sie müssen schließen blabla..."

Und genau das würde ich auch gerne erreichen....

Hallo zusammen,

ich habe eine vielleicht etwas theoretische Frage:

Ich habe ein Programm, das als MDI-Anwendung implementiert ist. Es gibt zwei Arten von Fenstern, AppView als Hauptfenster und nennen wir es mal ObjectView für die MDI-Childs. Entsprechend gibt es eine Klasse App, die allgemeine Funktionen bereitstellt und eine Klasse Object für die einzelnen Objekte, die in den MDI-Childs dargestellt werden.

Die Objects können mit Serialisierung gespeichert werden. Hierzu geh ich bisher folgendermaßen vor:

  • Im Menü von AppView wird speichern aufgerufen.
  • AppView nimmt das aktuelle MDI-Child und davon das zugehörige Object
  • AppView übergibt an App das Object
  • App öffnet einen Stream
  • App schreibt das Object in den Stream / in die Datei
  • App schließt den Stream

Das funktioniert alles wunderbar, mit einem kleinen Schönheitsfehler:
Dadurch, dass der Stream geschlossen wird, kann die eben geschriebene Datei außerhalb des Programms völlig nach Belieben manipuliert werden, d. h .gelöscht, kopiert oder verschoben werden. Das will ich aber verhindern. Ich möchte also ein Verhalten wie jedes andere Programm es hat, nämlich dass mir Windows sagt, dass diese Datei gerade von meinem Programm verwendet wird.

Ich weiß, dass ich das erreichen kann, wenn ich den Stream nicht schließe. Allerdings habe ich da bei meiner bisherigen Programmierung das Problem, dass wenn ich ein ObjectView und damit das Object schließe der Stream nicht geschlossen wird, da dieser nur lokal von App erzeugt wird.

Heißt das nun, dass ich den Stream irgendwie mit dem jeweiligen Object verknüpfen müsste? Hier gibt es doch bestimmt irgendein Framework oder Standard-Vorgehen, wie das realisiert wird? Ich bin bisher leider nicht fündig geworden.

Hier noch mal die Funktionen von App, die von AppView aufgerufen werden.


public bool SpeicherObject(Object object)
{
	try
	{
		BinaryFormatter formatter = new BinaryFormatter();
		Stream stream = new FileStream(object.Name,FileMode.Create);
		formatter.Serialize(stream,object);
		stream.Close();
	}
	catch
	{
		return false;
	}
	return true;
}

public Object LadeObject(Stream stream)
{
	Object object;
	try
	{
		BinaryFormatter formatter = new BinaryFormatter();
		object = (Object)formatter.Deserialize(stream);
		stream.Close();
	}
	catch
{
             return null;
       }
	return object;
}

Hier einfach den Stream nicht zu schließen, ist doch bestimmt nicht das optimale Vorgehen. Ich steh ein bisschen auf dem Schlauch....

Danke schon mal für jeden Tipp!

Fast vergessen: Die MDI-Childs werden so geschlossen (glaub auch nicht das optimale Vorgehen...):


private void menuItemSchliessen_Click(object sender, System.EventArgs e)
{
	if (this.ActiveMdiChild != null)
	{
		this.ActiveMdiChild.Dispose();
	}
}

Ps: Sollte ich im falschen Forum gepostet haben, bitte verschieben...

09.01.2008 - 14:53 Uhr

habs selber hinbekommen....

Lösung:

  • key auf 16 byte reduzieren
  • padding auf PaddingMode.None setzen
  • MemoryStream im Konstruktor schon das Array mit Werten übergeben, also
    data = new MemoryStream(dataToDecrypt)
    und nicht
    data = new MemoryStream()
    data.Write(dataToDecrypt,0,dataToDecrypt.Length)

schönen Tag euch noch

09.01.2008 - 12:09 Uhr

Hallo zusammen!

Ich bin mal wieder auf eure Hilfe angewiesen... ich versuche einzelne byte-Arrays mit Hilfe des Rijndael-Algorithmus zu ver- und entschlüsseln. Die Arrays haben immer garantiert eine Größe von 16 Byte, was einer Aes-Blocklänge genau entspricht. Jetzt erst mal der Code, dann erklär ich mein Problem:


public static void Encrypt(Message message)
		{
			//create byte array from first part of the message (i.e. content, timeStamp, id)
			byte[] dataToEncrypt = new byte[16];
			for (int i = 0; i < message.content.Length; i++)
			{
				dataToEncrypt[i] = message.content[i];
			}
			for (int i = 0; i < message.timeStamp.Length; i++)
			{
				dataToEncrypt[i+8] = message.timeStamp[i];
			}
			for (int i = 0; i < message.id.Length; i++)
			{
				dataToEncrypt[i+12] = message.id[i];
			} 
			
			//encrypt first part of the message
			byte[] encryptedData = AesEncrypt(dataToEncrypt);
			
			//copy encrypted data into message
			for (int i = 0; i < message.content.Length; i++)
			{
				message.content[i] = encryptedData[i];
			}
			for (int i = 0; i < message.timeStamp.Length; i++)
			{
				message.timeStamp[i] = encryptedData[i+8];
			}
			for (int i = 0; i < message.id.Length; i++)
			{
				message.id[i] = encryptedData[i+12];
			}
			
			//create byte array from second part of the message (i.e. hash)
			dataToEncrypt = message.hash;
			
			//encrypt second part of the message
			encryptedData = AesEncrypt(dataToEncrypt);
			
			//copy encrypted data into message
			message.hash = encryptedData;
			

			//Test
			Decrypt(message);
		}

		public static void Decrypt(Message message)
		{
			//create byte array from first part of the message (i.e. content, timeStamp, id)
			byte[] dataToDecrypt = new byte[16];
			for (int i = 0; i < message.content.Length; i++)
			{
				dataToDecrypt[i] = message.content[i];
			}
			for (int i = 0; i < message.timeStamp.Length; i++)
			{
				dataToDecrypt[i+8] = message.timeStamp[i];
			}
			for (int i = 0; i < message.id.Length; i++)
			{
				dataToDecrypt[i+12] = message.id[i];
			}

			//decrypt first part of the message
			byte[] decryptedData = AesDecrypt(dataToDecrypt);
			
			//copy decrypted data into message
			for (int i = 0; i < message.content.Length; i++)
			{
				message.content[i] = decryptedData[i];
			}
			for (int i = 0; i < message.timeStamp.Length; i++)
			{
				message.timeStamp[i] = decryptedData[i+8];
			}
			for (int i = 0; i < message.id.Length; i++)
			{
				message.id[i] = decryptedData[i+12];
			}
			
			//create byte array from second part of the message (i.e. hash)
			dataToDecrypt = message.hash;
			
			//decrypt second part of the message
			decryptedData = AesDecrypt(dataToDecrypt);

			//copy decrypted data into message
			message.hash = decryptedData;
		}

		private static byte[] AesEncrypt(byte[] dataToEncrypt)
		{
			Rijndael aes = Rijndael.Create();
			//aes.BlockSize = 128;
			aes.Mode = CipherMode.ECB;
			aes.Key = key;
			aes.IV = iv;
			ICryptoTransform transform = aes.CreateEncryptor();
			byte[] encryptedData = new byte[16];
			transform.TransformBlock (dataToEncrypt,0,dataToEncrypt.Length,encryptedData,encryptedData.Length);
			return encryptedData;
		}

		private static byte[] AesDecrypt(byte[] dataToDecrypt)
		{
			Rijndael aes = Rijndael.Create();
			//aes.BlockSize = 128;
			aes.Mode = CipherMode.ECB;
			aes.Key = key;
			aes.IV = iv;
			byte[] decryptedData = new byte[16];
			ICryptoTransform transform = aes.CreateDecryptor();
			transform.TransformBlock (dataToDecrypt,0,dataToDecrypt.Length,decryptedData,decryptedData.Length);
			return decryptedData;
		}

		private static byte[] AesEncrypt2(byte[] dataToEncrypt)
		{
			Rijndael aes = Rijndael.Create();
			//aes.BlockSize = 128;
			aes.Mode = CipherMode.ECB;
			aes.Key = key;
			aes.IV = iv;
			byte[] encryptedData = new byte[16];
			MemoryStream data = new MemoryStream();
			ICryptoTransform transform = aes.CreateEncryptor();
			CryptoStream cs = new CryptoStream(data,transform,CryptoStreamMode.Write);
			cs.Write(dataToEncrypt,0,dataToEncrypt.Length);
			cs.FlushFinalBlock();
			encryptedData = data.ToArray();
			cs.Close();
			data.Close();
			return encryptedData;
		}

		private static byte[] AesDecrypt2(byte[] dataToDecrypt)
		{
			Rijndael aes = Rijndael.Create();
			//aes.BlockSize = 128;
			aes.Mode = CipherMode.ECB;
			aes.Key = key;
			aes.IV = iv;
			byte[] decryptedData = new byte[16];
			MemoryStream data = new MemoryStream();
			ICryptoTransform transform = aes.CreateDecryptor();
			data.Write(dataToDecrypt,0,dataToDecrypt.Length);
			CryptoStream cs = new CryptoStream(data,transform,CryptoStreamMode.Read);
			cs.Read(decryptedData,0,decryptedData.Length);
			cs.Close();
			data.Close();
			return decryptedData;
		}

Die Methoden Encrypt und Decrypt sind hauptsächlich dafür verantwortlich, die erforderlichen Daten in ein 16 byte großes Array zu schreiben, die Ver- oder Entschlüsselung aufzurufen und das Ergebnis wiederum zu verarbeiten.

Wie man sieht, habe ich für die Aes-Geschichten schon 2 Wege ausprobiert, AesEncrypt und AesEncrypt2 bzw. AesDecpypt und AesDecrypt2... mit beiden gibts so seine Probleme...

Angefangen bei der ersten Version:
hier erhalte ich bei der TransformBlock()-Methode eine Cryptographic Exception, mit der Meldung "Input buffer contains insufficient data"... würd ich ja verstehen, wenn mein input buffer nicht genau 16 byte groß wär, was ja genau der Aes-Blocklänge entspricht.

Bei der zweiten Version:
bei der Entschlüsselung ist nach cs.Read() das Array decryptedData leer, bzw. mit 0 gefüllt, wie man's sieht...
außerdem erhöht sich beim Verschlüsseln die Länge von encryptedData nach dem Aufruf encryptedData = data.ToArray() von 16 auf 32... das passiert nich, wenn ich cs.FlushFinalBlock() weglasse, was aber nichts an dem Problme beim Entschlüsseln ändert...

die Aes-Blocklänge steht auf 128 (=16 byte), meine Arrays sind garantiert 16 byte groß...

Ich hoffe ihr könnt mir irgendwie helfen, ich weiß jetzt echt nicht mehr weiter...

Bevor ichs noch vergess: Ich entwickel mit dem .net Framework 1.1, höher geht leider nicht...

Danke schonmal und viele Grüße,

silversurger

19.11.2007 - 16:51 Uhr

Hi!

Ich komm an einer Stelle nicht wieter und brauche eure Hilfe!!!

Ich habe ein eigenes Control erstellt, abgeleitet von Windows.Forms.Button. Wenn ich nun dieses Control im Visual Studio Designer auf eine Form ziehe, kommt folgende Fehlermeldung:

"Request for the permission of type System.Security.Permissions.SecurityPermission, mscorlib, Version = 1.0.5000.0, Culture=neutral,PublicKeyToken=b77a5c561934e089 failed."

Wenn ich die Form jedoch als Code öffne und dann starte, funktioniert alles... Es muss wohl an der Anweisung this.Region = new Region(path) in der OnPaint-Methode meines Controls liegen, weil wenn ich das auskommentier kann ich es auf die Form ziehen...

In der Doku steht ja bei dieser Eigenschaft was von UIPermission, aber wie und wo muss ich da etwas einstellen??? Bin in der Hinsicht wirklich ratlos und auch bei meiner Suche nicht so fündig geworden, dass ich es versteh...

Vielen Dank und viele Grüße,

silversurger

Löschst du zufällig vorher die Einträge im ListView?

Falls du das machst, musst du ListView.Items.Clear() verwenden, nicht ListView.Clear(), da diese Funktion auch die Spalten löscht...

So als Idee/Vermutung....

Grüße,

silversurger

23.02.2007 - 10:28 Uhr

Vielen Dank!!!

23.02.2007 - 10:13 Uhr

Hallo zusammen!

Gibt es irgendeine Möglichkeit in C#, Objekte direkt in einer Datei abzulegen, beispielsweise als ein byte-Array, das alle aktuellen Attribut-Werte enthält?

Ich weiß, dass ich die einzelnen Attribut-Werte einfach in bytes konvertieren kann und dann der Reihe nach in einen File schreiben kann, aber die Klasse, um die es sich hier handelt, hat sehr viele Attribute und es wär für mich deutlich einfacher, wenn ich das Objekt komplett in so eine Form konvertieren könnte und in einen File schreiben.

Gefunden habe ich aber dazu bisher nichts... Gibt es die Möglichkeit? Bin ich nur zu dumm sie zu finden?

Danke schon mal und Grüße!

silversurger

ihr seid einfach die besten!!!

Vielen Dank, da wär ich glaub nie draufgekommen, dass das ja nur versteckt wird aber trotzdem selektiert ist...

Kann man jetzt noch irgendwo einstellen, dass die Selektion auch blau erscheint, wenn die ListView keinen Fokus hat?

Cheers

silversurger

Hi!

Ich habe einen Dialog mit 2 ListView Elementen. Der Benutzer soll nun aus jedem ListView einen Eintrag auswwählen...

Dummerweise scheinen die ListViews irgendwie aneinander gekoppelt zu sein, ich kann immer nur insgesamt einen Eintrag auswählen, d.h. in Sadchen Auswahl werden die ListViews wie ein einziges behandelt...

was mach ich hier falsch, oder kann man das gar nicht richtig machen so wie ich das will?

grüße

silversurger

20.04.2006 - 12:23 Uhr

Hi!

Hat jemand von euch eine Idee, wie man die Blockierzeit einer Funktion begrenzen kann?

Konkret geht es um die receive()-funktion von UdpClient. Die Methode blockiert, bis sie Daten empfängt.

Das Problem an der Sache ist: Wenn nun keine Daten eintreffen und ich das Programm beenden will, kann ich den Thread, von dem aus ich die receive aufgerufen habe, nicht beenden, da die Funktion ja noch blockiert...

Bin für jeden Tipp dankbar...

Grüße,

silversurger

11.03.2006 - 17:28 Uhr

Hi!

Ich hoffe ihr könnt mir kurz einen Tipp geben, was ich falsch mache...

Ich möchte ein Programm, das auf einem PDA bereits schön läuft, auch auf dem Desktop zum laufen bringen. Aber ich bekomm eine MarshalDirectiveException.

Zusätzliche Informationen: parameter #3 kann nicht gemarshallt werden: Die Typendefinition für diesen Typ enthält keine Layoutinformationen.

//init sound
			WAVEFORMATEX wftx = new WAVEFORMATEX();
			wftx.wFormatTag = 1;
			wftx.wBitsPerSample = 8;
			wftx.nChannels = 1;
			wftx.nSamplesPerSec = 11025;
			wftx.nAvgBytesPerSec = (uint)(wftx.nSamplesPerSec * wftx.nChannels * (wftx.wBitsPerSample / 8));
			wftx.nBlockAlign = (ushort)(wftx.wBitsPerSample * wftx.nChannels / 8);
			//MessageWindow win = new MessageWindow();
			waveOutOpen(ref deviceHandle, 0, wftx, IntPtr.Zero, 0, 0x10000);

der waveOutOpen-Aufruf ist der, der Probleme macht, und zwar meckert er an dem WAVEFORMATEX-struct rum...

hier noch mein struct:

protected class WAVEFORMATEX
		{
			/// <summary>
			/// Waveform-audio format type. Format tags are registered with Microsoft
			/// Corporation for many compression algorithms. A complete list of
			/// format tags is located in the Mmsystem.h header file. 
			/// </summary>
			public ushort wFormatTag = 0;
			/// <summary>
			/// Number of channels in the waveform-audio data. Monaural data uses one
			/// channel and stereo data uses two channels.
			/// </summary>
			public ushort nChannels = 0;
			/// <summary>
			/// Sample rate, in samples per second (hertz), that each channel should
			/// be played or recorded. If wFormatTag is WAVE_FORMAT_PCM, then common
			/// values for nSamplesPerSec are 8.0 kHz, 11.025 kHz, 22.05 kHz, and
			/// 44.1 kHz. For non-PCM formats, this member must be computed according
			/// to the manufacturer's specification of the format tag.
			/// </summary>
			public uint nSamplesPerSec = 0;
			/// <summary>
			/// Required average data-transfer rate, in bytes per second, for the format
			/// tag. If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec should be equal to
			/// the product of nSamplesPerSec and nBlockAlign. For non-PCM formats, this
			/// member must be computed according to the manufacturer's specification of
			/// the format tag. 
			/// Playback and record software can estimate buffer sizes by using the
			/// nAvgBytesPerSec member. 
			/// </summary>
			public uint nAvgBytesPerSec = 0;
			/// <summary>
			/// Block alignment, in bytes. The block alignment is the minimum atomic unit
			/// of data for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM,
			/// nBlockAlign should be equal to the product of nChannels and wBitsPerSample
			/// divided by 8 (bits per byte). For non-PCM formats, this member must be
			/// computed according to the manufacturer's specification of the format tag. 
			/// Playback and record software must process a multiple of nBlockAlign bytes
			/// of data at a time. Data written and read from a device must always start
			/// at the beginning of a block. For example, it is illegal to start playback
			/// of PCM data in the middle of a sample (that is, on a non-block-aligned
			/// boundary). 
			/// </summary>
			public ushort nBlockAlign = 0;
			/// <summary>
			/// Bits per sample for the wFormatTag format type. If wFormatTag is
			/// WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16. For
			/// non-PCM formats, this member must be set according to the manufacturer's
			/// specification of the format tag. Some compression schemes cannot define
			/// a value for wBitsPerSample, so this member can be zero.
			/// </summary>
			public ushort wBitsPerSample = 0;
		}

Ich hoffe, mir kann jemand von euch sagen, was es mit diesen (fehlenden) Layoutinformationen auf sich hat.

Thx...

08.03.2006 - 17:14 Uhr

War so, das ändern half aber nichts....

Zur Übersicht:

Es gibt eine Methode run(), die in einem eigenen Thread läuft und ständig diese receive-methode wie oben gepostet aufruft. Am Anfang dieser run-methode hab ich jetzt den UdpClient erzeugt, ändert aber nichts am Problem....

08.03.2006 - 16:00 Uhr

Hi!

Ich hab ein kleines Problem....

eigentlich sollte die receive()-methode von UdpClient ja blockieren....tut sie aber nicht. Außerdem spuckt sie immer den Fehler 10022 "ungültiges Argument" aus...

public void receive()
		{
			if (ip == null)
			{
				IPEndPoint dummyEndPoint = new IPEndPoint(IPAddress.Any, portClientToServer);
				try
				{
					soundData = udpClient.Receive(ref dummyEndPoint);
					ip = dummyEndPoint.Address;
					recorderClient = new IPEndPoint(ip, portClientToServer);
				}
				catch(SocketException e)
				{
					Console.WriteLine(e.Message);
					soundData = new byte[5];
				}
			}
			else
			{
				soundData = udpClient.Receive(ref recorderClient);
			}
			buffer.Write(0,soundData,0);
		}

eigentlich wist Sinn und Zweck des Ganzen, dass das Programm wartet, bis über den Port (der übrigens 5902 ist) etwas eingeht und ab da nur noch von diesem Absender etwas empfängt...

Wie gesagt, die Receive-Methode blockiert hier nicht, sie spuckt die Exception aus und macht weiter, obwohl keine Daten kommen...

Kann mir da jemand sagen, was ich falsch mach?

Grüße,

silversurger

01.03.2006 - 20:39 Uhr

Hi!

Ich suche mich jetzt schon den ganzen Tag dumm und dämlich und find nix, ich hoffe, ihr könnt mir helfen...

Ich möchste wissen, wie ich unter c# auf die Soundkarte zugreifen kann.

Dass es mit DirectX geht, weiß ich schon, aber ich möchte für Windows Mobile entwickeln, und da geht das leider nicht (oder ich bin zu doof).

Konkret: Ich möchte den Sound, den ein Benutzer über Mic eingibt, über eine Netzwerkverbindung verschicken und parallel Sound, der über das Netzwerk kommt, ausgeben.

Ich bin für jeden Tipp dankbar.

Viele Grüße,

silversurger