viernes, 15 de abril de 2011

El proveedor 'Microsoft.ACE.OLEDB.12.0' no está registrado en el equipo local

Tengo una aplicación que lee datos de un Excel y me sucedió el siguiente error:

Se detectó System.InvalidOperationException
  Message=El proveedor 'Microsoft.ACE.OLEDB.12.0' no está registrado en el equipo local.
  Source=System.Data

Entre paréntesis, mi cadena de conexión a Excel es:

Code Snippet
  1. <add name="AserewareExcelDataSource" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=FileName.xlsx;Persist Security Info=False;Extended Properties=&quot;Excel 12.0 Xml;HDR=YES;IMEX=1&quot;" providerName="System.Data.OleDb" />

Bueno después de buscar y encontrar este link, donde al parecer no existe un driver adecuado hice lo siguiente.

Mi máquina es de 64bits y tenía esto en el destino de la plataforma, lo que difiere de lo comentado el vínculo de referencia:

image

Lo cambié a “Any CPU” o bien “x64”:

image

Y listo,… funcionando perfectamente.

Imagino que instalé la versión de 64 bit del driver..que ya está.

sábado, 12 de marzo de 2011

Niveles de disponibilidad

Regularmente ando buscando esta información y no la tenía a la mano…


Entonces, ¿qué porcentaje de disponibilidad será el adecuado para una aplicación determinada? A continuación se incluyen algunas pautas:

Categoría Número de errores anual Tiempo de inactividad anual Tiempo medio de reparación Disponibilidad
No comercial 10 88 horas 10 horas 99.00%
Comercial 5 44 horas 8,8 horas 99.50%
Crítica para la empresa 4 8,5 horas 2,25 horas 99.90%
Crítica para una misión 4 1 hora 0,25 horas 99.99%
Nota Para realizar estos cálculos de disponibilidad se han utilizado 365,25 X 24 = 8.766 horas al año.

fuente: Microsoft MSDN


Tal y como se describe en el tema referente a la confiabilidad, se pueden producir errores en las aplicaciones por muchos motivos:

  • Comprobación inadecuada
  • Problemas relacionados con cambios en la administración
  • Falta de control y análisis continuados
  • Errores en las operaciones
  • Código poco consistente
  • Ausencia de procesos de diseño de software de calidad
  • Interacción con aplicaciones o servicios externos
  • Condiciones de funcionamiento distintas (cambios en el nivel de uso, sobrecargas máximas)
  • Sucesos inusuales (errores de seguridad, desbordamientos en la difusión)
  • Errores de hardware (discos, controladores, dispositivos de red, servidores, fuentes de alimentación, memoria, CPU).
  • Problemas de entorno (red eléctrica, refrigeración, incendios, inundaciones, polvo, catástrofes naturales)

Alrededor de un 40 por ciento del tiempo de inactividad de las aplicaciones se debe a una comprobación inadecuada, a una administración de cambios y a la ausencia de un control continuo de los errores. Otro 40 por ciento se debe a errores operativos producidos por la ausencia de procedimientos rigurosos y a errores de copia de seguridad/restauración. La confiabilidad del hardware ha mejorado durante los últimos años que menos del 10 por ciento del tiempo de inactividad se debe a problemas de hardware. El 10 por ciento restante del tiempo de inactividad se debe a problemas de entorno y a problemas de otro tipo.

En términos generales, se puede decir que la disponibilidad es una medida de la frecuencia con la que se puede utilizar la aplicación. Para ser más exactos, la disponibilidad es un cálculo porcentual del tiempo en que la aplicación está realmente disponible para controlar las solicitudes de servicio en comparación con el tiempo de ejecución total disponible previsto. El cálculo formal de la disponibilidad incluye el tiempo de reparación, ya que una aplicación que se está reparando no está disponible.

En el cálculo de la disponibilidad se utilizan varias medidas:

Nombre Acrónimo Cálculo Definición
Tiempo medio entre errores MTBF Horas / número de errores Duración media de funcionamiento de la aplicación antes de que produzca errores.
Tiempo medio de recuperación MTTR Horas de reparación / número de errores Tiempo medio necesario para reparar y restaurar el servicio después de que se produzca un error.

La fórmula de disponibilidad tiene esta forma:

Disponibilidad = (MTBF / (MTBF + MTTR)) X 100

Considere, por ejemplo, una aplicación concebida para que funcione continuamente. Pongamos un punto de control de 1.000 horas consecutivas, dos errores de una hora durante ese período darían lugar a una disponibilidad de ((1.000/2) / ((1.000/2) + 1)) X 100 = (500 / 501) X 100 = 0,998 X 100 = 99,8 %.

