471,627 Members | 1,681 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,627 software developers and data experts.

C# control causes VB6 application to crash on exit

Hi,
We have a VB6 application that needs to use a new control written in
..NET v1.1 C#, imported as a COM control.
We have tried adding the C# control to the VB6 control both dynamically
(using Controls.Add) and using the VB6 designer. In both approaches
the behavior was identical: the control was functional and accessible,
but the application crashed on exit with the message <app name> "has
encountered a problem and needs to close. We are sorry for the
inconvenience." etc.

I have searched the web, with no luck. Any ideas will be greatly
appreciated. The C# code is embedded below.

Thanks
Asaf.
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
[assembly:ClassInterface(ClassInterfaceType.AutoDua l)]
namespace MyCtrlLib
{
///
/// Summary description for UserControl1.
///
[ GuidAttribute("F321BAC9-5019-4c6f-BADF-8D104A499870") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceI sDual)]
public interface ICSharpCOMInterface
{
void MethodA();
void MethodB(int a);
}

[ComVisible(false)]
public delegate void CSharpEventHandlerA ();
[ComVisible(false)]
public delegate void CSharpEventHandlerB (int a);

[GuidAttribute("03018F99-263B-417e-94F3-F367471F6679"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceI sIDispatch)]
public interface ICSharpCOMEvents
{
[DispId(1)]void EventA();
[DispId(2)]void EventB(int a);
}

[GuidAttribute("E022271B-63C8-4878-8C9E-712E776C4785")]
[ProgIdAttribute("MyCtrlLib.CSharpUserControl")]
//[ComSourceInterfacesAttribute(typeof (ICSharpCOMEvents))]
[ComSourceInterfacesAttribute(typeof(MyCtrlLib.ICSh arpCOMEvents))]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
public class CSharpUserControl : System.Windows.Forms.UserControl,
ICSharpCOMInterface
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;

[Category("Action")]
public event CSharpEventHandlerA EventA;
[Category("Action")]
public event CSharpEventHandlerB EventB;

public CSharpUserControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitForm call
}

///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
MessageBox.Show("Dispose");
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}

public void MethodA()
{
this.textBox1.Text = "MethodA";
OnMyEventA();
}

public void MethodB(int a)
{
OnMyEventB(a);
}

protected void OnMyEventA()
{
if (EventA != null)
{
this.textBox1.Text = "Event fired!";
EventA();
}
}

protected void OnMyEventB(int a)
{
if (EventB != null)
EventB(a);
}
[ComRegisterFunction()]
public static void RegisterClass ( Type t )
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need
it
string sb = @"CLSID\" + t.GUID.ToString("B");
sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

// Open the CLSID\{guid} key for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true );
// And create the 'Control' key - this allows it to show up in
// the ActiveX control container
RegistryKey ctrl = k.CreateSubKey ( "Control" ) ;
ctrl.Close ( ) ;

using( RegistryKey subkey = k.CreateSubKey("MiscStatus") )
{
subkey.SetValue("", "131473");
}

using( RegistryKey subkey = k.CreateSubKey("MiscStatus\\1") )
{
subkey.SetValue("", "197009");
}

// Next create the CodeBase entry - needed if not string named and
GACced
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true
);
inprocServer32.SetValue ( "CodeBase" ,
Assembly.GetExecutingAssembly().CodeBase ) ;
inprocServer32.Close ( ) ;

// Now create the Version entry
RegistryKey vers = k.CreateSubKey("Version");
vers.SetValue("", "1.0");
vers.Close();

RegistryKey inst = k.CreateSubKey ( "Insertable" ) ;
inst.Close ( ) ;

// And the Type Lib Entry
using( RegistryKey subkey = k.CreateSubKey("TypeLib") )
{
Guid libid = Marshal.GetTypeLibGuidForAssembly(t.Assembly);

subkey.SetValue("", libid.ToString("B"));
}
// Finally close the main key
k.Close ( ) ;
}
[ComUnregisterFunction()]
public static void UnregisterClass ( string key )
{
StringBuilder sb = new StringBuilder ( key ) ;
sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

// Open HKCR\CLSID\{guid} for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true );
// Delete the 'Control' key, but don't throw an exception if it does
not exist
k.DeleteSubKey ( "Control" , false ) ;

// Next open up InprocServer32
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true
);

// And delete the CodeBase key, again not throwing if missing
k.DeleteSubKey ( "CodeBase" , false ) ;

k.DeleteSubKey ( "TypeLib" , false ) ;

k.DeleteSubKey ( "Version" , false ) ;

// Finally close the main key
k.Close ( ) ;
}

#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 8);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(192, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(8, 32);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(192, 24);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// CSharpUserControl
//
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "CSharpUserControl";
this.Size = new System.Drawing.Size(208, 64);
this.ResumeLayout(false);
}
#endregion

private void button1_Click(object sender, System.EventArgs e)
{
OnMyEventA();
}
}
}

Jan 1 '06 #1
3 2577
Seems to me that you'd be better off on a C# forum, as the problems seems to
be related to your control rather than to VB6.

