Laden...

Forenbeiträge von Gumble Ingesamt 18 Beiträge

17.12.2004 - 09:16 Uhr

Probier mal
[DllImport("bla.dll", CharSet=CharSet.Ansi)]
und [In,Out] char[] cp2

16.12.2004 - 01:07 Uhr

es lag wohl an dem Console.Out.Write -> Abhilfe schafft Console.Write

Informationen: http://dotgnu.org/pnetlib-doc/System/Console.html#Console.Out%20Property

14.12.2004 - 23:15 Uhr

Die Tester sind alle Consolen-anwendungen. Die Traces kommen von der dll.

14.12.2004 - 18:36 Uhr

vermutlich seh ich den Baum vor lauter Waelder nicht: also wenn ich mein Projekt (verschiedene dlls + tester executable) mit dem VS 7.1 debugge, dann kommen im output fenster auch schon saemtliche traces (console.out/error.write) - starte ich den Tester aber per Hand ueber die Console kommt gar nix.
Ist vielleicht irgend eine Environmentvariable zu setzen oder meine sln oder vcproj setting im arsch?
bitte hilfe! verzweifel

03.12.2004 - 12:19 Uhr

Hier nochmal fuer den geneigten NERO user meine bisherige kleine Komponente 🙂
Anregungen, Verbesserungen und Wuensche gerne aeussern. Vielleicht will ja einer da weiterbasteln - dann koennte man das in die Komponentensammlung aufnehmen.
Was noch geandert werden muss, ist nur noch den 'Trace.Debug' Befehl durch eigene Tracings (oder Console.Write) zu ersetzen.

[Inhalt wrappednero.zip]
CDService_NET.cs
Progress.cs
ColorProgressBar.dll

19.11.2004 - 13:11 Uhr

@guenni81
danke fuer die muehen, aber so wie es laeuft reichts mir erstmal. ist ja eh nur ne komponente zum testen. haette halt gern mehr details ueber nerocom@.net gehabt, aber die informationen sind ja sehr spaerlich. ein (vollstaendiges) uml-ablaufdiagramm waer fein - sowas wie 'select recoder', 'add files', 'add dir', 'EstimateTrackSize'. 'burn' usw und das alles in einem zeitlichen zusammenhang bringen...

18.11.2004 - 16:40 Uhr

also wenn ich den ProgressDialog nach dem BurnIsoAudio-aufruf modal aufrufe:
myProgressForm.ShowDialog();
dann funktionierts fast so ich mir es vorgestellt habe. Leider kann ich fuer die Zeit vor dem Brennaufruf keine Statusinformationen liefern, d.h. waehrend der erste While-schleife. Habe es nicht geschaft, da ein Fenster aufzumachen (darf nicht modal sein!) das auch funktioniert. Events wirft NeroCom da leider auch noch nicht...
anbei mal ein Bildchen wies momentan aussieht.

18.11.2004 - 13:09 Uhr

jaha! schaffst Du schon 😉
hab den wrapper gleich strong named signiert und in den GAC eingetragen.
Wollte vorhin eigentlich noch den Code etwas erklaeren, aber es musste schnell gehen, weil ich erstmal essen gegangen bin 🙂
In der OnProgress (Z. 265) ist ein Aufruf der das ProgressForm mit einem neuen Wert updated - genau dieses laesst mein Programm in die Endlosschleife laufen (im Gegensatz wie ich vorhinbehauptet habe, die Instanz alleine reicht aus)
Ausserdem funktion das Progressfensterchen noch nicht wirklich - es wird nur einmal am Anfang gezeichnet und sonst nie (-> weiss, wenn ichs verschieb). Vermutlich ist da auch noch ein Design(denk)fehler. Soll das Fenster in einen eigenen Thread?

18.11.2004 - 12:08 Uhr

das Ganze Projekt lade ich lieber nicht hoch - nerocom wie in der Anleitung selber wrappen! geht ganz einfach. Hier der Code. Das Progressform ist ein einfaches Windows.Forms.Form mit einem Label und einer Bar.