Una forma conocida de describir la disponibilidad es mediante los "nueves": los tres nueves de una disponibilidad de un 99,9%. No obstante, hay que tener en cuenta que las implicaciones de la medición por nueves a veces se malinterpretan. Es necesario realizar algunos cálculos para descubrir que tres nueves (disponibilidad de un 99,9%) representan aproximadamente 8,5 horas de interrupción de servicio en un solo año. El nivel inmediatamente superior, cuatro nueves (99,99%), representa alrededor de una hora de interrupción de servicio en un año. Cinco nueves (99,999%) representan sólo cinco minutos de interrupción al año.

fuente: Microsoft MSDN

Etiquetas de Technorati: ,

jueves, 24 de febrero de 2011

Silverlight. WebServices. WCF. Cross-Domain. clientaccesspolicy.xml

Bueno el famoso archivo “clientaccesspolicy.xml” debe colocarse en la raíz de su servidor web, no así en la raíz de un directorio virtual (configurado como aplicación) que usted haya creado.

Si usted tiene una aplicación en un directorio virtual llamado “miaplicación” tal como:

http://midominio/miaplicacion

entonces debe colocar el “clientaccesspolicy.xml” en la raíz:

http://midominio/clientaccesspolicy.xml

Este es el típico archivo predeterminado que permitiría el acceso desde cualquier dominio llamador (claro, esto siempre funcionaría en el supuesto de que sus servicios Web no tengan algún mecanismo de autentificación).

Code Snippet
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <access-policy>
  3.   <cross-domain-access>
  4.     <policy>
  5.       <allow-from http-request-headers="SOAPAction">
  6.         <domain uri="*"/>
  7.       </allow-from>
  8.       <grant-to>
  9.         <resource path="/" include-subpaths="true"/>
  10.       </grant-to>
  11.     </policy>
  12.   </cross-domain-access>
  13. </access-policy>

En cualquier caso si los dominios desde los que se llama son simples alias o entradas en un DNS (CNAME or A records) que apuntan a la misma IP, la seguridad provista por el dominio de su aplicación funcionaría adecuadamente y estaría en el contexto de las llamadas, por lo tanto una llamada a su servicio desde “midominioalias1/miaplicacion/miservicio” o desde “midominioalias2/miaplicacion/miservicio” no debería tener problemas aún cuando haya protegido sus servicios con algún mecanismo de seguridad de acceso como el provisto por ASP.NET. Este otro tema de seguridad se puede ver en Servicios WCF y ASP.NET

Ahora bien para limitar el acceso a su servicio desde dominios conocidos los mejor será eliminar el permisivo “<domain uri="*"/>”  y colocar explícitamente sus dominios en su archivo “clientaccesspolicy.xml”.

En el ejemplo siguiente, con los asteriscos, se aceptan llamadas desde cualquier subdominio de “midominio” y de subdominios de algunos otros dominios específicos (que podrían también ser alias de su propio dominio en un DNS). Podría poner una URL específica que acepta explícitamente, quitando el asterisco y reemplazándolo por “www.midominioalias1.com”.

Code Snippet
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <access-policy>
  3.   <cross-domain-access>
  4.     <policy>
  5.       <allow-from http-request-headers="SOAPAction">
  6.         <!--<domain uri="*"/>-->
  7.         <domain uri="http://midominio.com" />
  8.         <domain uri="http://*.midominio.com" />
  9.         <domain uri="http://*.midominioalias1.com" />
  10.         <domain uri="http://*.midominio2.com" />
  11.       </allow-from>
  12.       <grant-to>
  13.         <resource path="/" include-subpaths="true"/>
  14.       </grant-to>
  15.     </policy>
  16.   </cross-domain-access>
  17. </access-policy>

Dado que este archivo reside en la raíz de su sitio web, tal como está el “path” significa que podría llamar a cualquier servicio web que esté ubicado donde quiera bajo este punto de partida. Si necesita limitar el acceso a cierta ubicación debe colocar el “path”, por ejemplo: “path=”/miaplicacion/misservicios”. Vea Restricciones de seguridad de acceso a redes en Silverlight

Etiquetas de Technorati: ,,,

viernes, 4 de febrero de 2011

No olvidar El mensaje "Código de error: 0x80070002" cita un problema en la comprobación de la licencia después de una actualización en un equipo Dell

[Window Title]
Copias de seguridad de Windows: opciones para solucionar problemas

