none
Crear ActiveX con ATL para uso en Excel/Access y Página WEB

    Pregunta

  • Hola, soy nuevo en esto de creación de controles ActiveX y estoy bastante perdido. Os resumo mi problema a ver si alguien me puede dar luz:

    Necesito crear una DLL con ciertas funciones que pueda reutilizar luego desde Excel/Access y desde Internet Explorer con JavaScript. El caso que tras mucho mirar por internet vi lo que parecía la solución más sencilla:

    1- Crear un nuevo proyecto en Visual C++ 2010 de tipo ATL.

    2- Añadir una nueva clase para mis funciones de tipo "ATL Simple Object". Aquí dejo todo por defecto en el asistente excepto el campo ProgID que le puse un texto cualquiera (por lo que entendí, el ProgID es un alias del CLID para no tener que aprenderte/usar el numero infernal luego)

    3- Añadir nuevos métodos a la clase que me creé justo antes. Para mi prueba fue tan simple como un método sin argumentos. Luego en el .cpp de turno, añadí el código al método. Aquí  también por sencillez lo que puse fue un simple MessageBox con un Hola mundo.

    4- Para evitar los warnings del visual, añadí "using namespace ATL" al StdAfx.h.

    5- Finalmente guardé todo el proyecto, cerré el Visual studio y lo volví a abrir como administrador, de este modo hice el build de mi proyecto, ya que sino se entra como admin, no es capaz de registrar el control en el REGEDIT.

    6- Hecho esto probé a registrar también manualmente la dll con regsvr32 satisfactoriamente para ver que no tenía error (esto lo hice solo por gusto ya que nunca me dejaba hacer esto con mis pruebas anteriores siguiendo otras guías)

    7- Finalmente me dispuse a probar el control en Excel. Así, abrí Excel 2010, me metí en el editor de visualbasic, añadi desde el menú de referencias mi nuevo y flamante control y luego cree una sub función muy simple donde declaraba un "Dim test As New Test"; y luego "test.MostratMensaje", a todo esto el intelisense reconoció perfectamente tanto la clase de objeto declarado como el método que incorporaba. Pues bien al ejecutar esto me salió "Error 429: El componente ActiveX no puede crear el objeto"

    He probado de todo, tengo usuario con permisos de Admin, la dll copiada en todos lados, system32, system, etc. (uso Windows 7 Pro x64)  y nada que no hay manera de que funcione.

    ¿Alguien me echa una mano?

    lunes, 17 de diciembre de 2012 21:12