using System;
using System.IO;
using System.Collections;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
using NEROLib;

namespace CDServices_NET
{
	public delegate void OnProgressDelegate (int ProgressInPercent, string phase);
	
	public class CDService: System.Windows.Forms.Form
	{
		#region Attributes
		private NeroClass nClass;
		private NeroFolder nRootFolder;
		private NeroDrive nDrive;
		private NeroDrives nDrives;
		private NeroISOTrack nISOTrack;
		private string artist = "";
		private string title = "";
		private string imageTarget = @"c:\image.iso";
		private NERO_MEDIA_TYPE nType = 0;
		private int burningSpeed;
		private bool longOperation = false;
		private string phase = "";
		private ProgressForm myProgressForm = new ProgressForm();
		# endregion

		#region Events
		public event OnProgressDelegate OnNeroProgress;
		#endregion
		
		# region Properties
		public string Artist 
		{
			get 
			{
				return artist;
			}
			set 
			{
				artist = value;
			}
		}

		public string Title 
		{
			get 
			{
				return title;
			}
			set 
			{
				title = value;
			}
		}

		public string ImageTarget 
		{
			get 
			{
				return imageTarget;
			}
			set 
			{
				imageTarget = @value;
			}
		}
		# endregion

		#region Contructors
		public CDService()
		{
			nClass = new NeroClass();
			nRootFolder = new NeroFolderClass();
			nISOTrack = new NeroISOTrackClass();			
		}
		#endregion
		
		# region static Methods
		public static void StaticBurn( string title, string imageTarget, string path, string recorder, int burningSpeed, string mediaType)
		{
			NERO_MEDIA_TYPE nType = (NERO_MEDIA_TYPE) Enum.Parse(typeof(NERO_MEDIA_TYPE), mediaType, true);
			CDService cd = new CDService();
			cd.SelectRecoder(recorder);	
			cd.ImageTarget = imageTarget;
			cd.Title = title;
			cd.AddAllToFolderRecursive(new DirectoryInfo(@path));		
			cd.nISOTrack.Name = cd.Title;
			cd.Burn(burningSpeed, nType);
		}

		public static void StaticBurn( string title, string path, string recorder, int burningSpeed, string mediaType)
		{
			StaticBurn (title, @"c:\image.iso", path, recorder, burningSpeed, mediaType);			
		}
		# endregion

		#region Methods		
		
		public void Burn ( string title, string imageTarget, string path, string recorder, int burningSpeed, string mediaType)
		{
			Title = title;
			ImageTarget = imageTarget;
			AddAllToFolderRecursive(new DirectoryInfo(@path));	
			SelectRecoder(recorder);
			Burn(burningSpeed);
		}

		public void Burn(int burningSpeed)
		{
			Burn(burningSpeed, NERO_MEDIA_TYPE.NERO_MEDIA_NONE);
		}