[Main Instruction]
Comprobar copia de seguridad

[Content]
El sistema no puede encontrar el archivo especificado.


[V] Mostrar detalles [Intentar ejecutar de nuevo la copia de seguridad] [Cambiar configuración de copia de seguridad] [Cancelar]

[Expanded Information]
Hora de copia de seguridad: 04/02/2011 06:28 p.m.
Ubicación de copia de seguridad: Backup (J:)
Código de error:0x80070002


El mensaje "Código de error: 0x80070002" cita un problema en la comprobación de la licencia después de una actualización en un equipo Dell

sábado, 18 de septiembre de 2010

Interop COM Exception

Introducción

Tengo una aplicación desarrollada para el NET Framework 3.5 SP1 y la he publicado en mi IIS local.

Contexto

Windows 7 64 bits, SQL Server Express 2008 R2, IIS 7

Solución
  1. Permitir 32 bit.

image

image

  1. Autorizar al usuario IUSR en la carpeta donde se encuentre registrado el componente COM.

image

  1. Autorizar al usuario en la base de datos.

 

image

Contexto

Windows Server 2008 Estándar de 32bit

Problema

Retrieving the COM class factory for component with CLSID {E95C0FB5-A09E-46F6-9CB3-ADD6B866A38A} failed due to the following error: 80040154.

System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {E95C0FB5-A09E-46F6-9CB3-ADD6B866A38A} failed due to the following error: 80040154

Solución

Simplemente registrar el componente con regsvr32. Si no conoce qué componente es busque el GUID con regedit.

viernes, 25 de junio de 2010

Error al instanciar MS Outlook Application desde un complemento de MS Project

Durante el desarrollo de un complemento (Addin) para MS Project que se conecta con Outlook me encontré el siguiente error COM al intentar crear el objeto Application de Outlook:
Código
using MSOutlook = Microsoft.Office.Interop.Outlook;
...
MSOutlook.Application outlook = new  MSOutlook.Application();



Excepción (Exception)


Error al recuperar un generador de clases COM para el componente con CLSID {0006F03A-0000-0000-C000-000000000046} debido al siguiente error: 80080005.


La solución


Aunque tediosa por lo lenta, fue reparar la instalación de Visual Studio Tools for Office y de Office (en mi caso versiones 2010) desde el panel de control.


image


image


Lamentablemente no hice la reparación en partes, por lo que no supe si sólo con una de las dos reparaciones se corrige el problema. Dejo un voto para la reparación de Office.




---(Fin)---

lunes, 24 de mayo de 2010

Operador LIKE y COLLATION. Comparación de cadenas Unicode y no Unicode

El problema

Un amigo me preguntó la causa de que sus procedimientos almacenados no funcionaran bien con las comparaciones de cadenas a partir de instalar su base de datos con cierta intercalación (collation) de SQL Server 2008.

Su base de datos tiene varios años de evolución y maduración y se ha migrado desde SQL Server 2000. Originalmente la base de datos se había creado con una intercalación de SQL Server (la famosa SQL_Latin1_General_CP1_CI_AS). Cuando se migró a SQL Server 2008 se decidió actualizar la intercalación a una moderna de Windows llamada Latin1_General_100_CI_AI (Unicode no sensible ni a mayúsculas ni a los acentos).

A partir de entonces las comparaciones simples de variables de cadena en los procedimientos almacenados no funcionaban y esta consulta literal tan simple de comparación mediante LIKE, devolvía un resultado contrario al esperado, es decir devuelve “No” en vez de “Yes”:

IF '/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT' LIKE'%/DEVELOPMENT'
SELECT 'Yes' as
IsLikeLiteral
ELSE
SELECT
'No' as
IsLikeLiteral

Lógicamente aquí era de esperar que la cadena “[lo que sea antes]/DEVELOPMENT” sí se encuentre en la primera cadena literal.

El primer problema es que estos literales son interpretados por el motor como cadenas con una intercalación no Unicode entonces si el servidor está configurado (instalado) con una intercalación Unicode como Latin1_General_100_CI_AI, los caracteres no serán interpretados de la manera que esperamos al realizar la comparación y la ordenación.

Lo más simple para ver esto es colocar el indicador de literales Unicode (N) al frente de las cadenas e inmediatamente se obtendrá el resultado correcto esperado, es decir “Yes” (ver y o ejecutar los ejemplos de más abajo en una ventana de su SQL Server Management Studio 2008, si es otra versión previa comente la intercalación de tipo “_100_”, ya que s nueva en SQL Server 2008).

