Monday 23 August 2010

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

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

Sunday 22 August 2010

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

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

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#

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#

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

Saturday 21 August 2010

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

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

Thursday 19 August 2010

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

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

Tuesday 17 August 2010

Compilacion condicional en C#

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

Monday 16 August 2010

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

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

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

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

Wednesday 4 August 2010

Instalar Office 2007 Enterprise desatendido

Buscando en la web me encontre de que existe una manera de instalar el Office 2007 Enterprise de forma desatendida, pues bien segun he leido la unica version que se puede instalar desatendidamente es la version Enterprise:


La forma de hacerlo es configurar el Office mediante este comando:

C:\office2007\setup.exe /admin


Luego de seguir los pasos que te indican alli, al final guardas un archivo en el menu Archivo --> Guardar con la extension desatendido.MSP y usandolo de esta manera:

OJO ESTE METODO NO ME FUNCIONO!!! SIGUE LEYENDO

C:\office2007\setup.exe /adminfile desatendido.msp


Se supone que se deberia de instalar sin preguntar nada, sin embargo no es asi, al ejecutar este ultimo comando te abre la ventana con el boton Continuar osea que no es desatendido.


Pero existe otra manera de hacerlo y es editando el archivo:

Enterprise.WW\config.xml



<Configuration Product="Enterprise">

<Display Level="basic" CompletionNotice="no" SuppressModal="yes" AcceptEula="yes" />

<!-- <Logging Type="standard" Path="%temp%" Template="Microsoft Office Enterprise Setup(*).txt" /> -->

<PIDKEY Value="AQUITUCODIGOSINELGUION" />

<USERNAME Value="PC" />

<COMPANYNAME Value="PC" />

<!-- <INSTALLLOCATION Value="%programfiles%\Microsoft Office" /> -->

<!-- <LIS CACHEACTION="CacheOnly" /> -->

<!-- <SOURCELIST Value="\\server1\share\Office12;\\server2\share\Office12" /> -->

<!-- <DistributionPoint Location="\\server\share\Office12" /> -->

<!-- <OptionState Id="OptionID" State="absent" Children="force" /> -->

<!-- <Setting Id="Reboot" Value="IfNeeded" /> -->

<!-- <Command Path="msiexec.exe" Args="/i \\server\share\my.msi" QuietArg="/q" ChainPosition="after" Execute="install" /> -->

</Configuration>


El archivo esta oculto y ademas no se puede escribir en el asi que primero guardalo por ejemplo en el Escritorio y luego lo copias y reemplazas en el directorio Enterprise.WW

Basicamente lo que se hace es que el modo de presentacion sea el basico:
Display Level="basic"

No avisar cuando termine:
CompletionNotice="no"

Suprimimos el modal:
SuppressModal="yes"

Y aceptamos la licencia:
AcceptEula="yes"



Para ejecutarlo haz lo siguiente:

C:\office2007\setup.exe /config Enterprise.WW\config.xml



NOTA: obviamente cambia el directorio por el tuyo


Publicado en tttony.blogspot.com