BTW I'd be suspicious of any attempt to do manual disposing...

"Asaf" <as***@marvell.com> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
Hi,
We have a VB6 application that needs to use a new control written in
.NET v1.1 C#, imported as a COM control.
We have tried adding the C# control to the VB6 control both dynamically
(using Controls.Add) and using the VB6 designer. In both approaches
the behavior was identical: the control was functional and accessible,
but the application crashed on exit with the message <app name> "has
encountered a problem and needs to close. We are sorry for the
inconvenience." etc.

I have searched the web, with no luck. Any ideas will be greatly
appreciated. The C# code is embedded below.

Thanks
Asaf.
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
[assembly:ClassInterface(ClassInterfaceType.AutoDua l)]
namespace MyCtrlLib
{
///
/// Summary description for UserControl1.
///
[ GuidAttribute("F321BAC9-5019-4c6f-BADF-8D104A499870") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceI sDual)]
public interface ICSharpCOMInterface
{
void MethodA();
void MethodB(int a);
}

[ComVisible(false)]
public delegate void CSharpEventHandlerA ();
[ComVisible(false)]
public delegate void CSharpEventHandlerB (int a);

[GuidAttribute("03018F99-263B-417e-94F3-F367471F6679"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceI sIDispatch)]
public interface ICSharpCOMEvents
{
[DispId(1)]void EventA();
[DispId(2)]void EventB(int a);
}

[GuidAttribute("E022271B-63C8-4878-8C9E-712E776C4785")]
[ProgIdAttribute("MyCtrlLib.CSharpUserControl")]
//[ComSourceInterfacesAttribute(typeof (ICSharpCOMEvents))]
[ComSourceInterfacesAttribute(typeof(MyCtrlLib.ICSh arpCOMEvents))]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
public class CSharpUserControl : System.Windows.Forms.UserControl,
ICSharpCOMInterface
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;

[Category("Action")]
public event CSharpEventHandlerA EventA;
[Category("Action")]
public event CSharpEventHandlerB EventB;

public CSharpUserControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitForm call
}

///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
MessageBox.Show("Dispose");
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}

public void MethodA()
{
this.textBox1.Text = "MethodA";
OnMyEventA();
}

public void MethodB(int a)
{
OnMyEventB(a);
}

protected void OnMyEventA()
{
if (EventA != null)
{
this.textBox1.Text = "Event fired!";
EventA();
}
}

protected void OnMyEventB(int a)
{
if (EventB != null)
EventB(a);
}
[ComRegisterFunction()]
public static void RegisterClass ( Type t )
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need
it
string sb = @"CLSID\" + t.GUID.ToString("B");
sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

// Open the CLSID\{guid} key for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true );
// And create the 'Control' key - this allows it to show up in
// the ActiveX control container
RegistryKey ctrl = k.CreateSubKey ( "Control" ) ;
ctrl.Close ( ) ;

using( RegistryKey subkey = k.CreateSubKey("MiscStatus") )
{
subkey.SetValue("", "131473");
}

using( RegistryKey subkey = k.CreateSubKey("MiscStatus\\1") )
{
subkey.SetValue("", "197009");
}

// Next create the CodeBase entry - needed if not string named and
GACced
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true
);
inprocServer32.SetValue ( "CodeBase" ,
Assembly.GetExecutingAssembly().CodeBase ) ;
inprocServer32.Close ( ) ;

// Now create the Version entry
RegistryKey vers = k.CreateSubKey("Version");
vers.SetValue("", "1.0");
vers.Close();

RegistryKey inst = k.CreateSubKey ( "Insertable" ) ;
inst.Close ( ) ;

// And the Type Lib Entry
using( RegistryKey subkey = k.CreateSubKey("TypeLib") )
{
Guid libid = Marshal.GetTypeLibGuidForAssembly(t.Assembly);

subkey.SetValue("", libid.ToString("B"));
}
// Finally close the main key
k.Close ( ) ;
}
[ComUnregisterFunction()]
public static void UnregisterClass ( string key )
{
StringBuilder sb = new StringBuilder ( key ) ;
sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

// Open HKCR\CLSID\{guid} for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true );
// Delete the 'Control' key, but don't throw an exception if it does
not exist
k.DeleteSubKey ( "Control" , false ) ;

// Next open up InprocServer32
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true
);

// And delete the CodeBase key, again not throwing if missing
k.DeleteSubKey ( "CodeBase" , false ) ;

k.DeleteSubKey ( "TypeLib" , false ) ;

k.DeleteSubKey ( "Version" , false ) ;

// Finally close the main key
k.Close ( ) ;
}

#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 8);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(192, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(8, 32);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(192, 24);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// CSharpUserControl
//
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "CSharpUserControl";
this.Size = new System.Drawing.Size(208, 64);
this.ResumeLayout(false);
}
#endregion

private void button1_Click(object sender, System.EventArgs e)
{
OnMyEventA();
}
}
}

Jan 1 '06 #2
Asaf,

Unfortunately, ActiveX controls are not able to be exported from .NET to
automation-compatable clients.