El echo de que los procedimientos almacenados o funciones no realicen bien las comparaciones se debe a que todos los valores de las variables de cadena de la base de datos fueron originalmente definidas como “varchar” y almacenados con la intercalación antigua de SQL_Latin1_General_CP1_CI_AS (estas intercalaciones de SQL se mantienen por compatibilidad con el pasado y se recomienda utilizar las de Windows o bien actualizarlas).

La solución

Lo más adecuado es tomar su base de datos y hacer lo siguiente:

  • Transformar su base de datos (los datos almacenados) a la intercalación del servidor mediante este script maravilloso de Igor F. Kovalenko.
  • Actualice todas sus tablas para que utilicen tipos de datos Unicode en las cadenas (nchar, nvarchar, ntext).
  • Actualice todos sus procedimientos almacenados y funciones y cambie las declaraciones de variables de tipo “varchar” a “nvarchar” (vea el último ejemplo de la serie de consultas más abajo para que vea por qué).
    • Si tuvo la necesidad en el pasado de declarar algo como “varchar(8000)” y espera cadenas de ese largo ya no puede utilizar nvarchar con ese tamaño porque nvarchar está limitado a 4000 caracteres cuando quiere especificar la longitud. Entonces, si requiere más de 4000 caracteres, declare las variables como “nvarchar(max)” que soporta hasta 2 GB.

Fíjese que si los valores no están almacenados en la intercalación correcta aunque utilice COLLECT no obtendrá el resultado adecuado, por eso debe realizar la transformación de datos.

Para sus nuevos desarrollo, no lo dude, utilice una intercalación de Windows Unicode como la indicada aquí, que acepta un amplia variedad de idiomas humanos.

Demostrador

-------------------------------------------------
-- Comparación literal
-------------------------------------------------
IF '/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT' LIKE
'%/DEVELOPMENT'
SELECT 'Yes' as
IsLikeLiteral
ELSE
SELECT
'No' as
IsLikeLiteral

-------------------------------------------------
-- Comparación literal explícita Unicode
-------------------------------------------------
IF N'/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT' LIKE
N'%/DEVELOPMENT'
SELECT 'Yes' as
IsLikeUnicode
ELSE
SELECT
'No' as
IsLikeUnicode

-------------------------------------------------
-- Conversión a una intercalación determinada
-------------------------------------------------
IF '/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT' COLLATE Latin1_General_CI_AI LIKE '%/DEVELOPMENT' COLLATE
Latin1_General_CI_AI
SELECT 'Yes' as
IsLikeCollation
ELSE
SELECT
'No' as
IsLikeCollation

-------------------------------------------------
-- Conversión a una intercalación determinada (100)
-------------------------------------------------
IF '/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT' COLLATE Latin1_General_100_CI_AI LIKE '%/DEVELOPMENT' COLLATE
Latin1_General_100_CI_AI
SELECT 'Yes' as
IsLikeCollation100A
ELSE
SELECT
'No' as
IsLikeCollation100A

-------------------------------------------------
-- Conversión a una intercalación determinada (100)
-------------------------------------------------
IF N'/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT' COLLATE Latin1_General_100_CI_AI LIKE N'%/DEVELOPMENT' COLLATE
Latin1_General_100_CI_AI
SELECT 'Yes' as
IsLikeCollation100B
ELSE
SELECT
'No' as
IsLikeCollation100B

-------------------------------------------------
-- Comparación con varchar (cadena no unicode)
-------------------------------------------------
DECLARE @varCharInput1 varchar(500
)
DECLARE @varCharInput2 varchar(500
)
SET @varCharInput1 =
'/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT'
SET @varCharInput2 =
'%/DEVELOPMENT'

IF @varCharInput1 LIKE
@varCharInput2
SELECT 'Yes' as
IsLikeVarchar
ELSE
SELECT
'No' as
IsLikeVarchar

-------------------------------------------------
-- Finalmente este es el punto.
-- Comparación con nvarchar (cadena unicode)
-------------------------------------------------
DECLARE @nVarCharInput1 nvarchar(500
)
DECLARE @nVarCharInput2 nvarchar(500
)
SET @nVarCharInput1 =
N'/SYSTEM_ROOT/DEVELOPMENT_COMPANY/DEVELOPMENT'
SET @nVarCharInput2 =
N'%/DEVELOPMENT'

IF @nVarCharInput1 LIKE
@nVarCharInput2
SELECT 'Yes' as
IsLikeNVarchar
ELSE
SELECT
'No' as IsLikeNVarchar

Los resultados

image

---(FIN)---