		public void Burn(int speed, NERO_MEDIA_TYPE mediaType)
		{		
			if (nDrive == null)
				throw new Exception("no recorder selected");
			myProgressForm.totalNumber = 100;
			myProgressForm.Show();
			nISOTrack.RootFolder = nRootFolder;
			burningSpeed = speed;
			nType = mediaType;
			
			
			longOperation = true;
			nDrive.EstimateTrackSize(nISOTrack, NERO_ESTIMATE_FLAGS.NETS_DATA, null);
			
			
			//adding handler	
			nDrive.OnDoneBurn += new _INeroDriveEvents_OnDoneBurnEventHandler(OnDoneBurn);
			nDrive.OnProgress += new _INeroDriveEvents_OnProgressEventHandler(OnProgress);
			nDrive.OnDoneWaitForMedia += new _INeroDriveEvents_OnDoneWaitForMediaEventHandler(nDrive_OnDoneWaitForMedia);
			nDrive.OnAddLogLine += new _INeroDriveEvents_OnAddLogLineEventHandler(nDrive_OnAddLogLine);
			nDrive.OnSetPhase += new _INeroDriveEvents_OnSetPhaseEventHandler(nDrive_OnSetPhase);
			nDrive.OnAborted += new _INeroDriveEvents_OnAbortedEventHandler(nDrive_OnAborted);
			nDrive.OnDoneCDInfo +=new _INeroDriveEvents_OnDoneCDInfoEventHandler(nDrive_OnDoneCDInfo);
			nDrive.OnDoneEstimateTrackSize +=new _INeroDriveEvents_OnDoneEstimateTrackSizeEventHandler(nDrive_OnDoneEstimateTrackSize);
			nDrive.OnDoneImport += new _INeroDriveEvents_OnDoneImportEventHandler(nDrive_OnDoneImport);
			
			nClass.OnFileSelImage += new _INeroEvents_OnFileSelImageEventHandler(OnFileSelImage);
			nClass.OnMegaFatal += new _INeroEvents_OnMegaFatalEventHandler(nClass_OnMegaFatal);
			nClass.OnNonEmptyCDRW += new _INeroEvents_OnNonEmptyCDRWEventHandler(nClass_OnNonEmptyCDRW);
			nClass.OnWaitCD += new _INeroEvents_OnWaitCDEventHandler(nClass_OnWaitCD);
			nClass.OnWaitCDMediaInfo += new _INeroEvents_OnWaitCDMediaInfoEventHandler(nClass_OnWaitCDMediaInfo);
			nClass.OnWaitCDReminder += new _INeroEvents_OnWaitCDReminderEventHandler(nClass_OnWaitCDReminder);
			nClass.OnWaitCDDone += new _INeroEvents_OnWaitCDDoneEventHandler(nClass_OnWaitCDDone);
			nClass.OnDriveStatusChanged +=new _INeroEvents_OnDriveStatusChangedEventHandler(nClass_OnDriveStatusChanged);
			
			
			while(longOperation == true)
			{
				Thread.Sleep(500);
				Console.WriteLine("locked");
			}
			longOperation = true;											
			
			nDrive.BurnIsoAudioCD(Artist, Title, false, nISOTrack, null, null, NERO_BURN_FLAGS.NERO_BURN_FLAG_WRITE, 
				burningSpeed, nType); 

			while(longOperation == true)
			{
				Thread.Sleep(500);
				Console.WriteLine("locked");
			}
			
		
		}

		private ArrayList GetRecoderList(NERO_MEDIA_TYPE property)
		{
			nType = property;
			ArrayList al = new ArrayList();
			
			nDrives = (NeroDrives)nClass.GetDrives(property);
			
			foreach(NeroDrive nd in nDrives)
			{				
				al.Add(nd.DeviceName);				
			}
			return al;
		}

		public void SelectRecoder(string recoderName)
		{
			nDrives = (NeroDrivesClass)nClass.GetDrives(nType);					
			foreach(NeroDrive nd in nDrives)
			{				
				if (nd.DeviceName == recoderName)
				{
					nDrive = nd;
					return;
				}
			}
			
			throw new Exception("cannot find selected target with Name: " + recoderName);
		}

		public void SelectRecoder(int  recoderID)
		{
			foreach(NeroDrive nd in nDrives)
			{				
				if (nd.DeviceID == recoderID)
				{
					nDrive = nd;
					return;
				}
			}
			throw new Exception("cannot find selected target with ID: " + recoderID);
		}

		public void AddAllToFolderRecursive(DirectoryInfo rootDir)
		{
			AddAllToFolderRecursive(nRootFolder, rootDir);
		}

