Si vas a copiar

.. y pegar este post en tu web o blog personal, por favor te pido que coloques el link del post de donde lo copiastes:

Fuente:

Mostrando las entradas con la etiqueta C#. Mostrar todas las entradas
Mostrando las entradas con la etiqueta C#. Mostrar todas las entradas

La mejor forma de encriptar contraseñas en C# y VB.NET

31 de octubre de 2012 3 comentarios:


Hace como dos años hice este post pero la encriptacion md5 es considerada insegura, incluso desde mucho antes de crear ese post

¿Porque md5 es inseguro?


Con el hardware actual es posible crackear md5, de hecho en internet hay herramientas y hasta paginas web como http://crackstation.net/ que te ayudan a crackear no solo md5 sino una amplia cantidad de algoritmos de hash/encriptacion, pero existe una utilidad mucho mas poderosa capaz de crackear md5 llamada oclHashcat-lite que usa el procesador grafico GPU(tarjeta de video/grafica)

Esta utilidad es capaz de crackear los siguientes algoritmos:

  • MD5
  • md5($pass.$salt)
  • Joomla
  • SHA1
  • nsldap, SHA-1(Base64), Netscape LDAP SHA
  • sha1($pass.$salt)
  • nsldaps, SSHA-1(Base64), Netscape LDAP SSHA
  • Oracle 11g
  • MSSQL(2000)
  • MSSQL(2005)
  • MySQL
  • MD4
  • md4($pass.$salt)
  • NTLM
  • Domain Cached Credentials, mscash
  • SHA256
  • sha256($pass.$salt)
  • descrypt, DES(Unix), Traditional DES
  • SHA512
  • sha512($pass.$salt)
  • SL3
  • Cisco-PIX MD5
  • Double MD5
  • vBulletin < v3.8.5
  • vBulletin > v3.8.5
  • IPB2+, MyBB1.2+
  • LM
  • Oracle 7-10g, DES(Oracle)
  • y muchos mas...

Segun http://www.codinghorror.com/blog/2012/04/speed-hashing.html arroja estos resultados en este GPU y CPU:

  • Radeon 7970           8213.6 M c/s
  • 6-core AMD CPU   52.9     M c/s
 (PRONTO HARE PRUEBAS EN MI AMD HIS 6950 2GB Y CORE i5 2500K)

Ejecute el archivo: oclExample.cmd que contiene el siguiente comando de prueba:

oclHashcat-lite64.exe 9b957cc6ab97cbf88c4f6f0f146adafe

Tardo elrededor de 20minutos para crackear con:


  • AMD 6950 2GB: 4600 M/s
AMD 6950 2GB

Tardo alrededor de 20 minutos en crackear

Con una carga de 96% y 71° de temperatura


Sin duda las tarjetas ATi/AMD son las mejores para este tipo de trabajo

Es por eso que la mejor opcion es Bcrypt


Que para definirlo brevemente es:  

Una funcion derivada de claves

Para la tecnologia .NET tenemos esta libreria llamada BCypt.NET, te puedes descargar la libreria y el codigo fuente tambien, incluso viene con UnitTest para testearla

Recuerda agregar el archivo BCrypt.Net.dll como referencia al proyecto

Es muy sencillo de usar ya que posee solo cuatro metodos y ademas son estaticos, asi que no es necesario instanciar la clase BCrypt para acceder a esos metodos:

  1. GenerateSalt()
  2. HashPassword()
  3. HashString()
  4. Verify()

La documentacion te la puedes descargar de aqui, es un archivo de ayuda de Windows que por cierto esta en ingles, pero como dije es muy facil de usar

Existen dos pasos importantes aqui a la hora de de/encriptar contraseñas:

  1. Encriptar la contraseña cuando se agregue/edite un usuario
  2. Usar el metodo Verify() para verificar que la contraseña de la base de datos corresponde con la contraseña dada

Codigo C#: (pseudocodigo por los momentos)

Aqui tengo un sistema de login usando esta encriptacionen Access 2007

/*
 * Creado por tttony 2012
 * http://tttony.blogspot.com/
 *
 * POR FAVOR NO BORRES ESTE COMENTARIO
 */

public bool AddUser(string name, string pass)
{
    string hashed = BCrypt.Net.BCrypt.HashPassword(pass, BCrypt.Net.BCrypt.GenerateSalt());

    //
    // Agregar aqui la sentencia sql INSERT para guardar el usuario
    // y contraseña encriptada
    //

    // Retornar el valor necesario
    //
    return false;
}

public bool Login(string name, string pass)
{
    //
    // Primero encuentra el usuario
    //
    // SELECT * FROM TablaUsuarios WHERE = 'name'
    //
    // if (founds == 1) si encontro uno
    //
    // Entonces con el objecto del usuario encuentra la contraseña
    // y pasala a la funcion BCrypt.Net.BCrypt.Verify()
    //

    //
    // La funcion Verify() verifica si la contraseña encriptada que
    // esta guardada en la base de datos contiene la palabara clave
    // con la contraseña dada
    //
    bool verify = BCrypt.Net.BCrypt.Verify(pass, password);

    return verify;
}


ESTE POST SE ACTUALIZARA


Publicado en tttony.blogspot.com

Extraer icono de un ejecutable en C# y VB.NET

11 de agosto de 2011 No hay comentarios.:
C#:


// Extraer el icono de la misma aplicacion
this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
// O de otra
this.Icon = Icon.ExtractAssociatedIcon(@"C:\dev\app\ejecutable.exe");


