martes, octubre 25, 2011

Alternativa libre a MS Project

Buscando por la web encontre un programa para gestionar tareas, actividades, similar a Microsoft Project, me refiero a Gant Project.

Gant Project es una alternativa libre al ya conocido MS Project, puedes descargarlo de la siguiente pagina http://www.ganttproject.biz/

sábado, octubre 22, 2011

Saber el PRODUCTCODE de un instalador usando Batch

despues de algunos meses sin postear escribire algo acerca del PRODUCTOCODE de los paquetes de instalación de windows.



Cuando generamos un instalador de un proyecto hecho en .NET, se genera un paquete con la extension msi. Al generar un instalador podemos indicarle la versión, la ruta donde se intalará, el ProductCode entre otras cosas.



Cada vez que se cambia la version en la capa de instalación de un proyecto en .NET, el entorno hace la siguiente pregunta:






Si le damos click en Sí, el ProductCode cambiará automaticamente.


el productCode de una aplicación .NET es importante a la hora de querer desinstalar una versión antigua o si derrepente se quiere realizar una actualizacion a la versión actual.


Teniendo en claro esto, que pasa si solo se cuenta con el instalador .msi y no se tiene las fuentes o si por ahi se realizó una instalacion con cierta versión y las fuentes originales sufrieron mas cambios de versiones sin haber guardado un historial.


Una solución para saber el ProductCode de un instalador es la siguiente:

Crear el archivo GetMSIProductCode.vbs (la extensión debe ser .vbs) y colocar el siguiente script:





'---------------------------------------------------------------------------------------------


' GetMSIProductCode.vbs

Option Explicit

' Variables
Const msiOpenDatabaseModeReadOnly = 0

' Get command-line arguements
Dim argCount:argCount = Wscript.Arguments.Count

' Connect to the Windows Installer object.
On Error Resume Next
Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer") : CheckError

' Open the database (read-only).
Dim databasePath:databasePath = Wscript.Arguments(0)
Dim openMode : openMode = msiOpenDatabaseModeReadOnly
Dim database : Set database = installer.OpenDatabase(databasePath, openMode) : CheckError

' Extract language info and compose report message
Wscript.Echo "Database (MSI) = " & databasePath
Wscript.Echo "ProductName = " & ProductName(database)
Wscript.Echo "ProductCode = " & ProductCode(database)

' Clean up
Set database = nothing
Wscript.Quit 0

' Get the Property.ProductName value.
Function ProductName(database)
On Error Resume Next
Dim view : Set view = database.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductName'")
view.Execute : CheckError
Dim record : Set record = view.Fetch : CheckError
If record Is Nothing Then ProductName = "Not specified!" Else ProductName = record.StringData(1)
End Function

' Get the Property.ProductCode value.
Function ProductCode(database)
On Error Resume Next
Dim view : Set view = database.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")
view.Execute : CheckError
Dim record : Set record = view.Fetch : CheckError
If record Is Nothing Then ProductCode = "Not specified!" Else ProductCode = record.StringData(1)
End Function

Sub CheckError
Dim message, errRec
If Err = 0 Then Exit Sub
message = Err.Source & " " & Hex(Err) & ": " & Err.Description
If Not installer Is Nothing Then
Set errRec = installer.LastErrorRecord
If Not errRec Is Nothing Then message = message & vbNewLine & errRec.FormatText
End If
Fail message
End Sub

Sub Fail(message)
Wscript.Echo message
Wscript.Quit 2
End Sub


'---------------------------------------------------------------------------------------------


En el disco “C:\” copiar el instalador .msi del cual se desea saber su ProductCode y además copiamos el archivo GetMSIProductCode.vbs que acabamos de crear

En la ventana de ejecutar colocamos CMD e ingresamos al DOS

Luego, en la ventana de DOS nos situamos en el disco “C:\“ (o en el directorio que elijas pero debes copiar el instalador y el GetMSIProductCode.vbs)

Escribimos el siguiente código:

cscript GetMSIProductCode.vbs "[nombre del instalador].msi"

si el instalador se encuentra en otra ruta debes colocar la dirección completa.

El resultado arrojará el ProductCode en el DOS.

viernes, abril 29, 2011

UserControl: NotificationBar

El siguiente control funciona como un mensaje dentro del formulario que lo contenga.

Para poder crear este control debemos agregar un nuevo UserControl con el nombre NotificationBar.vb y escribir el siguiente código:
Public Class NotificationBar

Private _NumberOfTimesBlink As Integer

Public Enum NotificationIconType
Exclamation
Information
Question
End Enum

_
Public Property BlinkTimes() As Integer
Get
Return Me._NumberOfTimesBlink
End Get
Set(ByVal value As Integer)
Me._NumberOfTimesBlink = value
If value Then
Me.TableLayoutPanel1.ColumnStyles(0).Width = 35
Else
Me.TableLayoutPanel1.ColumnStyles(0).Width = 0
End If
End Set
End Property

Public Sub New()
InitializeComponent()
Me.Visible = False
Me.Dock = DockStyle.Top
Me._NumberOfTimesBlink = 7
End Sub