		private void AddAllToFolderRecursive( NeroFolder rootFolder, DirectoryInfo rootDir)
		{
			foreach (FileInfo fi in rootDir.GetFiles())
			{
				NeroFile newFile = new NeroFileClass();
				newFile.Name = fi.Name;
				newFile.SourceFilePath = fi.FullName;
				rootFolder.Files.Add(newFile);
			}
			foreach (DirectoryInfo di in rootDir.GetDirectories())
			{
				NeroFolder newFolder = new NeroFolderClass();
				newFolder.Name = di.Name;
				rootFolder.Folders.Add(newFolder); 
				AddAllToFolderRecursive(newFolder, di);
			}
				
		}	
		
		
		//Here we present the user with the results of the burn process
		private void OnDoneBurn(ref NERO_BURN_ERROR statusCode)
		{
			longOperation = false;
			if (statusCode != NERO_BURN_ERROR.NERO_BURN_OK)
				Console.WriteLine("OnDoneBurn: NOT successful! " + statusCode + " " + nClass.ErrorLog.ToString() + nClass.LastError.ToString());			
			else
				Console.WriteLine("OnDoneBurn: successful! " + statusCode);
		
		}

		//Here we just want to display the text that NeroCOM offers us whenever a line is
		//added to the log.
		private void nDrive_OnAddLogLine(ref NERO_TEXT_TYPE TextType, ref string Text)
		{
			Console.WriteLine("nDrive_OnAddLogLine: " + TextType + " : " + Text);
		}

		//OnAborted queries whether an operation shall be aborted. We always return
		//false; if we choose to abort, we will explicitly call the Nero object’s abort method.
		private void nDrive_OnAborted(ref bool Abort)
		{
			Abort = false;			
		}

		//progress reports from NeroCOM.
		private void OnProgress(ref int ProgressInPercent, ref bool Abort)
		{
			Abort = false;
			if (OnNeroProgress != null)
				OnNeroProgress(ProgressInPercent, this.phase);

			Console.WriteLine("OnProgress: " + ProgressInPercent);
			myProgressForm.currentNumber = ProgressInPercent;
			//myProgressForm.Invalidate();
		}
		
		//This event will be called when Nero has stopped waiting for the media.
		private void nDrive_OnDoneWaitForMedia(ref bool Success)
		{			
			Console.WriteLine("nDrive_OnDoneWaitForMedia: ");
		}

		//finding out about the current phase NeroCOM is in –
		//writing data, writing lead-in or lead-out parts of the CD-ROM and related information.
		private void nDrive_OnSetPhase(ref string Text)
		{
			this.phase = Text;
			Console.WriteLine("nDrive_OnSetPhase: " + Text);
		}
	

		//This handler is called when a very critical error occurs.
		private void nClass_OnMegaFatal()
		{
			Console.WriteLine("nClass_OnMegaFatal: " + "A mega fatal error has occurred.");
		}

		//If the user decides to use the virtual device and not a real device more
		//information is needed. The data that NeroCOM creates will be written to an
		//image file. To provide the location of that file we need to handle this event.
		private void OnFileSelImage(ref string target)
		{			
			target = ImageTarget;	
			Console.WriteLine("OnFileSelImage: " + target);
		}

		//This event will be called whenever the user tries to write on a non-empty CD-RW.
		//We merely return NERO_RETURN_EXIT, although of course more sophisticated
		//ways of handling this message are possible, e.g. by asking the user if he wants to
		//erase the CD-RW.
		private void nClass_OnNonEmptyCDRW(ref NERO_RESPONSE Response)
		{
			Response = NERO_RESPONSE.NERO_RETURN_EXIT;
			Console.WriteLine("nClass_OnNonEmptyCDRW: NERO_RETURN_EXIT");
		}

		//This event will be called when Nero is waiting for a CD to be inserted into the
		//drive.
		private void nClass_OnWaitCD(ref NERO_WAITCD_TYPE WaitCD, ref string WaitCDLocalizedText)
		{
			Console.WriteLine("nClass_OnWaitCD: " + WaitCDLocalizedText);
		}