VB.NET:


' Extraer el icono de la misma aplicacion
Me.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath)
' O de otra
Me.Icon = Icon.ExtractAssociatedIcon("C:\dev\app\ejecutable.exe")



Publicado en tttony.blogspot.com

Iniciar un programa en C# y VB.NET

19 de abril de 2011 No hay comentarios.:
C#


using System;
using System.Diagnostics;
using System.ComponentModel;

namespace MyProcessSample
{
class MyProcess
{
public static void Main()
{
Process myProcess = new Process();

try
{
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "C:\\ejecutable.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();

}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}





VB.NET


Imports System
Imports System.Diagnostics
Imports System.ComponentModel


Namespace MyProcessSample

Class MyProcess

Public Shared Sub Main()
Dim myProcess As New Process()

Try

myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.FileName = "C:\\ejecutable.exe"
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()

Catch e As Exception
Console.WriteLine((e.Message))
End Try
End Sub
End Class
End Namespace




Publicado en tttony.blogspot.com

Centrar el texto de una columna en un DataGridView en C# y VB.NET

31 de enero de 2011 4 comentarios:
Centrar el texto de una columna tiene una desventaja y es que no es posible ordenar las columnas

C#


private void form_load()
{

// primero asignar las columnas como no sortables, osea, no ordenables
dgv1.Columns["nombre_columna"].SortMode = DataGridViewColumnSortMode.NotSortable;

// segundo asignarle que se centre el texto de la columna
dgv1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

}



VB:NET


Private Sub form_load()

' primero asignar las columnas como no sortables, osea, no ordenables
dgv1.Columns("nombre_columna").SortMode = DataGridViewColumnSortMode.NotSortable

' segundo asignarle que se centre el texto de la columna
dgv1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter

End Sub




Publicado en tttony.blogspot.com

Validar columnas de solo números o mayúsculas en DataGridView en C# y VB.NET

1 comentario:
Es posible manejar la entrada de datos en cada columna del control DataGridView, usando el evento EditingControlShowing de dicho control, y es muy sencillo, así evitas por ejemplo en una columna que solo introduzcan letras mayúsculas que Copien&Peguen caracteres en minúsculas o que solo el campo sea numérico

En mi caso yo uso el tipo de columna, por ejemplo si la columna es numérica entonces asignarle el evento de solo números y si es alfa-numérico en mayúsculas le asignas la propiedad CharacterCasing a Upper ya que como sabras, las columnas de textos son simplementes TextBox

C#
/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{

    if (e.Control is TextBox)
    {
        TextBox txt = e.Control as TextBox;

        // Si la columna es numerica
        if (object.ReferenceEquals(dataGridView1.CurrentCell.ValueType, typeof(System.Int32)))
        {
            // Asignar el evento de solo numeros a las columnas numericas
            txt.KeyPress += OnlyNumbers_KeyPress;
        }
        else // o texto
        {
            /*
             * Quitar el EventHandler del KeyPress para que permita escribir texto
             */
            txt.KeyPress -= OnlyNumbers_KeyPress;
            ((TextBox)(e.Control)).CharacterCasing = CharacterCasing.Upper;
        }
    }
}

private void OnlyNumbers_KeyPress(object sender, KeyPressEventArgs e)
{
    if (!Char.IsDigit(e.KeyChar) && e.KeyChar != 8) // Si no es numerico y si no es espacio
    {
        // Invalidar la accion
        e.Handled = true;
        // Enviar el sonido de beep de windows
        System.Media.SystemSounds.Beep.Play();
    }
}


VB.NET


Private Sub dataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs)

 If TypeOf e.Control Is TextBox Then
  Dim txt As TextBox = TryCast(e.Control, TextBox)

  ' Si la columna es numrica
  If Object.ReferenceEquals(dataGridView1.CurrentCell.ValueType, GetType(System.Int32)) Then
   ' Asignar el evento de solo numeros a las columnas numericas
   AddHandler txt.KeyPress, AddressOf OnlyNumbers_KeyPress
  Else
   ' o texto
   '
'             * Quitar el EventHandler del KeyPress para que permita escribir texto
'             