Respuestas

  • Ok, su archivo MyActiveX_01.rgs está vacío.  Debería contener una serie de instrucciones para registrar el componente.  En pocas palabras:  Aún cuando regsvr32.exe dice que el componente registra bien, en realidad no está escribiendo nada.  Su contenido debe leerse algo así:

    HKCR
    {
    	ElProgIDDeSuEleccion.1 = s 'Alguna descripción del objeto COM'
    	{
    		CLSID = s '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
    	}
    	ElProgIDDeSuEleccion = s 'Alguna descripción del objeto COM'
    	{
    		CLSID = s '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
    		CurVer = s 'ElProgIDDeSuEleccion.1'
    	}
    	NoRemove CLSID
    	{
    		ForceRemove {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} = s 'Alguna descripción del objeto COM'
    		{
    			ProgID = s 'ElProgIDDeSuEleccion.1'
    			VersionIndependentProgID = s 'ElProgIDDeSuEleccion'
    			ForceRemove 'Programmable'
    			InprocServer32 = s '%MODULE%'
    			{
    				val ThreadingModel = s 'Apartment'
    			}
    			'TypeLib' = s '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
    		}
    	}
    }

    Algo así.  Adicionalmente debe contener lo siguiente si es un Browser Helper Object para IE:

    HKLM
    {
    	NoRemove SOFTWARE
    	{
    		NoRemove Microsoft
    		{
    			NoRemove Windows
    			{
    				NoRemove CurrentVersion
    				{
    					NoRemove Explorer
    					{
    						NoRemove 'Browser Helper Objects'
    						{
    							ForceRemove {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
    							{
    								val 'NoExplorer' = d '1'
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    }
    

    Donde las XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX corresponden a valores de UUID de interfases o coclasses según el lugar.  Lo que le puse lo copié de un proyecto mío y no le recomiendo usarlo para arreglar su archivo .rgs; únicamente le muestro esto para que se dé una idea de lo que le falta en ese archivo.

    Por cierto, el archivo se crea solo; algo hizo usted que omitió la creación de este archivo o bien algún dedillo tonto por ahí borró los contenidos inadvertidamente.  Le recomiendo crear un nuevo proyecto, que de todas formas lo que actualmente tiene es bien fácil de recrear.


    Jose R. MCP
    Code Samples

    miércoles, 19 de diciembre de 2012 2:56
    Moderador

Todas las respuestas

  • ¿La cuenta de administrador que utilizó para el build es distinta de la cuenta que utilizó para hacer la prueba en Excel?

    Jose R. MCP
    Code Samples

    martes, 18 de diciembre de 2012 3:51
    Moderador
  • No. En todo momento he usado la misma cuenta de usuario. La única diferencia es que para hacer el build hice click derecho en el icono del VS2010 y le día a ejecutar como administrador.

    martes, 18 de diciembre de 2012 22:07
  • Ok, entiendo eso.  Pero mi pregunta es:  ¿Qué cuenta utilizó después de que hizo clic en ejecutar como administrador?  Porque hay dos posibilidades:

    1. La cuenta que está usando tiene derechos administrativos, en cuyo caso "Ejecutar como administrador" únicamente muestra un cuadro de diálogo de Sí o No.
    2. La cuenta que está usando NO tiene derechos administrativos, en cuyo caso "Ejecutar como administrador" muestra un cuadro de diálogo que pregunta por usuario y contraseña.

    Mi pregunta sería:  ¿Cuál de los dos casos es el suyo?  Pregunto porque podría de pronto estar pasando que el DLL se queda dentro de los documentos de la cuenta administrativa, que es una ubicación inaccesible para cualquier otro usuario, a menos claro que también tengan derechos administrativos.

    En general, el error 429 puede darse por varias causas y lo que está diciendo es "traté de crear el objeto pero no pude".  Puede ser porque el DLL esté en una ruta inaccesible al usuario (que es mi sospecha actual), o que las claves de registro no estén disponibles para el usuario activo, etc.


    Jose R. MCP
    Code Samples

    martes, 18 de diciembre de 2012 22:36
    Moderador
  • Lo primero gracias por tu interés. Bien, mi caso se correspondería con el primero de los dos que comentas. Con lo que has comentado he probado por si acaso a ejecutar Excel como admin también pero nada, el mismo error.

    Mira por si te sirve te pongo el enlace del proyecto de prueba: h t t p : / / skydrive.live.com/redir?resid=66CD453C7076A2DB!148&authkey=!AAly_uZNFtn26x8

    Es la primera vez que uso skydrive así que espero que te funcione bien el enlace.

    Gracias

    martes, 18 de diciembre de 2012 23:18
  • Ok, su archivo MyActiveX_01.rgs está vacío.  Debería contener una serie de instrucciones para registrar el componente.  En pocas palabras:  Aún cuando regsvr32.exe dice que el componente registra bien, en realidad no está escribiendo nada.  Su contenido debe leerse algo así:

    HKCR
    {
    	ElProgIDDeSuEleccion.1 = s 'Alguna descripción del objeto COM'
    	{
    		CLSID = s '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
    	}
    	ElProgIDDeSuEleccion = s 'Alguna descripción del objeto COM'
    	{
    		CLSID = s '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
    		CurVer = s 'ElProgIDDeSuEleccion.1'
    	}
    	NoRemove CLSID
    	{
    		ForceRemove {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} = s 'Alguna descripción del objeto COM'
    		{
    			ProgID = s 'ElProgIDDeSuEleccion.1'
    			VersionIndependentProgID = s 'ElProgIDDeSuEleccion'
    			ForceRemove 'Programmable'
    			InprocServer32 = s '%MODULE%'
    			{
    				val ThreadingModel = s 'Apartment'
    			}
    			'TypeLib' = s '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
    		}
    	}
    }

    Algo así.  Adicionalmente debe contener lo siguiente si es un Browser Helper Object para IE:

    HKLM
    {
    	NoRemove SOFTWARE
    	{
    		NoRemove Microsoft
    		{
    			NoRemove Windows
    			{
    				NoRemove CurrentVersion
    				{
    					NoRemove Explorer
    					{
    						NoRemove 'Browser Helper Objects'
    						{
    							ForceRemove {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
    							{
    								val 'NoExplorer' = d '1'
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    }
    

    Donde las XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX corresponden a valores de UUID de interfases o coclasses según el lugar.  Lo que le puse lo copié de un proyecto mío y no le recomiendo usarlo para arreglar su archivo .rgs; únicamente le muestro esto para que se dé una idea de lo que le falta en ese archivo.

    Por cierto, el archivo se crea solo; algo hizo usted que omitió la creación de este archivo o bien algún dedillo tonto por ahí borró los contenidos inadvertidamente.  Le recomiendo crear un nuevo proyecto, que de todas formas lo que actualmente tiene es bien fácil de recrear.


    Jose R. MCP
    Code Samples

    miércoles, 19 de diciembre de 2012 2:56
    Moderador
  • OK acabo de hacer la prueba de fuego, he cogido y he compilado el proyecto en otra máquina con Windows XP de 32 bits y allí todo me ha funcionado perfectamente y he podido llamar a my ActiveX desde Excel y desde una pagina web con la función new ActiveXObject sin ningún problema lo que me indica cláramente que en Windows 7 x64 hay que hacer algo extra que no se qué será.

    • Editado rtomasal miércoles, 19 de diciembre de 2012 15:06
    miércoles, 19 de diciembre de 2012 9:07
  • Se me ocurren dos cosas:

    A) La versión de Excel es de 64 bits y la de tu componente de 32 bits. Ambos deberían ser de 32 ó de 64 bits.

    B) En Windows Vista/7/8 existe un tema en el que un proceso con menor nivel de acceso no puede hacer llamadas a otro proceso (en este caso el contenedor COM de tu ActiveX) que tenga un mayor nivel de acceso. Hablo de permisos.

    Aunque creo que es la A)


    MVP Visual C++ - Visita mi blog sobre desarrollo: http://geeks.ms/blogs/rfog/

    miércoles, 09 de enero de 2013 14:57
    Moderador