		//This event will be fired when Nero is waiting for a particular type of media.
		private void nClass_OnWaitCDMediaInfo(ref NERO_MEDIA_TYPE LastDetectedMedia, ref string LastDetectedMediaName, ref NERO_MEDIA_TYPE RequestedMedia, ref string RequestedMediaName)
		{
			Console.WriteLine("nClass_OnWaitCDMediaInfo: Waiting for a particular media type: " + RequestedMediaName);
		}

		//This event will occur when Nero has been waiting for the insertion of a CD for
		//quite a while.
		private void nClass_OnWaitCDReminder()
		{
			Console.WriteLine("nClass_OnWaitCDReminder: Waiting for CD");
		}
		#endregion

		private void nDrive_OnDoneCDInfo(INeroCDInfo pCDInfo)
		{
			Console.WriteLine("nDrive_OnDoneCDInfo: " + pCDInfo.ToString());
		}

		private void nDrive_OnDoneEstimateTrackSize(bool bOk, int BlockSize)
		{
			longOperation = false;	
			Console.WriteLine("nDrive_OnDoneEstimateTrackSize: " + bOk + "Blocksize: " + BlockSize);
				
		}

		private void nDrive_OnDoneImport(ref bool Ok, ref NeroFolder Folder, ref NeroCDStamp CDStamp)
		{
			Console.WriteLine("nDrive_OnDoneImport: " + Ok + Folder.ToString() + CDStamp);
		}

		private void nClass_OnWaitCDDone()
		{
			Console.WriteLine("nClass_OnWaitCDDone");
		}

		private void nClass_OnDriveStatusChanged(int hostID, int targetID, NERO_DRIVECHANGE_RESULT driveStatus)
		{
			Console.WriteLine("nClass_OnDriveStatusChanged: hostID:" + hostID + " targetID:" + targetID + " " + driveStatus);
		}
	}

}
18.11.2004 - 11:37 Uhr

Also ich habe mich jetzt noch weiter damit auseinander gesetzt - es klappt zwar schon ganz gut, aber sehr transparent ist das alles nicht. Ab und an krieg ich Fehler aufgrund 2 asynchroner Operations - passiert beim debuggen nicht - abhilfe durch (halb)aktives warten und statusvariable: habe vor und nach dem BurnIsoAudioCD-Aufruf eine solche Schleife um den internen hochprioren NeroThread genuegend Zeit zum werkeln zu geben:
while(longOperation == true)
{
Thread.Sleep(500);
Console.WriteLine("locked");
}
die longOperation variable entsperre ich in den EventHandlermethoden OnDoneBurn und nDrive_OnDoneEstimateTrackSize.
Ich glaube mein Design ist grausam 🙂
Jedenfalls klappt es nicht mehr wenn ich anstelle der Consolenausgabe (z.B. in OnProgress - Methode) den aktuellen Status in einem Form visualisiere (beinhaltet eine Progressbar). Schon allein das halten einer Instanz [edit: nein, war zu uebereifrig - siehe Beitrag spaeter] veranlasst den Nerothread keine Events mehr zu senden so dass ich natuerlich auch nie aus meiner Speerschleife rauskomme. Verstehen tu ichs nicht.
Wems interessiert, kann ich den Code ja gezippt zukommen lassen, oder ich stell ihn hier rein. Muss ihn aber erstmal bisschen saeubern 🙂 Ziel meines Vorhabens: eine schlanke .NET dll mit der man mit einem einzigen static Aufruf einfach eine cd/dvd brennen kann - so nach der Art Burn(string label, string folder, string imagePath, string recorder, int speed, string cdtype).

05.11.2004 - 10:19 Uhr

Super Tutorial 👍
Gibts eigentlich ausser dem pdf, das bei dem NeroCom SDK dabei ist noch eine Beschreibung der Bibliothek? Bitte kein VB - davon hab ich null Ahnung. Will naemlich um die (RCW) gewrappte Library eine einfache .NET-Komponente basteln - d.h. nur die Funktionen anbieten die ich brauche. Noch leider blick ichs noch net ganz. Da steckt einfach zuviel Funktionalitaet drin.
Beispiele waeren auch klasse. Habe hier leider keinen Brenner eingebaut, deswegen wuerd ich gern mit dem Image-Recorder testen. Ich brauch doch nur den Haendler hinzufuegen und dort den string mit dem Target-path+name zu ueberschreiben?