   RemoveHandler txt.KeyPress, AddressOf OnlyNumbers_KeyPress
   DirectCast(e.Control, TextBox).CharacterCasing = CharacterCasing.Upper
  End If
 End If
End Sub

Private Sub OnlyNumbers_KeyPress(sender As Object, e As KeyPressEventArgs)
 If Not [Char].IsDigit(e.KeyChar) AndAlso e.KeyChar <> 8 Then
  ' Si no es numerico y si no es espacio
  ' Invalidar la accion
  e.Handled = True
  ' Enviar el sonido de beep de windows
  System.Media.SystemSounds.Beep.Play()
 End If
End Sub


FUENTE

Publicado en tttony.blogspot.com

Centrar un formulario en C# y VB.NET

27 de enero de 2011 No hay comentarios.:
Los formularios tienen una propiedad, que puedes usar para centrar el formulario cuando este se muestra:

form1.StartPosition = FormStartPosition.CenterScreen;


El detalle con esto es que si por ejemplo, quieres modificar el tamaño del formulario cuando se cargue, la propiedad StartPosition no nos servirá

C#
/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

private void form_Load(object sender, EventArgs e)
{

this.Width = 333;

// esto no funciona
form.StartPosition = FormStartPosition.CenterScreen;
}


Así que puedes usar este código para centrarlo basándose en el tamaño de tu monitor:

C#
/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

private void form_Load(object sender, EventArgs e)
{

this.Width = 333;

/*
* Centrar el formulario
*/
int boundWidth = Screen.PrimaryScreen.Bounds.Width;
int boundHeight = Screen.PrimaryScreen.Bounds.Height;
int x = boundWidth - this.Width;
int y = boundHeight - this.Height;
this.Location = new Point(x / 2, y / 2);

}



VB.NET
/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

Private Sub form_Load(sender As Object, e As EventArgs)

Me.Width = 333

Dim boundWidth As Integer = Screen.PrimaryScreen.Bounds.Width
Dim boundHeight As Integer = Screen.PrimaryScreen.Bounds.Height
Dim x As Integer = boundWidth - Me.Width
Dim y As Integer = boundHeight - Me.Height
Me.Location = New Point(x \ 2, y \ 2)

End Sub


Publicado en tttony.blogspot.com

Infracción de concurrencia: DeleteCommand o UpdateCommand en C# o VB.NET

1 comentario:
Si tienes este error:

Infracción de concurrencia: DeleteCommand o UpdateCommand afectó a 0 de los 1 registros esperados."


Ya sea agregando o editando un registro, es porque seguro esa tabla tiene un Id auto numérico y cuando intentas borrar o editar un registro recién guardado el nuevo Id no es retornado a menos de que lo hagas explícitamente, aqui hay un ejemplo de un registro recién agregado a un DataGridView:



Como puedes ver el Id auto numérico no es guardado

Yo intenté solucionarlo tratando de que sea lo mas sencillo posible y encontré que la mejor forma(en este caso para mi) fué, volver a cargar lo datos nuevamente después de agregarlo, algo así:

Pseudo-código:



Agregar_registro();
Recargar_registros(); // <-- Aqui se vuelve a actualizar



Esta es una manera que me funciona bien hasta los momentos si tienes una mejor por favor comentala

Publicado en tttony.blogspot.com

Detectar si Windows esta en Modo Seguro con C# y VB.NET

6 de enero de 2011 No hay comentarios.:
Desde aplicaciones .NET puedes detectar si el Windows esta siendo ejecutando en Modo seguro, con la clase SystemInformation

Tienes tres modos:

1. Normal: inicio de Windows normal
2. Modo seguro(FailSafe): inicio de Windows en modo seguro
3. Modo seguro con funciones de red:(FailSafeWithNetwork): eso mismo

Ejemplo:

C#

BootMode mode = SystemInformation.BootMode;

if (mode != BootMode.Normal)
{
    MessageBox.Show("Este programa no puede ejecutarse en modo seguro. Cerrando...");
    Application.Exit();
}


VB.NET

Dim mode As BootMode = SystemInformation.BootMode

If mode <> BootMode.Normal Then
   MessageBox.Show("Este programa no puede ejecutarse en modo seguro. Cerrando...")
   Application.[Exit]()
End If


FUENTE


Publicado en tttony.blogspot.com

Convertir codigo de C# a VB.NET y de VB.NET a C#

23 de agosto de 2010 No hay comentarios.:
Existe un utilidad en la web del conocido elGuille que te ayuda a convertir tu codigo de C# a VB.NET y viceversa

Aqui lo puedes encontrar, te bajas el ejecutable y luego te bajas las dos librerias(no se porque no coloco todo junto)

La utilidad no es 100% fiable, todavia le falta por pulir muchas cosas, yo lo uso para convertir los codigos de C# a VB.NET y tiene muchos errores, mas que todo cuando hay comentarios /* ESTE ES UN COMENTARIO EN C# */ que no los parsea bien

Tambien puedes usarlo via web: C# a VB.NET y de VB.NET a C#

Otra buena utilidad online para convertir codigo esta aqui

ACTUALIZACION: 09/08/2011

Me he encontrado una aplicacion online mucho mejor, ya que permite subir un archivo o varios archivos .zip al servidor el cual contenga los archivos .vb para VB.NET o .cs para C# que quieras convertir

http://converter.telerik.com/Default.aspx


Publicado en tttony.blogspot.com

Encriptar contraseñas con MD5 en C# y VB.NET (Obsoleto)

22 de agosto de 2010 No hay comentarios.:
ADVERTENCIA!!! la encriptacion con la funcion md5() es insegura, es mejor usar la encriptacion BCrypt
Para encriptar contraseñas en tu base de datos lo mas comun es usar la ecriptacion MD5

Codigo C#:

public string GetMD5Hash(string input)
{
    MD5CryptoServiceProvider x = new MD5CryptoServiceProvider();
    byte[] bs = Encoding.UTF8.GetBytes(input);
    bs = x.ComputeHash(bs);
    StringBuilder s = new StringBuilder();
    foreach (byte b in bs)
    {
        s.Append(b.ToString("x2").ToLower());
    }
    string password = s.ToString();
    return password;
}


Codigo VB.NET:

Public Function GetMD5Hash(input As String) As String

    Dim x As New MD5CryptoServiceProvider()
    Byte() bs = Encoding.UTF8.GetBytes(input)
    bs = x.ComputeHash(bs)
    Dim s As New StringBuilder()
    For Each b As Byte in bs

        s.Append(b.ToString("x2").ToLower())