There is an unsupported hack to do this, but I wouldn't recommend it,
since it is not supported in the least.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Asaf" <as***@marvell.com> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
Hi,
We have a VB6 application that needs to use a new control written in
.NET v1.1 C#, imported as a COM control.
We have tried adding the C# control to the VB6 control both dynamically
(using Controls.Add) and using the VB6 designer. In both approaches
the behavior was identical: the control was functional and accessible,
but the application crashed on exit with the message <app name> "has
encountered a problem and needs to close. We are sorry for the
inconvenience." etc.

I have searched the web, with no luck. Any ideas will be greatly
appreciated. The C# code is embedded below.

Thanks
Asaf.
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
[assembly:ClassInterface(ClassInterfaceType.AutoDua l)]
namespace MyCtrlLib
{
///
/// Summary description for UserControl1.
///
[ GuidAttribute("F321BAC9-5019-4c6f-BADF-8D104A499870") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceI sDual)]
public interface ICSharpCOMInterface
{
void MethodA();
void MethodB(int a);
}

[ComVisible(false)]
public delegate void CSharpEventHandlerA ();
[ComVisible(false)]
public delegate void CSharpEventHandlerB (int a);

[GuidAttribute("03018F99-263B-417e-94F3-F367471F6679"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceI sIDispatch)]
public interface ICSharpCOMEvents
{
[DispId(1)]void EventA();
[DispId(2)]void EventB(int a);
}

[GuidAttribute("E022271B-63C8-4878-8C9E-712E776C4785")]
[ProgIdAttribute("MyCtrlLib.CSharpUserControl")]
//[ComSourceInterfacesAttribute(typeof (ICSharpCOMEvents))]
[ComSourceInterfacesAttribute(typeof(MyCtrlLib.ICSh arpCOMEvents))]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
public class CSharpUserControl : System.Windows.Forms.UserControl,
ICSharpCOMInterface
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;

[Category("Action")]
public event CSharpEventHandlerA EventA;
[Category("Action")]
public event CSharpEventHandlerB EventB;

public CSharpUserControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitForm call
}

///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
MessageBox.Show("Dispose");
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}

public void MethodA()
{
this.textBox1.Text = "MethodA";
OnMyEventA();
}

public void MethodB(int a)
{
OnMyEventB(a);
}

protected void OnMyEventA()
{
if (EventA != null)
{
this.textBox1.Text = "Event fired!";
EventA();
}
}

protected void OnMyEventB(int a)
{
if (EventB != null)
EventB(a);
}
[ComRegisterFunction()]
public static void RegisterClass ( Type t )
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need
it
string sb = @"CLSID\" + t.GUID.ToString("B");
sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

// Open the CLSID\{guid} key for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true );
// And create the 'Control' key - this allows it to show up in
// the ActiveX control container
RegistryKey ctrl = k.CreateSubKey ( "Control" ) ;
ctrl.Close ( ) ;

using( RegistryKey subkey = k.CreateSubKey("MiscStatus") )
{
subkey.SetValue("", "131473");
}

using( RegistryKey subkey = k.CreateSubKey("MiscStatus\\1") )
{
subkey.SetValue("", "197009");
}

// Next create the CodeBase entry - needed if not string named and
GACced
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true
);
inprocServer32.SetValue ( "CodeBase" ,
Assembly.GetExecutingAssembly().CodeBase ) ;
inprocServer32.Close ( ) ;

// Now create the Version entry
RegistryKey vers = k.CreateSubKey("Version");
vers.SetValue("", "1.0");
vers.Close();

RegistryKey inst = k.CreateSubKey ( "Insertable" ) ;
inst.Close ( ) ;

// And the Type Lib Entry
using( RegistryKey subkey = k.CreateSubKey("TypeLib") )
{
Guid libid = Marshal.GetTypeLibGuidForAssembly(t.Assembly);

subkey.SetValue("", libid.ToString("B"));
}
// Finally close the main key
k.Close ( ) ;
}
[ComUnregisterFunction()]
public static void UnregisterClass ( string key )
{
StringBuilder sb = new StringBuilder ( key ) ;
sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

// Open HKCR\CLSID\{guid} for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true );
// Delete the 'Control' key, but don't throw an exception if it does
not exist
k.DeleteSubKey ( "Control" , false ) ;

// Next open up InprocServer32
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true
);

// And delete the CodeBase key, again not throwing if missing
k.DeleteSubKey ( "CodeBase" , false ) ;

k.DeleteSubKey ( "TypeLib" , false ) ;

k.DeleteSubKey ( "Version" , false ) ;

// Finally close the main key
k.Close ( ) ;
}

#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 8);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(192, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(8, 32);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(192, 24);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// CSharpUserControl
//
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "CSharpUserControl";
this.Size = new System.Drawing.Size(208, 64);
this.ResumeLayout(false);
}
#endregion

private void button1_Click(object sender, System.EventArgs e)
{
OnMyEventA();
}
}
}

Jan 1 '06 #3
Thanks
Asaf

Jan 1 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.