Public Sub Clear()
lblMensaje.Text = ""
Me.picIcon.Image = Nothing
Me.Visible = False
End Sub
Public Sub ShowNotificiation(ByVal NotificationText As String, ByVal NotificationType As NotificationIconType, ByVal Blink As Boolean)
Me.Visible = True
Clear()
Me.lblMensaje.Text = NotificationText
Select Case NotificationType
Case NotificationIconType.Exclamation
Me.picIcon.Image = My.Resources.Resources.WarningHS
Case NotificationIconType.Information
Me.picIcon.Image = My.Resources.Resources.important
Case NotificationIconType.Question
Me.picIcon.Image = My.Resources.Resources.question16
End Select
Me.Visible = True
If Blink Then
Me.tmrBlink.Enabled = True
End If
Me.BackColor = Color.White
Me.ForeColor = Color.FromArgb(48, 75, 139)
End Sub

Private Sub tmrBlink_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBlink.Tick
Static NumberOfTimesBlinked As Integer

If NumberOfTimesBlinked > Me._NumberOfTimesBlink Then
NumberOfTimesBlinked = 0
Me.tmrBlink.Enabled = False
Else
If NumberOfTimesBlinked Mod 2 = 0 Then
Me.BackColor = Color.FromArgb(48, 75, 139)
Me.ForeColor = Color.White
Else
Me.BackColor = Color.White
Me.ForeColor = Color.FromArgb(48, 75, 139)
End If

NumberOfTimesBlinked += 1
End If
End Sub

Private Sub NotificationBar_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Visible = False
End Sub

Private Sub pbxClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles pbxClose.Click
Clear()
End Sub
End Class



Luego volvemos a generar el proyecto y agregamos un nuevo formulario y del cuadro de herramientas arrastramos el controls NotificationBar (se muestra cuando se vuelve a generar el proyecto)

Función para limpiar controles en Vb.net

Esta sencilla funcion permite limpiar los controles de un formulario.
  
Public Sub EmptyControls(ByVal Value As Control)
For Each control As Object In Value.Controls
If control.TabIndex = 1 Then
control.Focus()
End If
If TypeOf control Is TextBox Then
control.Text = String.Empty
End If
If TypeOf control Is ComboBox Then
control.selectedValue = String.Empty
End If

If TypeOf control Is RadioButton Then
control.Checked = False
End If

If TypeOf control Is CheckBox Then
control.Checked = False
End If

If TypeOf control Is GroupBox Then
EmptyControls(control)
End If

If TypeOf control Is Panel Then
EmptyControls(control)
End If

If TypeOf control Is TabControl Then
EmptyControls(control)
End If

If TypeOf control Is TabPage Then
EmptyControls(control)
End If

If TypeOf control Is SplitContainer Then
EmptyControls(control)
End If

If TypeOf control Is DataTable Then
control.Dispose()
End If

If TypeOf control Is DataSet Then
control.dispose()
End If
If TypeOf control Is MaskedTextBox Then
control.text = String.Empty
End If

Next
End Sub

UserControl: ToolStripNumericUpDown

Para agregar un control NumericUpDown dentrol de un ToolStrip debemos agregar una nueva clase y copiar el siguiente código.

Imports System.Windows.Forms.Design

_
Public Class ToolStripNumericUpDown : Inherits ToolStripControlHost

Public Event ValueChanged As EventHandler

Public Sub New()
MyBase.New(New NumericUpDown)
End Sub

Public ReadOnly Property ToolStripNumericUpDown() As NumericUpDown
Get
Return CType(Control, NumericUpDown)
End Get
End Property

#Region "Propiedades"
Shared _someSharedValue As Decimal = 100
Public Shared Property SomeSharedValue() As Decimal
Get
Return _someSharedValue
End Get
Set(ByVal value As Decimal)
_someSharedValue = value
End Set
End Property

Public Property Value() As Decimal

Get
Return ToolStripNumericUpDown.Value
End Get

Set(ByVal value As Decimal)
ToolStripNumericUpDown.Value = value
End Set

End Property

#End Region

#Region "Eventos"
Protected Overrides Sub OnSubscribeControlEvents(ByVal c As Control)

MyBase.OnSubscribeControlEvents(c)

Dim toolStripNumericUpDown As NumericUpDown = CType(c, NumericUpDown)

AddHandler toolStripNumericUpDown.ValueChanged, AddressOf HandleValueChanged

End Sub

Protected Overrides Sub OnUnsubscribeControlEvents(ByVal c As Control)

MyBase.OnUnsubscribeControlEvents(Control)

Dim toolStripNumericUpDown As NumericUpDown = CType(c, NumericUpDown)

RemoveHandler toolStripNumericUpDown.ValueChanged, AddressOf HandleValueChanged

End Sub

Private Sub HandleValueChanged(ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent ValueChanged(Me, e)
End Sub
#End Region

End Class



ToolStripNumericUpDown es un control que tiene la misma funcioanlidad que un NumericUpDown pero dentro de un ToolsTrip.

Para ver el resultado volvemos a generar nuestro proyecto y en un formulario agregamos un ToolStrip y añadimos un nuevo elemento, se podrá apreciar que ahora aparece la opción de agregar un NumericUpDown.