neroClass.OnFileSelImage += new NEROLib._INeroEvents_OnFileSelImageEventHandler(OnFileSelImage);

Gibts einen globalen Fehlerhandler? Hab irgendwie kein passendes Event gefunden. Welche Events sollte man denn alle behandeln?
Gibts eine Funktion um ein Verzeichnis + alle Unterverzeichnisse inkl. Inhalt einer NeroFolderClass zu adden? Oder muss ich (muehsam) mich durch alles durchhangeln und jedes File einzeln adden?

Danke schonmal fuer Hilfe 🙂

27.10.2004 - 17:24 Uhr

verstehe auch nicht den VB-Code wenn du doch eine c++-COM-lib hast die du mit c# ansprechen moechtest, oder?
Mit der Thematik befasse ich mich seit ein paar Tagen -ein Schlagwoert ist interop (interoperability).
Ich nehm mal an dass es sich um eine unmanaged Komponente handelt: Wenn die COM-Komponente ordentlich registriert wurde (regsvr32), dann kann mit dem VStudio (add Reference/COM) die dll einbinden, alternativ bindest du die dll ein die tlbimp erzeugt. Mehr muss man imho nicht tun. Als Namespace evtl den Namen der dll-verwenden.
DllImport soll durch Pinvoke mehr overhead verursachen

27.10.2004 - 15:21 Uhr

Vielleicht sollte ich nochmal Verdeutlichen wo mein Problem liegt:

Ich moechte nicht durch direkte Referenzierung die dlls einbinden sondern nur per ProgId. Wo werden die genau verwaltet? Wo ist eine Uebersicht in WinXP zu sehen? Was wunderbar klappt ist z.B. der Aufruf von Word:

Type t = Type.GetTypeFromProgID("Word.Application");
object o = Activator.CreateInstance(t);
object[] parameter = new object {"true"};
t.InvokeMember("visible",System.Reflection.BindingFlags.SetProperty, null, o, parameter);

Wenn ich jetzt den Wrapper nicht durchs VS und nicht mittels tlbimp generiere, sondern selber einen schreibe wie hier: COM Interop Part 1: C# Client Tutorial Beispiel 2, wie kann ich ihn dann ansprechen wenn ich ihn ebenfalls nicht direkt refenzieren, sondern auch per ProgId ansteuern moechte?

http://www.c-sharpcorner.com/Code/2004/Aug/Interoperabilityin.NET.asp

27.10.2004 - 09:01 Uhr

Also die c#-dll enthaelt in einem Namespace nur das Interface und die leere Klasse (nochmal zur Info). In den Optionen ist noch COM-Interop eingeschaltet. Das sollte eigentlich schon alles sein - eine typelib (tlb) ist jedenfalls dabei. Mach ich jetzt regsvr32 dann kommt: "dll was loaded, but the DllRegisterServer entry point was not found. The file can not be registered". Ich moechte spaeter mein Com-Object nur durch eine ProgId ansprechen..

26.10.2004 - 14:02 Uhr

Danke! Zu dem MSDN - Beispiel:
Moechte mir nochmal einen richtigen Wrapper nach der Beispielvorgabe erstellen. Bisher hab ich es mit Imports gemacht:

[DllImport("MediaDeviceCom.dll", EntryPoint="?Init@?$CW2AEX@$0IA@@ATL@@AAEXPBGI@Z", CharSet=CharSet.Ansi)]
static extern int InitDelegate( [In,MarshalAs( UnmanagedType.BStr)] string strLocation);
...

Nachdem Beispiel wird aber ein Interface mit den Funktionen beschrieben mit dem Zusatz:

