Hej ! Du vill alltså göra ett program i VB6 som skall använda din C# klass? Tack för ditt svar ! >Var lägger jag dessa attribut ? hmmm...får inte till det... Tack ! ..har du kommit ihåg att sätta med /tlb flaggan till regasm när du registrerar din dll? C:\Documents and Settings\Simon>regasm Ja...nu dök den upp, Tack för det ! hmm, testa lägga till en konstruktor utan parametrar, eventuellt behövs en sån läggas till explicit för att det ska funka.. 80070002 är ett ganska otrevligt meddelande eftersom det kan bero på så många saker. Martin, ja men...ärligt talat, KAN det vara så avancerat att skriva en liten DLL ?? Kunde självklart inte låta bli att testa. nej, men du måste sätta till en referens till System.Windows.Forms.dll (för clipboard funktionaliteten) Gjorde det programmet och klistrade in nyckeln, men samma resultat... inte heller med regasm /CodeBase försvinner problemet. Nej. Tack...men inte det heller.... msdn för ClassInterfaceType.AutoDispatch ja...jag har sett det och har ändrat koden i VB : <b>För visst är det väl det man ska använda vid late bindings ?</b> Det funkar !!!!!Register for COM interop
Jag gör mina första trevande försök i C# (VS2005)
Jag har gjort en klass (DLL) som jag vill referera till i VB6.
Den är väldigt enkel, typ "Hello World" :-)
Problemet är att den inte dyker upp bland referenser och om jag försöker lägga till den får jag felmeddelande :"Can't add reference to specified file"
Jag har registrerat DLL'en med regasm.
Jag har googlat omkring lite och sett att jag ska bocka i en ruta som heter :Register for COM interop.
Denna hittar jag ingen stans, men däremot en som heter : make assembly com-visible. Är det samma sak ?
Kan någon ge mig en knuff i rätt riktning ?
/MartinSv: Register for COM interop
Isåfall skall du kryssa i "make assembly com visible".
Men du måste dessutom lägga till lite attribut på din klass.
Prova med följande:
[ComVisibleAttribute(true)]
[ProgId("Minassembly.Minklass")]
[Guid("ABC...")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class minklass {
public int minmetod(int x) { return x*x; }
};
Använd bara vanliga metoder med int som argument och returtyp tills du få det att fungera)
När du kompilerat och registrerat din dll (regasm minassembly.dll) är det lättast att testa med ett litet vbscript program. Skapa en fil test.vbs som innehåller:
Set o = CreateObject("Minassembly.Minklass")
msgbox o.minmetod(1)Sv:Register for COM interop
Var lägger jag dessa attribut ?
Innan NameSpace-noden eller efter min Public Class xxx ?
Finns det inget som heter "Class declaration" i C# ?
Vad ska GUID[ABC...] innehålla?
/MartinSv: Register for COM interop
Som i exemplet ovan. Precis innan public class
>Vad ska GUID[ABC...] innehålla?
Ett GUID. Använd guidgen i toolsmenynSv:Register for COM interop
Ser ut så här nu :
<CODE C#>
using System;
using System.Collections.Generic;
using System.Text;
namespace TstDll
{
[ComVisibleAttribute(true)]
[ProgId("TstDll.Minklass")]
//[Guid("ABC...")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class minklass
{
public int minmetod(int x) { return x * x; }
}
}
</CODE>
Får följande fel vid kompilering / Build :
Error 3 The type or namespace name 'ClassInterface' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\Martin\Lokala inställningar\Application Data\Temporary Projects\ClassLibrary1\Class1.cs 12 6 ClassLibrary1
Error 2 The type or namespace name 'ProgId' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\Martin\Lokala inställningar\Application Data\Temporary Projects\ClassLibrary1\Class1.cs 10 6 ClassLibrary1
Error 1 The type or namespace name 'ComVisibleAttribute' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\Martin\Lokala inställningar\Application Data\Temporary Projects\ClassLibrary1\Class1.cs 9 6 ClassLibrary1Sv:Register for COM interop
Nu gick den att kompilera...men...det är samma resultat.
Den går att registrera, men inte lägga som referens till VB6.
Jag hittade inget om GUID i Tools-menyn...kan det vara det som fattas ??Sv: Register for COM interop
Sv: Register for COM interop
Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.42
Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.
Syntax: RegAsm AssemblyName [Options]
Options:
/unregister Unregister types
/tlb[:FileName] Export the assembly to the specified type library
and register it
/regfile[:FileName] Generate a reg file with the specified name
instead of registering the types. This option
cannot be used with the /u or /tlb options
/codebase Set the code base in the registry
/registered Only refer to already registered type libraries
/asmpath:Directory Look for assembly references here
/nologo Prevents RegAsm from displaying logo
/silent Silent mode. Prevents displaying of success messages
/verbose Displays extra information
/? or /help Display this usage messageSv:Register for COM interop
Men...
Har följande kod i VB6 :
<CODE>
Private Sub Command1_Click()
Dim tdll As TstDll.minklass
Set tdll = New TstDll.minklass
A = tdll.minmetod(8)
End Sub
</CODE>
Får automation error (80070002) på raden :Set tdll = New TstDll.minklass
Något förslag ?Sv: Register for COM interop
(har inte vb6 här så jag kan testa)Sv: Register for COM interop
Prova följande:
1. 80070002 betyder egentligen att någon fil saknas men det är sällan det är så (enligt min erfarenhet). Kolla dock att du inte har angett någon referens i C# projektet som eventuellt inte hittas när din komponent skall laddas. (vill du vara mer avancerad kan du kolla med verktyg som depends och fuslogvw). Om du inte är administratör på datorn kan det också vara bra att kolla med procmon att det inte är något rättighetsproblem som spökar.
2. Som jag skrev ovan bör du först prova med vbscript då det oftast är enklare att få late-binding att fungera (dvs createobject istället för dim as).
3. Prova att registrera med "regasm /codebase". Det skall egentligen inte behövas och du får en varning när du gör det men ibland gör det att det fungerar.
4. Kolla i registret att din klass inte är registrerad flera gånger. (dvs avregistrera din komponent och sök sen i registret efter namnet och den guid du angav)Sv:Register for COM interop
Jag angav ingen guid, eftersom jag inte hittade det i tools-menyn.
Kan det vara problemet ?Sv: Register for COM interop
(du kan göra din egen uuidgen som t.ex. som följande, stoppa bara i ett kommandoradprogram och kör, sen ctrl+V, minns inte om .ToString formatet är rätt, eftersom jag använt denna när jag jobbade med WiX)
using System;
using System.Text;
using System.Windows.Forms;
namespace UuidGen {
class Program {
[STAThread]
static void Main(string[] args) {
string guid = Guid.NewGuid().ToString("D").ToUpper();
Console.WriteLine(guid);
Clipboard.SetText(guid, TextDataFormat.Text);
}
}
}
Sv:Register for COM interop
Hur ska det då vara att designa ett helt system ?
Det kan väl inte vara möjligt att man måste göra stödprogram bara för att man vill implementera 2-3 kod-rader ?? :-)
Hur som helst, TACK för alla tips och råd.
Jag återkommer säkert i morgon.Sv: Register for COM interop
På raden : using System.Windows.Forms;
får jag följande fel:
Error 1 The type or namespace name 'Windows' does not exist in the namespace 'System' (are you missing an assembly reference?) C:\Documents and Settings\Martin\Lokala inställningar\Application Data\Temporary Projects\ConsoleApplication1\Program.cs 3 14 ConsoleApplication1
Saknar jag någon "USING" ?Sv:Register for COM interop
Sv: Register for COM interop
Hittar också nyckeln i "regedit"
Innan dess hade jag kört regasm /u
Sedan regasm /tlb
Fler förslag ???Sv:Register for COM interop
vad kan fattas ?Sv:Register for COM interop
Ska jag vara ärlig så vet jag inte hur en sådan kan se ut.
Har du tid att visa ?Sv: Register for COM interop
using System;
using System.Collections.Generic;
using System.Text;
namespace TstDll
{
[ComVisibleAttribute(true)]
[ProgId("TstDll.Minklass")]
[Guid("ABC...")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class minklass
{
public minklass() {
//behöver inte göra nåt just nu...
}
public int minmetod(int x) { return x * x; }
}
}
Sv:Register for COM interop
Vad kan det vara....jag blir snart tokig...
Jag kan ju se på google att massor av folk har haft samma problem, men jag kan inte se att det har blivit löst.
GÅR det ??Sv: Register for COM interop
<b>Indicates that the class only supports late binding for COM clients.</b>Sv:Register for COM interop
<code>
Private Sub Command1_Click()
Dim tdll As TstDll.minklass
Set tdll = CreateObject("tstdll.minklass")
A = tdll.minmetod(8)
End Sub
</code>
men det är ingen skillnad med CreateObject.
För visst är det väl det man ska använda vid late bindings ?Sv: Register for COM interop
..tydligen inte :)
Edit: tydligen ska du "dimma" din tdll as Object och inte nåt annat
dim tdll as object
Sv:Register for COM interop
Det verkar inte ha så mycket med Dim, CreateObject etc. att göra.
Däremot verkar det som att DLL och TLB måste finnas i både \windows\system32 och "clientens" hembibliotek.
Man kan ju bli knäpp för mindre :-)
STORT tack till alla er som hjälp till !!!
Mvh
Martin