    Next
    Dim password As String = s.ToString()
    Return password

End Function


Publicado en tttony.blogspot.com

Sistema de login en C# con Access 2007

35 comentarios:
He mejorado un poco el sistema y ademas lo puedes descargar como archivo de proyecto para VS2010

Sistema de login

Es facil de usar solo tienes que configurarlo dependiendo de como tengas la base de datos de los usuarios

NUEVO: agregada opcion de encriptacion de contraseña con Bcrypt

La contraseña de la base de datos login.accdb es: test

Ejecuta el proyecto pero modo Debug ya que la base de datos login.accdb esta en el directorio Debug e introduce estos datos:


Usuario: prueba
Contraseña: 5555

El codigo esta documentado


ACTUALIZADO 11/11/12


Publicado en tttony.blogspot.com

Manejar errores en C#

No hay comentarios.:
Los errores en las aplicaciones son un dolor de cabeza, no sirve de mucho usar:



try
{
   // codigo aqui
}
catch(Exception ex)
{
   MessageBox.Show(ex.Message);
}


Es mejor hacer un log, osea escribir en un archivo el error lanzado, en internet me encontre con este

Cada vez que haya una excepcion tienes la opcion de guardar el error en archivo propio .log o al archivo log del sistema



try
{
   // codigo aqui
}
catch(Exception ex)
{
   if (!ErrorLog.ErrorRoutine(false, ex))
       MessageBox.Show("No es posible escribir en el archivo de error");
}


Fuente: http://www.codeproject.com/KB/dotnet/logger.aspx


Publicado en tttony.blogspot.com

Encriptar/Decriptar cadenas con Base64 en C#

No hay comentarios.:
Me he encontrado un codigo para encriptar y decriptar cadenas con Base64:


static class EncryptClass
{

// http://www.codeproject.com/KB/cs/Cryptography.aspx

///
/// Encrypt a string using dual encryption method. Return a encrypted cipher Text
///

/// string to be encrypted
/// use hashing? send to for extra secirity
///
public static string Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

string key = Properties.Settings.Default.SecurityKey; //<-- crealo en tu configuracion

if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
///
/// DeCrypt a string using dual encryption method. Return a DeCrypted clear string
///

/// encrypted string
/// Did you use hashing to encrypt this data? pass true is yes
///
public static string Decrypt(string cipherString, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = {0};

try
{
/*
* La longitud de cadena enritptada con Hashing es de 24
* si es menor de 24 lanza una excepcion, asi que hay que pasar de ella
*/
toEncryptArray = Convert.FromBase64String(cipherString);
}
catch (Exception)
{
return null;
}

string key = Properties.Settings.Default.SecurityKey;

if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

tdes.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
}



Creas un valor de configuracion llamado SecurityKey en tu proyecto y le asignas un valor aleatorio

Fuente: http://www.codeproject.com/KB/cs/Cryptography.aspx

Publicado en tttony.blogspot.com

Guardar tamaño de las columnas de un DataGridView en C#

21 de agosto de 2010 No hay comentarios.:
La terea es sencilla, guardar el tamaño de las columnas de un DataGridView

Primero creas en tu configuracion un valor llamado por ej. DataGridViewColumnSize con el tipo System.Collections.Specialized.StringCollection

En el evento FormLoad despues de haber cargado tus datos en el DataGridView coloca este codigo:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

// Primera vez
if (Properties.Settings.Default.DataGridViewColumnSize == null)
{
// como es primera vez que inicia entonces colocar todas
// las columnas con el mismo tamaño
colWidth = (dgvLastServices.Width / dgvLastServices.Columns.Count) - (dgvLastServices.Columns.Count);
foreach (DataGridViewColumn col in dgvLastServices.Columns)
{
col.Width = colWidth;
}
}
else
{
StringCollection cols = Properties.Settings.Default.DataGridViewColumnSize;

string[] colsArray = new string[cols.Count];
cols.CopyTo(colsArray, 0);
Array.Sort(colsArray);

for (int i = 0; i < colsArray.Length; ++i)
{
string[] a = colsArray[i].Split(',');
int index = int.Parse(a[3]);
dataGridView1.Columns[index].DisplayIndex = Int16.Parse(a[0]);
dataGridView1.Columns[index].Width = Int16.Parse(a[1]);
dataGridView1.Columns[index].Visible = bool.Parse(a[2]);
}
}


Y en el evento FormClosing del formulario coloca esto:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
StringCollection stringCollection = new StringCollection();

int i = 0;
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
stringCollection.Add(string.Format(
"{0},{1},{2},{3}",
column.DisplayIndex.ToString("D2"), // Column order fix
column.Width,
column.Visible,
i++));
}

Properties.Settings.Default.DataGridViewColumnSize = stringCollection;
Properties.Settings.Default.Save();
}



Cuando se cierra el formulario se guarda el tamaño y propiedades de las columnas

Fuente: http://www.codeproject.com

Publicado en tttony.blogspot.com

Compactar base de datos Access 2007 en C# y VB.NET

19 de agosto de 2010 2 comentarios:
Para compactar una base de datos Access en C#, primero agregas esta referencia a tu solucion:

Microsoft Office 12.0 Access Database Engine Object Library


Y con esta funcion compactas la base de datos

Codigo C#:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

