Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)
Mostrando entradas con la etiqueta C# .Net Microsoft. Mostrar todas las entradas
Mostrando entradas con la etiqueta C# .Net Microsoft. Mostrar todas las entradas

jueves, 9 de junio de 2022

Error "Clase no registrada" al usar Microsoft.Speech en Visual Studio 2019 y Windows 10

Un día quise jugar con las librerías de Microsoft Speech para hacer hablar a mi laptop. Las descargas fueron las siguientes:

Microsoft Speech Platform Runtime. Descargué el instalador de 64 y 32 bits, bastan los instaladores de la plataforma en la que se compila la aplicación, pero por el error que explicaré más abajo tuve que probar ambos:

https://www.microsoft.com/en-us/download/details.aspx?id=27225

Microsoft Speech Platform Runtime Languages:

https://www.microsoft.com/en-us/download/details.aspx?id=27224

Los paquetes para reconocimiento de audio son los que dicen TELE, los paquetes para convertir texto a voz son los que tienen nombres de personas. Yo descargué los paquetes de español México y español España. En total fueron 4 paquetes de idioma.

Lo siguiente que hice fue crear un proyecto de C# con .Net Framework. Referencié el archivo Microsoft.Speech.dll en mi proyecto:

Para 64 bits, la dll está en C:\Program Files\Microsoft SDKs\Speech\v11.0\Assembly

Para 32 bits, está en C:\Program Files (x86)\Microsoft SDKs\Speech\v11.0\Assembly

Finalmente copié y pequé un poco del código de esta web: https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/december/voice-recognition-speech-recognition-with-net-desktop-applications

        static void Main(string[] args)
        {
            try
            {
                ss.SetOutputToDefaultAudioDevice();
                Console.WriteLine("\n(Speaking: I am awake)");
                ss.Speak("He despertado");
                CultureInfo ci = new CultureInfo("es-PE");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }

Y apenas empezar el debugueo me saltó este error:

Retrieving the COM class factory for component with CLSID {D941651C-44E6-4C17-BADF-C36826FC3424} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

Luego de intentar varias soluciones: cambiar a 32 bits, cambiar a .Net Framework 4, iniciar Visual Studio como administrador, lo único que funcionó fue lo propuesto en este foro


En 64 bits el instalador está en C:\Program Files\Microsoft SDKs\Speech\v11.0\Redist

En 32 bits está en C:\Program Files (x86)\Microsoft SDKs\Speech\v11.0\Redist

Al ejecutar los instaladores se pueden ver los mensajes de que se están registrando las dlls.

Lugo volví a referenciar la dll de 64 bits, cambié a .Net Framework 4.5, puse que se trata de una aplicación de 64 bits, y probé.

Funcionó, la aplicación puede decir "He despertado" con la voz de una mujer (apodada Hilda).

Ya puedo ponerle voz a mis aplicaciones de C# :)

jueves, 17 de febrero de 2011

C# y Ms Access: Excepciòn del tipo "Insert Into Syntaxis Error"

Sucedió un día que tenía que insertar unos datitos a una base de datos en Access 2003 usando C#. La base de datos tiene una sola tabla (la llamaré "miTabla") con tres campos: "No", "un_ID" y "Tittle" de tipos numérico, texto y texto, respectivamente.

Mi código era:

private void AddDato(string No, string ID, string Tittle, ref OleDbConnection cnn)
        {
            OleDbCommand cmd = new OleDbCommand(
"INSERT INTO miTabla (No, un_ID, Tittle) VALUES(@Num, @uID, @nTittle)", cnn);
            cmd.Parameters.AddWithValue("@Num", Convert.ToInt32(No));
            cmd.Parameters.AddWithValue("@uID", ID);
            cmd.Parameters.AddWithValue("@nTittle", Tittle);          

                cnn.Open();
                cmd.ExecuteNonQuery();

                cmd.Dispose();
                cnn.Close();
            }
        }


Y a pesar de estar todo bien, siempre me tiraba una excepción que decía "Syntaxis Error en Insert Into", o cualquier cosa parecida, en la línea cmd.ExecuteNonQuery().

Después de horas depurando y leyendo foros, encontré por ahí un tip clave:
A las bases de datos en Access no les gustan los campos con nombres como "Date", "login" o "Password".

Entonces el error no estaba en mi Insert Into, si no, posiblemente, en los nombres de mis campos.
Hice una pequeña modificación al código (no a la base de datos) y el problema se resolvió maravillosamente:

private void AddDato(string No, string ID, string Tittle, ref OleDbConnection cnn)
        {
            OleDbCommand cmd = new OleDbCommand(
"INSERT INTO miTabla ([No], [un_ID], [Tittle]) VALUES(@Num, @uID, @nTittle)", cnn);
            cmd.Parameters.AddWithValue("@Num", Convert.ToInt32(No));
            cmd.Parameters.AddWithValue("@uID", ID);
            cmd.Parameters.AddWithValue("@nTittle", Tittle);

                cnn.Open();
                cmd.ExecuteNonQuery();


                cmd.Dispose();
                cnn.Close();
            }
        }
 

Dejo como tarea hallar el cambio que hice :)

viernes, 7 de agosto de 2009

Microsoft Connect y cómo instanciar una clase en C#

Sucedió que necesitaba trabajar con manipulación de imágenes en C# (en el namespace System.Drawing) pero en una aplicación de consola. Los problemas que tuve al declarar objetos globales del tipo ColorPalette e Image me llevaron a escribirles a la gente de Microsoft Connect (siempre programo mi C# en el Visual Studio Express). Lo que me respondieron está en este link (en inglés).

En la solución que dan dicen que hace falta crear una instancia a la clase Process. Crear una instancia es simplemente usar: AnyClass p = new AnyClass(); pues .net asigna un constructor por defecto a todas las clases, aún si este no se declara (también hay un destructor implícito).
La solución la programé yo misma, luego de leer las instrucciones de Alex Turner.

Haciendo simplemente:
Image fotoJpg;
ColorPalette cp;

static void Main(string[] args)
{
Program p = new Program();
p.fotoJpg = Image.FromFile("C:\\background-black.jpg");
p.cp = p.fotoJpg.Palette;
}
}

Ya tenía los objetos ColorPalette e Image como globales.

See ya next time!