[Guid("E072CA28-FAEB-464A-8F84-E78D22BC4822"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
... 

danach eine Klasse:

	[ComImport, Guid("78bc1be0-5e9c-44ad-a551-a3803a2ddca5"), ProgId("MediaDevice.MediaDeviceComInterface2")]
public class MediaDeviceCoClass {}

Kriege aber das Problem wenn ich ein Objekt der Klasse instanziieren moechte:
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in TestApp.exe
Additional information: COM object with CLSID {78BC1BE0-5E9C-44AD-A551-A3803A2DDCA5} is either not valid or not registered.

Habe diese GUID mit uuidgen generiert (die andere beim Interface ist die vom COM-Objekt) -wie (und wiesoe) soll das Ding regestriert werden? regsvr32 verweigert das.

25.10.2004 - 17:09 Uhr

aah es geht. Keine Ahnung wieso auf einmal. Das Objekt ist zwar eines vom Typ "System.__ComObject" - kann aber alle Methoden invoken die im IDL des COM-Objektes vereinbart wurden. Man sollte aber ein try/catch Block aussenrum setzen.
Wer aber noch Infos und andere Loesungsvorschlaege hat, dann bitte posten! Moecht mich (irgendwann mal) besser mit der Komponententechnik auskennen!
🙂

25.10.2004 - 16:22 Uhr

Als ich spiele seit ein paar Tagen mit der Interoperability COM/ .NET herum, aber so 100% laeuft es noch nicht.
Ziel ist verschiedenste Komponenten generisch zu starten und zu steuern. Das Was, Wie und Wann soll in einem XML festgehalten werden.
Jetzt zu den Details. Ich habe verschiedene Testkomponenten hier, die mit c# gesteuert werden. Ich moechte diese aber nicht alle anfangs binden (References) sondern dynamisch zur Laufzeit (late bind). Referenzieren am besten per ProgId (natuerlich muessen die Komponenten registriert sein). Mit .NET Assemblies ('Register for COM Interop' im VS) klappt alles wunderbar. Jetzt hab ich hier eine unmanaged COM dll (in c++ gemacht, hab aber davon wenig Ahnung) - wenn ich mir den Wrapper selber schreibe (mit vielen DLLImports) dann gehts auch - er kriegt ja auch eine eigene guid und wird eigens registriert. Ist aber sehr umstaendlich wegen den Marshal-Befehlen der Ein- und Ausgaenge. Jetzt moechte ich aber tlbimp verwenden um damit den RCW (Run-time Callable Wrapper) zu erzeugen (tlbimp.exe comobject.dll /keyfile: key.snk /out: comobject_rcw.dll ). Wie krieg ich jetzt das Wrapper-dll geladen? statisch binden geht natuerlich - will es aber zur Laufzeit haben, weiss aber nicht ob es eine ProgId hat und wenn ja welche. Im OLE- Viewer find ich nix, genauso wenig wie im GAC (Global Assembly Cache).
Anbei noch ein paar Zeilen Beispielcode wie ich auf die DLLs zugreife:

Type t = Type.GetTypeFromProgID("MySpace.MyApp");
object o = Activator.CreateInstance(t);
t.InvokeMember("methode", BindingFlags.InvokeMethod , null, o, null);

Lad ich das unmanaged COM, dann krieg ich als Typ {"System.__ComObject"}. Lade ich den managed Wrapper oder ein managed COM, so krieg ich den exakten Typ. Damit kann ich dann auch mit Type.GetMembers die Funktionen abrufen.

Get das alles vielleicht viel einfacher? Oder hat jemand schonmal sowas aehnliches Programmiert? Bin fuer jeden Tipp dankbar!

Was mich ausserdem interessieren wuerde ist eine gute Uebersicht + Tutorials ueber COM, DCOM, COM+, .NET-Assemblies und Serviced Components . D.h. Vorteile, Nachteile, Erzeugen, Verwenden.