public void compact()
{

try
{
/*
* http://techieyogi.blogspot.com/2009/11/how-to-compact-access-2007-database.html
*/
Microsoft.Office.Interop.Access.Dao.DBEngine objDbEngine = new Microsoft.Office.Interop.Access.Dao.DBEngine();

// Archivo temporal no debe existir
string strDbTmp = Application.StartupPath + @"\compacting__.accdb";
// path de la base de datos a compactar
string strDB = @"C:\db\access.accdb";

objDbEngine.CompactDatabase(strDB , strDbTmp, null, null, ";pwd=" + m_dataBasePassword);

if ((new FileInfo(strDbTmp)).Length == (new FileInfo(strDB)).Length)
{
// no fue compactada ya que tiene el mismo tamaño que antes
File.Delete(strDbTmp);
}
else // compactacion exitosa
{
// copia de seguridad IMPORTANTE!!!
File.Copy(strDB, strDB + ".nocompact_" + DateTime.Today.ToString().Replace("/", "_").Substring(0, 10));
// borrar original
File.Delete(m_dataBaseFile);
// mover la db compactada
File.Move(strDbTmp, m_dataBaseFile);
}

}
catch(Exception ex)
{
ErrorToLog(ex);
}

}


Codigo VB.NET:

' * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO


Public Sub compact()

Try
'
' * http://techieyogi.blogspot.com/2009/11/how-to-compact-access-2007-database.html
'

Dim objDbEngine As New Microsoft.Office.Interop.Access.Dao.DBEngine()

' Archivo temporal no debe existir
Dim strDbTmp As String = Application.StartupPath + "\compacting__.accdb"
' path de la base de datos a compactar
Dim strDB As String = "C:\db\access.accdb"

objDbEngine.CompactDatabase(strDB, strDbTmp, Nothing, Nothing, ";pwd=" & m_dataBasePassword)

If (New FileInfo(strDbTmp)).Length = (New FileInfo(strDB)).Length Then
' no fue compactada ya que tiene el mismo tamaño que antes
File.Delete(strDbTmp)
Else
' compactacion exitosa
' copia de seguridad IMPORTANTE!!!
File.Copy(strDB, strDB & ".nocompact_" & DateTime.Today.ToString().Replace("/", "_").Substring(0, 10))
' borrar original
File.Delete(m_dataBaseFile)
' mover la db compactada
File.Move(strDbTmp, m_dataBaseFile)

End If
Catch ex As Exception
ErrorToLog(ex)
End Try

End Sub




Publicado en tttony.blogspot.com

Compilacion condicional en C#

17 de agosto de 2010 No hay comentarios.:
En C# existe algo llamado compilacion condicional (en otros lenguajes tambien existen) que no es mas que definir una variable segun el entorno (Debug, Release) por ej:

/* * Creado por tttony 2010 * http://tttony.blogspot.com/ * * POR FAVOR NO BORRES ESTE COMENTARIO */

#if (DEBUG)

// Esto se mostrara solo en modo depuracion
private void info()
{
Debug.WriteLine("Alguna informacion aqui en modo depuracion (debug)");
}

#endif



En Visual Studio por defecto no puedes elegir el modo de trabajo (Debug o Release), asi que lo activamos en el menu:


Herramientas -> Opciones -> En el panel izq. selecciona Proyectos y soluciones -> General -> En la parte derecha activa la opcion Mostrar configuraciones de generacion avanzadas


Ahora si vas al menu:


Proyecto -> Propiedades de TU_PROYECTO -> Generar


Alli veras que se han activado unos combosBox (Configuracion y Plataforma respectivamente) en la parte de arriba, podras configurar que es lo que quieres en modo debug y modo release



Publicado en tttony.blogspot.com

Agregar tu programa al inicio de Windows en C# y VB.NET

16 de agosto de 2010 1 comentario:
Con este codigo puedes iniciar tu aplicacion con Windows:

Codigo C#:

/*
* Creado por tttony 2010
* http://tttony.blogspot.com/
*
* POR FAVOR NO BORRES ESTE COMENTARIO
*/
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
string path = hklm.GetValue(Application.ProductName).ToString();

string thisApp = Application.ExecutablePath.ToUpper();

if (path != thisApp) // No se inicia con windows
{
hklm.SetValue(Application.ProductName, thisApp);
}

hklm.Close();


Codigo VB.NET:

'
' * Creado por tttony 2010
' * http://tttony.blogspot.com/
' *
' * POR FAVOR NO BORRES ESTE COMENTARIO
'

Dim hklm As RegistryKey = Registry.LocalMachine
hklm = hklm.CreateSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run")
Dim path As String = hklm.GetValue(Application.ProductName).ToString()

Dim thisApp As String = Application.ExecutablePath.ToUpper()

If path <> thisApp Then
' No se inicia con windows
hklm.SetValue(Application.ProductName, thisApp)
End If

hklm.Close()




Publicado en tttony.blogspot.com

Guardar configuracion previa en C# y VB.NET

3 comentarios:
Cada vez que compilas tu programa en C# cambia la version del ensamblado y por consiguiente la aplicacion crea una nueva carpeta:


C:\Documents and Settings\Usuario\Configuración local\Datos de programa\NOMBREPROGRAMA\NOMREDELEJECUTABLE.EXE_Url_2ha3w3vmz3qfzpaloruetfyed\1.0.3880.23525\app.config


Otra compilacion:

C:\Documents and Settings\Usuario\Configuración local\Datos de programa\NOMBREPROGRAMA\NOMREDELEJECUTABLE.EXE_Url_2ha3w3vmz3qfzpaloruetfyed\1.0.3880.24678\app.config


Entonces ahi tendras problemas con la configuracion y tendras que configurar el programa cada vez que lo compiles

Para evitar esto agrega este codigo, normalmente lo agrego en el archivo Program.cs de la solucion:

Codigo C#:

