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

lunes, 8 de julio de 2013

Imprimir en impresora de etiquetas SATO desde PowerShell

Aquí les dejo un pequeño programa que me habilita la impresión desde PowerShell en impresoras de etiquetas SATO. (parte del código salio de http://social.msdn.microsoft.com/Forums/en-US/94967169-a9ee-45db-9c8a-acd6f173680d/rawprinthelper-for-bold-font)...

El archivo PrinterHelper.ps1 es

clear

$src = @'
using System;
using System.IO;
using System.Runtime.InteropServices;

public class RawPrinterHelper
{
 // Structure and API declarions:
 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
 public class DOCINFOA
 {
  [MarshalAs(UnmanagedType.LPStr)]
  public string pDocName;
  [MarshalAs(UnmanagedType.LPStr)]
  public string pOutputFile;
  [MarshalAs(UnmanagedType.LPStr)]
  public string pDataType;
 }

 #region "Imports"
  [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

  [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool ClosePrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

  [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool EndDocPrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool StartPagePrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool EndPagePrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
 #endregion


 public  RawPrinterHelper(){}

 // SendBytesToPrinter()
 // When the function is given a printer name and an unmanaged array
 // of bytes, the function sends those bytes to the print queue.
 // Returns true on success, false on failure.
 public  bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
 {
  Int32 dwError = 0, dwWritten = 0;
  IntPtr hPrinter = new IntPtr(0);
  DOCINFOA di = new DOCINFOA();
  bool bSuccess = false; // Assume failure unless you specifically succeed.

  di.pDocName = "My document";
  di.pDataType = "RAW";

  try
  {
   // Open the printer.
   if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
   {
    // Start a document.
    if (StartDocPrinter(hPrinter, 1, di))
    {
     // Start a page.
     if (StartPagePrinter(hPrinter))
     {
      // Write your bytes.
      bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
      EndPagePrinter(hPrinter);
     }
     EndDocPrinter(hPrinter);
    }
    ClosePrinter(hPrinter);
   }
  }
  catch (Exception ex)
  {
   throw (ex);
  }
  // If you did not succeed, GetLastError may give more information
  // about why not.
  if (bSuccess == false)
  {
   dwError = Marshal.GetLastWin32Error();
  }
  return bSuccess;
 }

 public  bool SendStringToPrinter(string szPrinterName, string szString)
 {
  IntPtr pBytes;
  Int32 dwCount;
  szString = reemplazarCaracteres(szString);
  // How many characters are in the string?
  dwCount = szString.Length;
  // Assume that the printer is expecting ANSI text, and then convert
  // the string to ANSI text.
  pBytes = Marshal.StringToCoTaskMemAnsi(szString);
  // Send the converted ANSI string to the printer.
  SendBytesToPrinter(szPrinterName, pBytes, dwCount);
  Marshal.FreeCoTaskMem(pBytes);
  return true;
 }

 private string reemplazarCaracteres(string PrintCommand)
 {
  PrintCommand = PrintCommand.Replace("<STX>", ((char)02).ToString());
  PrintCommand = PrintCommand.Replace("<ETX>", ((char)03).ToString());
  PrintCommand = PrintCommand.Replace("<ESC>", ((char)27).ToString());
  return PrintCommand;
 }
}

'@


Add-Type -TypeDefinition $src -Language CSharpVersion3


$PrinterHelper = new-object RawPrinterHelper



 
Su uso es simple, por ejemplo desde otro archivo ps1 hacemos

. .\PrinterHelper.ps1

$PrinterHelper.SendStringToPrinter('\\PROG03\sato cg408', '<STX><ESC>A1002400880<ESC>A<ESC>H0030<ESC>V0030<ESC>BT101030100<ESC>BW03100*555*<ESC>H0030<ESC>V0133<ESC>WB0555<ESC>Q1<ESC>Z<ETX>') 


Con lo que estaríamos imprimiendo una etiqueta con el valor 555 en code39, imprimiendo el número 555 debajo.
Esta misma clase se puede usar para imprimir desde .Net (con c#)

jueves, 19 de julio de 2012

Cómo convertir una solución o proyecto de C# a VB.NET automáticamente

Muchas páginas permiten pasar pedazos de código de VB.Net a C# y viceversa, pero cuando uno tiene un proyecto o solución grande, utilizar éstas páginas para convertir de lenguaje suele ser tedioso y lento. Por eso para pasar una solución completa tuve que ponerme a buscar una mejor opción....
Luego de buscar bastante por internet encontré una mejor forma de hacerlo.
Para poder hacerlo hay que bajar un interesante programa de internet que se llama SharpDevelop (al momento de escribir este artículo en su version 4.2).

SharpDevelop es un interesane IDE de desarrollo en tecnología .NET el cual es gratuito y open-source, dispone de varios lenguajes para desarrollar (C#, VB.NET, C++, F#, Python, Ruby y algunas cosas más)... Es verdaderamente muy liviano y anda muy rápido, aunque lo utilicé poco le encontre un solo defecto importante: no permite, al estar haciendo debug modificar el código y seguir debuguiando (a no ser que reinicie el debug), esto se debe a que (según leí en sus foros) el compilador .NET de Microsoft no tiene abierta la posibilidad de hacer esto (se me ocurre que así Microsoft se asegura que nadie pueda hacer un IDE mejor, o que le pueda competir al Visual Studio)...

Bueno, el tema es que este IDE, entre otras funcionalidades tiene la de convertir Proyectos enteros de un lenguaje a otro de los que tiene para desarrollar. :-)

Por ejemplo para pasar de C# a .NET mi proyecto hago lo siguiente, abro mi solución con SharpDevelop y en la solapa projects selecciono el proyecto a convertir y con botón derecho->Convert->From C# to VB.NET lo convierto y me deja una copia convertida del proyecto con el mismo nombre pero agregando .Converted... GENIAL!!!

Deja algún que otro pequeño error o advertencia, pero no muchas y fáciles de solucionar. Lo único que tardé un poco en darme cuenta fue que deja los Resources en
Global.<nombre proyecto>.Properties.Resources.<recurso>

cuando debería dejarlos en
Global.<nombre proyecto>.Resources.<recurso>

O sea sin el properties... 
También que a algunos controles se "olvida" de ponerles el WithEvents cuando tienen eventos...
En algunas páginas deja los "Option Strict On" "Option Explicit On" sin estar exactamente al principio, lo cual genera algunos errores.
... Fuera de eso y alguna que otra advertencia ¡Compilo y anda!

miércoles, 11 de julio de 2012

Obtener la posicion de un control respecto al parentform

Bueno, aquí un breve código que utilicé para obtener la posición de un control WinForm con respecto a su ParentForm, es útil si se quieren poner controles dinámicamente dentro de un formulario y cambiar su posición (por ejemplo posicionándolo al lado de otro control)... con c# .Net



using System.Drawing;
using System.Windows.Forms;

...

public   class UserControlGeneral : UserControl
    {
        /// <summary>
        /// Busca el Point donde está ubicado el control respecto del ParentForm
        /// </summary>
        /// <returns>Point</returns>
        protected Point buscarLocationRespectoParentForm()
        {
            return buscarLocationRespectoParentForm(this);
        }

        /// <summary>
        /// Busca el Point donde está ubicado el control que recibe de parámetro respecto del ParentForm
        /// </summary>
        /// <param name="control">Control al que se le quiere encontrar la posición</param>
        /// <returns>Point</returns>
        protected Point buscarLocationRespectoParentForm(Control control)
        {
            if (control.Parent == this.ParentForm)
            {
                return new Point(control.Location.X, control.Location.Y);
            }
            else
            {
                Point p = buscarLocationRespectoParentForm(control.Parent);
                p.X += control.Location.X;
                p.Y += control.Location.Y;
                return p;
            }
        }
    }





domingo, 24 de junio de 2012

Cómo ver si un programa está instalado en nuesta PC

Utilizando el registro de windows se pueden ver todos los programas instalados en nuestra máquina (o cualquier texto que esté en la registry de windows). El código que sigue a continuación se desarrolló para buscar una serie de programas instalados en un cliente.

El llamado al método de búsqueda es algo del estilo:
reg.buscarEnLaRegistry(Registry.LocalMachine.OpenSubKey(@"SOFTWARE"), busqueda);

Siendo busqueda:
private List<RegistroWindows.itemBuscar> busqueda;

Y siendo reg
RegistroWindows reg = new RegistroWindows();

Como notarán uso Registry.LocalMachine.OpenSubKey(@"SOFTWARE") solo buscando en el nodo SOFTWARE de la registry ya que allí se encuentra el soft instalado.


using System;
using System.Collections.Generic;
using Microsoft.Win32;

namespace ProgramasInstalados.Clases
{
    /// <summary>
    /// Clase para trabajar con el registro de windows
    /// </summary>
    public class RegistroWindows
    {
        /// <summary>
        /// Item a buscar
        /// </summary>
        public class itemBuscar
        {
            /// <summary>
            /// Nombre del item o texto a buscar
            /// </summary>
            public string Nombre { get; set; }
            public bool Encontrado { get; set; }
            public string Paths { get; set; }
            public itemBuscar(string nombre)
            {
                Nombre = nombre;
                Encontrado = false;
                Paths = "";
            }
        }


        /// <summary>
        /// Busca un texto en la registry
        /// </summary>
        /// <param name="registryKey">Clave del registro donde se realiza la busqueda (y en sus nodos hijo)</param>
        /// <param name="buscar">Lista de items a buscar del tipo itemBuscar</param>
        public void buscarEnLaRegistry(RegistryKey registryKey, List<itemBuscar> buscar)
        {
            foreach (string keyName in registryKey.GetSubKeyNames())// me fijo si esta en alguna clave de este nivel
            {
                if (!ignorar(keyName))// solo veo las claves que no estan en la lista de ignorar
                {
                    try
                    {
                        using (RegistryKey rk = registryKey.OpenSubKey(keyName))
                        {
                            foreach (string valueName in rk.GetValueNames())
                            {
                                foreach (itemBuscar item in buscar)
                                {
                                    string path = "";
                                    if ((path = rk.GetValue(valueName).ToString()).ToLower().EndsWith(item.Nombre.ToLower()))// me fijo si tiene el .exe que estoy buscando
                                    {// si no esta NO lo seteo en false porque podria haberlo encontrado antes
                                        item.Encontrado = true;
                                        if (!item.Paths.Contains(path))// me fijo que ya no este cargado
                                        {
                                            item.Paths += path;
                                        }
                                    }
                                }
                            }
                            buscarEnLaRegistry(rk, buscar);// me fijo si esta en alguno de sus hijos
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }

        /// <summary>
        /// Verifica si keyName esta en la lista de ignorar (en los settings, sitting Excluir separado por comas)
        /// </summary>
        /// <param name="keyName">el string a buscar para ver si se debe ignorar</param>
        /// <returns>true si se debe ignorar, sino false</returns>
        private bool ignorar(string keyName)
        {
            foreach (string ignorar in ProgramasInstalados.Properties.Settings.Default.Excluir.Split(','))
            {
             // En settings guardo en un string separado por comas los nodos en los que no quiero
             // que se busque dentro de la registry; ya que por ejemplo el nodo Microsoft tiene
             // todos los programas que instalo Microsoft, tambien se puede evitar el nodo Windows
             // ya que tiene los programas propios de windows, entre otros. Esto hace que sea mas
             // rapida la busqueda dentro de la registry, ya que recorrerla completa si no es
             // necesario insumiria bastante tiempo.
                if (ignorar == keyName)
                {
                    return true;
                }
            }
            return false;
        }
    }
}

sábado, 23 de junio de 2012

Cómo ejecutar un programa con .NET C#

Con una simple instrucción se puede ejecutar un programa que esté instalado en nuestra pd desde .NET... con C# son un par de líneas:

try
{
 Process.Start(item.Paths);
}
catch (Exception exception)
{
 MessageBox.Show("Se ha producido un error al intentar abrir el programa." + Environment.NewLine + "Mensaje de error: " + exception.Message;);
}
 
Para que esto funcione hay que usar también: using System.Diagnostics;

viernes, 22 de junio de 2012

Cómo sacar un ícono de un .exe o .dll en .NET con C#

Aquí una pequeña función que sirve para sacar el ícono de un archivo (.exe, .dll) en windows en c#.



using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ProgramasInstalados.Clases
{
    /// <summary>
    /// Clase para extraer iconos de ficheros de recursos.
    /// </summary>
    class Iconos
    {

 ...

 ...

 ...

  
     /// <summary>
     /// Devuelve el icono del programa
     /// </summary>
     /// <param name="path">
     /// La ruta del programa al que se le quiere sacar el ícono 
     /// ej: "c:/prog.exe" </param>
     /// <returns>
     /// Un objeto Icon con el icono o null
     /// </returns>
     public static Icon IconDelPrograma(string path)
     {
          Icon icono = null;
          try
          {
              icono = Icon.ExtractAssociatedIcon(path);
          }
          catch
          { //capturo la excepcion
          }
       return icono;
     }

  

 .........


    }
}