/*
* Importar la ultima configuracion
*/
Version appVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

// Cambio la version del ensamblado???
// si es asi entonces guardalo
if (Properties.Settings.Default.ApplicationVersion != appVersion.ToString())
{
Properties.Settings.Default.Upgrade(); // <-- aqui importa la configuracion anterior
Properties.Settings.Default.ApplicationVersion = appVersion.ToString();
Properties.Settings.Default.Save();
}



Codigo VB.NET:

'
' * Importar la ultima configuracion
'

Dim appVersion As Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version

' Cambio la version del ensamblado???
' si es asi entonces guardalo
If Properties.Settings.[Default].ApplicationVersion <> appVersion.ToString() Then
Properties.Settings.[Default].Upgrade()
' <-- aqui importa la configuracion anterior
Properties.Settings.[Default].ApplicationVersion = appVersion.ToString()
Properties.Settings.[Default].Save()
End If


Como veras tendras que agregar un campo de configuracion llamado ApplicationVersion


Publicado en tttony.blogspot.com

BrowserFolder en C# y VB.NET

No hay comentarios.:
Necesitado en un BrowserFolder me encontre con este:

Codigo C#:

folderBrowserDialog1.Description = "Buscar el directorio";

// Para tener un directorio de inicio propio debes primero
// asignar a RootFolder = Environment.SpecialFolder.MyComputer
// luego en la siguiente linea escribes el directorio de inicio
// en SelectedPath

folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
folderBrowserDialog1.SelectedPath = Application.StartupPath; // <-- Directorio de inicio

if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
txtReportsPath.Text = folderBrowserDialog1.SelectedPath;
}


Codigo VB.NET:

folderBrowserDialog1.Description = "Buscar el directorio"
' Para tener un directorio de inicio propio debes primero
' asignar a RootFolder = Environment.SpecialFolder.MyComputer
' luego en la siguiente linea escribes el directorio de inicio
' en SelectedPath
folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer
folderBrowserDialog1.SelectedPath = Application.StartupPath ' <-- Directorio de inicio
If folderBrowserDialog1.ShowDialog() = DialogResult.OK Then
txtReportsPath.Text = folderBrowserDialog1.SelectedPath
End if


Pues bien o mejor dicho mal, ya que este control no permite ver carpetas en la red, si que malo no???

Buscando en la web, me encontre con la funcion SHBrowseForFolder de la API de Windows, segui buscando y encontre este codigo que tambien venia sin el InitDir, asi que lo modifique:

Codigo C#:

using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WINAPI32
{
/*
* Codigo original de netomatix.com
* http://www.netomatix.com/FolderBrowser.aspx
*
* Modificado para tener un directorio de inicio por: tttony 2010
* http://tttony.blogspot.com/
*
* POR FAVOR NO BORRAR ESTE COMENTARIO
*/
public delegate int BrowseCallbackProc(IntPtr hwnd, int uMsg, IntPtr wParam, IntPtr lParam);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
[ComVisible(true)]
public class BROWSEINFO
{
public IntPtr hwndOwner;
public IntPtr pidlRoot;
public IntPtr pszDisplayName;
public string lpszTitle;
public int ulFlags;
public BrowseCallbackProc lpfn;
public IntPtr lParam;
public int iImage;

}

public class Win32SDK
{
[DllImport("shell32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern IntPtr SHBrowseForFolder(BROWSEINFO bi);

[DllImport("shell32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);

[DllImport("shell32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, string lParam);

}

public enum BrowseForFolderMessages
{
BFFM_ENABLEOK = 0x465,
BFFM_INITIALIZED = 1,
BFFM_IUNKNOWN = 5,
BFFM_SELCHANGED = 2,
BFFM_SETEXPANDED = 0x46a,
BFFM_SETOKTEXT = 0x469,
BFFM_SETSELECTIONA = 0x466,
BFFM_SETSELECTIONW = 0x467,
BFFM_SETSTATUSTEXTA = 0x464,
BFFM_SETSTATUSTEXTW = 0x468,
BFFM_VALIDATEFAILEDA = 3,
BFFM_VALIDATEFAILEDW = 4
}

[Flags, Serializable]
public enum BrowseFlags
{
BIF_DEFAULT = 0x0000,
BIF_BROWSEFORCOMPUTER = 0x1000,
BIF_BROWSEFORPRINTER = 0x2000,
BIF_BROWSEINCLUDEFILES = 0x4000,
BIF_BROWSEINCLUDEURLS = 0x0080,
BIF_DONTGOBELOWDOMAIN = 0x0002,
BIF_EDITBOX = 0x0010,
BIF_NEWDIALOGSTYLE = 0x0040,
BIF_NONEWFOLDERBUTTON = 0x0200,
BIF_RETURNFSANCESTORS = 0x0008,
BIF_RETURNONLYFSDIRS = 0x0001,
BIF_SHAREABLE = 0x8000,
BIF_STATUSTEXT = 0x0004,
BIF_UAHINT = 0x0100,
BIF_VALIDATE = 0x0020,
BIF_NOTRANSLATETARGETS = 0x0400,
}

public class FolderBrowser
{
private string m_strDirectoryPath;
private string m_strTitle;
private string m_strDisplayName;
private BrowseFlags m_Flags;
private string m_initDir = null;

public FolderBrowser()
{
m_Flags = BrowseFlags.BIF_DEFAULT;
m_strTitle = "";
}

public string DirectoryPath
{
get { return this.m_strDirectoryPath; }
}

public string DisplayName
{
get { return this.m_strDisplayName; }
}

public string Title
{
set { this.m_strTitle = value; }
}

public BrowseFlags Flags
{
set { this.m_Flags = value; }
}

public DialogResult ShowDialog()
{
BROWSEINFO bi = new BROWSEINFO();
bi.pszDisplayName = IntPtr.Zero;
//bi.lpfn = IntPtr.Zero;
/*
* InitDir??
*/
bi.lpfn = new BrowseCallbackProc(browserCallBack);
bi.lParam = IntPtr.Zero;
bi.lpszTitle = "Select Folder";
IntPtr idListPtr = IntPtr.Zero;
IntPtr pszPath = IntPtr.Zero;
try
{
if (this.m_strTitle.Length != 0)
{
bi.lpszTitle = this.m_strTitle;
}
bi.ulFlags = (int)this.m_Flags;
bi.pszDisplayName = Marshal.AllocHGlobal(256);
// Call SHBrowseForFolder
idListPtr = Win32SDK.SHBrowseForFolder(bi);

// Check if the user cancelled out of the dialog or not.
if (idListPtr == IntPtr.Zero)
{
return DialogResult.Cancel;
}

// Allocate ncessary memory buffer to receive the folder path.
pszPath = Marshal.AllocHGlobal(256);
// Call SHGetPathFromIDList to get folder path.
bool bRet = Win32SDK.SHGetPathFromIDList(idListPtr, pszPath);
// Convert the returned native poiner to string.
m_strDirectoryPath = Marshal.PtrToStringAuto(pszPath);
this.m_strDisplayName = Marshal.PtrToStringAuto(bi.pszDisplayName);
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
return DialogResult.Abort;
}
finally
{
// Free the memory allocated by shell.
if (idListPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(idListPtr);
}
if (pszPath != IntPtr.Zero)
{
Marshal.FreeHGlobal(pszPath);
}
if (bi != null)
{
Marshal.FreeHGlobal(bi.pszDisplayName);
}
}
return DialogResult.OK;
}

private IntPtr GetStartLocationPath()
{
return IntPtr.Zero;
}

public string InitDir
{
set { this.m_initDir = value; }
}

private int browserCallBack(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam)
{
if (uMsg == (int)BrowseForFolderMessages.BFFM_INITIALIZED)
{
/*
* Con BFFM_SETSELECTIONW todo bien
*/
Win32SDK.SendMessage(hWnd, (int)BrowseForFolderMessages.BFFM_SETSELECTIONW, 1, this.m_initDir);
}

return 0;
}
}

}


Codigo VB.NET:

Imports System.Diagnostics
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Data
Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Namespace WINAPI32
'
' * Codigo original de netomatix.com
' * http://www.netomatix.com/FolderBrowser.aspx
' *
' * Modificado para tener un directorio de inicio por: tttony 2010
' * http://tttony.blogspot.com/
' *
' * POR FAVOR NO BORRAR ESTE COMENTARIO
'

Public Delegate Function BrowseCallbackProc(hwnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer

_
_
Public Class BROWSEINFO
Public hwndOwner As IntPtr
Public pidlRoot As IntPtr
Public pszDisplayName As IntPtr
Public lpszTitle As String
Public ulFlags As Integer
Public lpfn As BrowseCallbackProc
Public lParam As IntPtr
Public iImage As Integer

End Class

Public Class Win32SDK
_
Public Shared Function SHBrowseForFolder(bi As BROWSEINFO) As IntPtr
End Function

_
Public Shared Function SHGetPathFromIDList(pidl As IntPtr, pszPath As IntPtr) As Boolean
End Function

_
Public Shared Function SHGetSpecialFolderLocation(hwnd As IntPtr, csidl As Integer, ByRef ppidl As IntPtr) As Integer
End Function

_
Public Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As Integer, lParam As String) As IntPtr
End Function

End Class

Public Enum BrowseForFolderMessages
BFFM_ENABLEOK = &H465
BFFM_INITIALIZED = 1
BFFM_IUNKNOWN = 5
BFFM_SELCHANGED = 2
BFFM_SETEXPANDED = &H46a
BFFM_SETOKTEXT = &H469
BFFM_SETSELECTIONA = &H466
BFFM_SETSELECTIONW = &H467
BFFM_SETSTATUSTEXTA = &H464
BFFM_SETSTATUSTEXTW = &H468
BFFM_VALIDATEFAILEDA = 3
BFFM_VALIDATEFAILEDW = 4
End Enum

_
Public Enum BrowseFlags
BIF_DEFAULT = &H0
BIF_BROWSEFORCOMPUTER = &H1000
BIF_BROWSEFORPRINTER = &H2000
BIF_BROWSEINCLUDEFILES = &H4000
BIF_BROWSEINCLUDEURLS = &H80
BIF_DONTGOBELOWDOMAIN = &H2
BIF_EDITBOX = &H10
BIF_NEWDIALOGSTYLE = &H40
BIF_NONEWFOLDERBUTTON = &H200
BIF_RETURNFSANCESTORS = &H8
BIF_RETURNONLYFSDIRS = &H1
BIF_SHAREABLE = &H8000
BIF_STATUSTEXT = &H4
BIF_UAHINT = &H100
BIF_VALIDATE = &H20
BIF_NOTRANSLATETARGETS = &H400
End Enum

Public Class FolderBrowser
Private m_strDirectoryPath As String
Private m_strTitle As String
Private m_strDisplayName As String
Private m_Flags As BrowseFlags
Private m_initDir As String = Nothing

Public Sub New()
m_Flags = BrowseFlags.BIF_DEFAULT
m_strTitle = ""
End Sub

Public ReadOnly Property DirectoryPath() As String
Get
Return Me.m_strDirectoryPath
End Get
End Property

Public ReadOnly Property DisplayName() As String
Get
Return Me.m_strDisplayName
End Get
End Property

Public WriteOnly Property Title() As String
Set
Me.m_strTitle = value
End Set
End Property

Public WriteOnly Property Flags() As BrowseFlags
Set
Me.m_Flags = value
End Set
End Property

Public Function ShowDialog() As DialogResult
Dim bi As New BROWSEINFO()
bi.pszDisplayName = IntPtr.Zero
'bi.lpfn = IntPtr.Zero;
'
' * InitDir??
'

bi.lpfn = New BrowseCallbackProc(AddressOf browserCallBack)
bi.lParam = IntPtr.Zero
bi.lpszTitle = "Select Folder"
Dim idListPtr As IntPtr = IntPtr.Zero
Dim pszPath As IntPtr = IntPtr.Zero
Try
If Me.m_strTitle.Length <> 0 Then
bi.lpszTitle = Me.m_strTitle
End If
bi.ulFlags = CInt(Me.m_Flags)
bi.pszDisplayName = Marshal.AllocHGlobal(256)
' Call SHBrowseForFolder
idListPtr = Win32SDK.SHBrowseForFolder(bi)

' Check if the user cancelled out of the dialog or not.
If idListPtr = IntPtr.Zero Then
Return DialogResult.Cancel
End If

' Allocate ncessary memory buffer to receive the folder path.
pszPath = Marshal.AllocHGlobal(256)
' Call SHGetPathFromIDList to get folder path.
Dim bRet As Boolean = Win32SDK.SHGetPathFromIDList(idListPtr, pszPath)
' Convert the returned native poiner to string.
m_strDirectoryPath = Marshal.PtrToStringAuto(pszPath)
Me.m_strDisplayName = Marshal.PtrToStringAuto(bi.pszDisplayName)
Catch ex As Exception
Trace.WriteLine(ex.Message)
Return DialogResult.Abort
Finally
' Free the memory allocated by shell.
If idListPtr <> IntPtr.Zero Then
Marshal.FreeHGlobal(idListPtr)
End If
If pszPath <> IntPtr.Zero Then
Marshal.FreeHGlobal(pszPath)
End If
If bi IsNot Nothing Then
Marshal.FreeHGlobal(bi.pszDisplayName)
End If
End Try
Return DialogResult.OK
End Function

Private Function GetStartLocationPath() As IntPtr
Return IntPtr.Zero
End Function

Public WriteOnly Property InitDir() As String
Set
Me.m_initDir = value
End Set
End Property

Private Function browserCallBack(hWnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer
If uMsg = CInt(BrowseForFolderMessages.BFFM_INITIALIZED) Then
'
' * Con BFFM_SETSELECTIONW todo bien
'

Win32SDK.SendMessage(hWnd, CInt(BrowseForFolderMessages.BFFM_SETSELECTIONW), 1, Me.m_initDir)
End If

Return 0
End Function
End Class

End Namespace



Como usarlo??

Codigo C#:

FolderBrowser browser = new FolderBrowser();
browser.Title = "Buscar el directorio";
browser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE | BrowseFlags.BIF_NONEWFOLDERBUTTON;
browser.InitDir = Application.StartupPath; // <-- el directorio de inicio
if (browser.ShowDialog() == DialogResult.OK)
{
txtPath.Text = browser.DirectoryPath;
}


Codigo VB.NET:

Dim browser As New FolderBrowser()
browser.Title = "Buscar el directorio"
browser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE Or BrowseFlags.BIF_NONEWFOLDERBUTTON
browser.InitDir = Application.StartupPath ' <-- el directorio de inicio
If browser.ShowDialog() = DialogResult.OK Then
txtPath.Text = browser.DirectoryPath
End if



Publicado en tttony.blogspot.com

Problemas con las fechas en Access en C# y VB.NET

5 de julio de 2010 3 comentarios:
Si han tenido problemas para buscar filas con determinadas fechas, la fecha debe ser con este formato: YYYY/MM/DD de lo contrario tendras resultados indeseables como los que he tenido, aqui les dejo esta funcion:

Codigo C#:

// Darle formato a la fecha
private string ToDBDate(DateTime dt)
{
    return dt.Year + "/" + dt.Month + "/" + dt.Day;
}


Codigo VB.NET:

' Darle formato a la fecha
Private Function ToDBDate(dt As DateTime) As String

    Return dt.Year & "/" & dt.Month & "/" & dt.Day

End Function


EL otro problema que surge es con sentencias BETWEEN

Codigo C#:

string sql = String.Format("SELECT * FROM table1 WHERE datetime BETWEEN #{0} 00:00:00# AND #{1} 23:59:59#", ToDBDate(fromDateTime), ToDBDate(toDateTime));


Codigo VB.NET:

Dim sql As String = String.Format("SELECT * FROM table1 WHERE datetime BETWEEN #{0} 00:00:00# AND #{1} 23:59:59#", ToDBDate(fromDateTime), ToDBDate(toDateTime))


Asi el resultado sera el que buscas


Publicado en tttony.blogspot.com

Buscar en el Blog



PUBLICIDAD