3/2/17

Ordenar tablas de una base de datos para que las referenciadas estén antes de las que referencian

public void OrdenaTablas() {
    List listaOrdenada = new List();
    while (this.lTable.Count > 0) {//mientras haya elementos
        ColocaTablaEnOrden(this.lTable, this.lTable[0], listaOrdenada);
    }
    foreach (var item in listaOrdenada) {
        lTable.Add(item);
    }
}
private void ColocaTablaEnOrden(List listaOriginal, CTableM cTableM, List listaOrdenada) {
    listaOriginal.Remove(cTableM);
    foreach (CRelationM relacion in cTableM.lRelation) {
        string NombreTablaConLaQueSeRelaciona = relacion.tableDestination;
        CTableM tablaRelacionada = listaOriginal.Find(x => x.Name.Equals(NombreTablaConLaQueSeRelaciona));
        if (tablaRelacionada != null) {//Si la tabla relacionada aún está en la lista de tablas a ordenar
            //Meter antes en la lista de ordenadas
            ColocaTablaEnOrden(listaOriginal, tablaRelacionada, listaOrdenada);
        }
    }
    listaOrdenada.Add(cTableM);
}

14/9/16

Crear servicio en Windows:

1 - Nuevo proyecto de tipo: Installed → Visual C# → Classic Desktop → Windows Service.
2 - Saca un editor en donde poner componentes pero lo más importante es poner la propiedad (F4) “ServiceName”. Esta propiedad será el nombre que tiene el servicio en Windows. No será el nombre del ejecutable.
3 - Añadir un “Instalador” se hace con “Add Instaler” en la parte baja de la pestaña de propiedades. No sé exáctamente para qué sirve, pero ahí podremos poner una descripción del servicio y algunas propiedades interesantes más, pero si no se añade esto, luego no se “Instala” el servicio.
4 - “Instalar el Servicio”. No se puede ejecutar directamente, hay que instalarlo y luego iniciarlo. Para instalarlo hay que ejecutar: InstallUtil con el nombre del fichero ejecutable.
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe .\PCSService.exe

5 - “Arrancar el Servicio”. Se hace con net start y el nombre del servicio que hemos puesto en el paso 2.
net start XviConSl

Nota final:
Si en las propiedades del Servicio hemos puesto "AutoLog" a true (que viene por defecto) podremos ver con el visor de eventos (ejecutar "eventvwr" en cmd) mensajes del servicio al instalarse, iniciar, parar tanto en la parte de "sistema" como en la de "aplicaciones".

 

24/8/16

Html y css. Esqueleto página centrada horizontalmente

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml">
 <head> 
  <style> 
   div.clBloqueEncabezado{ 
                  background-color: cyan; 
    text-align: center; 
   } 
   div.clEncabezado{
    display:inline-block;
    background-color:green; 
    padding:0.5em; 
   } 
   div.clCuerpo { 
    text-align: center; 
   } 
   div.clMenu { 
    display: inline-block; 
    background-color: lightblue; 
   } 
   div.clPanelPrincipal { 
    display: inline-block; 
    background-color: lightcoral; 
   } 
   div.clBloquePie { 
    background-color: aquamarine; 
    text-align: center; 
   } 
   div.clPie{ 
    display:inline-block; 
    background-color:green; 
    padding:0.5em; 
   } 
  </style> 
 </head> 
 <body> 
  <div class="clBloqueEncabezado"> 
   <div class="clEncabezado"> 
    Encabezado 
   </div>
  </div> 
  <div class="clCuerpo"> 
   <div class="clMenu"> 
    <h2>Menú</h2> 
    <ul> 
     <li>Uno</li> 
     <li>Dos</li> 
     <li>Tres</li> 
    </ul> 
   </div> 
   <div class="clPanelPrincipal">panelPrincipal</div> 
  </div> 
  <div class="clBloquePie">
   <div class="clPie">Pie</div> 
  </div> 
 </body> 
</html>

19/8/16

Buscar con grep

grep -l -r -i --include="*.cs" "tExto a buscar" .
(Ojo que hay un punto al final)
  • -l que muestre solo el nombre
  • -r que busque en los directorios recursivamente.
  • -i CaseInsensitive. Que no distinga mayúsculas de minúsculas.
  • --include="*.cs". Tipos de fichero a buscar.
  • El punto al final es "Donde" buscar. En este caso en el directorio actual.

    (Si no se pone da un error extraño)

    grep: (entrada estándar): Not enough space

Para windows se consigue aquí


29/6/16

Hola mundo con C# Interactive de Visual Studio 2015

> #r "System.Windows.Forms" //Cargar el ensamblado
> using System.Windows.Forms; //Usar el Namespace
> MessageBox.Show("Hola"); //Mostrar el mensaje

9/6/16

Incluir fichero css en código con JSF.

Definiendo en el código xhtml la etiqueta h con
xmlns:h="http://java.sun.com/jsf/html"

Escribimos:

<h:outputStylesheet library="css" name="Estilos.css"  />

En cualquier parte del código

Lo que genera incluye en la cabecera, y con la ruta adecuada, y ... con parámetros que no entiendo un enlace
<link type="text/css" rel="stylesheet"
href="/proyecto/javax.faces.resource/Estilos.css.xhtml?ln=css" />
Pero el caso es que funciona. Si se usa algún estilo en la página lo usa.
Ejemplo:
<p:panelGrid columns="2" columnClasses="alinearArriba">

20/4/16

Conectar Java con SqlServer.

  1. Abrir SqlServer para conexión por tcp/ip
  2. Para SqlServer 2008 sería:

    Ejecutar: Microsoft SQL Server 2008>Herramientas de configuración>Administración de Configuración de SQL Server

    Desplegar "Configuración de red de SQL Server", "Protocolos de " [Nombre instancia], y en TCP/IP dejar como habilitado

  3. Conseguir el jar adecuado.
  4. página de Microsoft sobre el tema

    Para la Java 1.7 corresponde el sqljdbc41.jar que habría que bajar de Internet

  5. La cadena de conexión
  6. Aquí está la madre del cordero.

    En mi caso "jdbc:sqlserver:" es siempre fijo.

    //nombre servidor:numero de puerto

    instanceName=nombre de instancia(si hay varias en el mismo equipo es fundamental ponerla)

    si se trabaja con autenticación de sqlServer (no Directorio Activo), user y password

    En resumen:

    "jdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS2008;databaseName=nombreBD;user=sa;password=secreta";

Con esto funciono.

Añado código de ejemplo:(Sacado de uno de los ejemplos de Microsoft que vienen junto al .jar para conectarse)


import java.sql.*;


public class CrudSqlServer1 {

 public static void main(String[] args) {
  // Create a variable for the connection string.
  String connectionUrl = "jdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS2008;databaseName=nombreBD;user=sa;password=secreta";

  // Declare the JDBC objects.
  Connection con = null;
  Statement stmt = null;
  ResultSet rs = null;
  
         try {
          // Establish the connection.
          Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
              con = DriverManager.getConnection(connectionUrl);
            
              // Create and execute an SQL statement that returns some data.
              String SQL = "SELECT * FROM Tabla1";
              stmt = con.createStatement();
              rs = stmt.executeQuery(SQL);
            
              // Iterate through the data in the result set and display it.
              while (rs.next()) {
               System.out.println(rs.getString(4) + " " + rs.getString(6));
              }
              System.out.println("FIN");
         }
        
  // Handle any errors that may have occurred.
  catch (Exception e) {
   e.printStackTrace();
  }

  finally {
   if (rs != null) try { rs.close(); } catch(Exception e) {}
       if (stmt != null) try { stmt.close(); } catch(Exception e) {}
       if (con != null) try { con.close(); } catch(Exception e) {}
  }

 }

}

19/3/16

Vim. Fijar los espacios de un tab. 8 es mucho.

Hay que poner las dos variables.
:set ts=4
:set sw=4
Siempre el mismo número. Es para el tab y el >>. que por lo visto, no son lo mismo.

Estructura base html a 19/03/2016

  1. Bajar jQuery
  2. 4 ficheros: Los "min" para producción (con el javascript comprimido) y los normales para depuración Para cada uno habría que considerar las versiones 1.X compatibles con Explorers 6,7 y 8 y los de la 2.X que no soportan esos navegadores Download jQuery
  3. Bajar bootstrap
  4. Baja todas las versiones (min y normal) Download Bootstrap
  5. Página vacía
  6. Copiado de: https://openwebinars.net/tutorial-bootstrap-3-introduccion-e-instalacion/ <!DOCTYPE html> <html lang="es"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!--Con esto garantizamos que se vea bien en dispositivos móviles--> <title>Pon un título</title> <link href="css/bootstrap.min.css" rel="stylesheet" media="screen"> <!--Llamamos al archivo CSS --> </head> <body> <script src="js/jquery.min.js"></script> <!-- Importante llamar antes a jQuery para que funcione bootstrap.min.js --> <script src="js/bootstrap.min.js"></script> <!-- Llamamos al JavaScript de Bootstrap --> </body> </html>

29/7/14

PsExec de PsTools

Psexec

PsExec.exe \\nombreEquipo -i -d -s "c:\windows\notepad.
exe"
-i para que salga en la pantalla (en alguna prueba con
    el notepad salio todo la ventana negra, problemas de repintado)
-d para que no se quede la línea de comandos pillada hasta que se 
    acabe el proceso. Lo lanza, devuelve el promp y un número de
    proceso que usamos para matarlo luego.
-s Usa la cuenta del sistema para lanzar la aplicación. Soluciona
    el problema de que no se vea la ventana
La aplicación saca algo como esto

c:\windows\notepad.exe started on nombreEquipo with process ID 7452.
Y lo matamos remotamente (el usuario podría cerrarlo) con:

C:\Users\icrufra\Desktop\PSTools>pskill.exe \\nombreEquipo 7452
Si se quiere entrar en la máquina remota con otro usuario se pondría –u (usuario@dominio) y el programa pide la clave.

15/7/14

Crear un acceso directo (Link) desde C#

(Con .net 4)
Type ShellType = Type.GetTypeFromProgID("WScript.Shell");
dynamic Shell = Activator.CreateInstance(ShellType);
dynamic shortcut = Shell.CreateShortcut(@"c:\borrame.lnk");
shortcut.TargetPath = @"c:\Windows\Notepad.exe";
shortcut.WorkingDirectory = @"c:\Windows";
shortcut.Save();
(Esto es antiguo con .net 4 usar el anterior)
Basado en:
http://www.codeproject.com/Articles/3905/Creating-Shell-Links-Shortcuts-in-NET-Programs-Usi
Por debajo usa Windows Scripting Host con lo que hay que importar un com (ocx) para que funcione. Es un poco chapuza pero es lo que hay.
En el proyecto se añade la referencia a ese com:
  1. En el proyecto,
  2. añadir referencia,
  3. de tipo com,
  4. el nombre es: “Windows Script Host Object Model”
Desde ese momento deja hacer un:
using IWshRuntimeLibrary;
El código que crea un link al notepad en el escritorio sería:

var shell = new WshShell();
IWshShortcut  link = (IWshShortcut)shell.CreateShortcut((Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"borrame.lnk")));
link.TargetPath = @"c:\windows\notepad.exe";
link.Save();

6/3/14

Obtener información de catálogo de Base de datos Access

DataTable t = Ctx.con.GetSchema(OleDbMetaDataCollectionNames.Columns);
StringBuilder sb = new StringBuilder();
foreach(DataRow r in t.Rows){
 foreach(DataColumn c in t.Columns){
  sb.Append(String.Format("{0}: {1}||",c.ColumnName,r[c.ColumnName]));
 }
 sb.AppendLine();
}
Clipboard.SetText(sb.ToString());
MessageBox.Show(sb.ToString());
DataRow []dr = t.Select("TABLE_NAME = 'AnoActual' and COLUMN_NAME = 'Ano'");
MessageBox.Show(dr[0]["TABLE_NAME"].ToString() + dr[0]["COLUMN_NAME"].ToString());

29/1/14

Salto de página en html

@media all {
   div.saltopagina{
      display: none;
   }
}
@media print{
   div.saltopagina{
      display:block;
      page-break-before:always;
   }
}
<div class="saltopagina"><div>

17/1/14

Compilar proyecto desde línea de comandos

msbuild UILog1.csproj /p:Configuration=Release /t:Clean
El msbuild está en:
C:\Windows\Microsoft.NET\Framework\v4.0.30319
Este ejemplo borraría la versión release. Sin el /t:Clean la crearía. También funciona con soluciones. Y es compatible con SharpDevelop.

14/1/14

Nlog a fichero por mes

Crearía un log a un fichero. Cada mes crea un fichero nuevo. El fichero está, en principio, en la misma carpeta que el ejecutable.
NLog.Targets.FileTarget ft = new NLog.Targets.FileTarget();
ft.FileName ="FicheroDeLog.txt";
ft.ArchiveEvery = FileArchivePeriod.Month;
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Trace);
LogManager.Configuration.AddTarget("File",ft);
Logger logger = LogManager.GetCurrentClassLogger();

9/7/13

Recabar información del equipo en windows

WMI: Windows Management Instrumentation http://msdn.microsoft.com/en-us/library/windows/desktop/aa394586(v=vs.85).aspx
static void MostrarTodo(StringBuilder sb, string cad){
 ObjectQuery query = new ObjectQuery("Select * from " + cad);
 XmlOpen(sb,1,cad);
 ManagementObjectSearcher mos = new ManagementObjectSearcher(query);
 if(mos!=null){
  ManagementObjectCollection moc = mos.Get();
  if(moc != null){
   foreach (ManagementObject mo in moc) {
    PropertyDataCollection pdc = mo.Properties;
    if(pdc != null){
     foreach (PropertyData pd in pdc) {
      AppendProperty(sb, pd);
     }
    }else{
     sb.AppendLine("");
    }
   }
  }else{
   sb.AppendLine("");
  }
 }else{
  sb.AppendLine("");
 }
 XmlClose(sb,1,cad);
}
Se le llamaría con:
MostrarTodo(sb, "Win32_Desktop");
MostrarTodo(sb, "Win32_DesktopMonitor");
MostrarTodo(sb, "Win32_OperatingSystem");
MostrarTodo(sb, "Win32_StartupCommand");

   
MostrarTodo(sb, "Win32_LogicalDisk");
MostrarTodo(sb, "Win32_MappedLogicalDisk");
MostrarTodo(sb, "Win32_DiskDrive");

MostrarTodo(sb, "Win32_NetworkAdapter");
MostrarTodo(sb, "Win32_NetworkAdapterConfiguration");

12/6/12

Generación de Codigo en C#

Nota: Está el código en hithub https://github.com/IvanCruzFraguela/EjemploGeneracionCodigo

usings necesarios:


using System.CodeDom;
using System.CodeDom.Compiler;
Suponemos que hay 2 controles de Tipo TextBox llamados:
tbFuenteGenerado
tbErrores
la función que genera los objectos necesarios para definir el código a generar como ejemplo es:
private CodeCompileUnit GeneraCodigo(){
 //Unidad de Compilación (ensamblado)
 var cu = new CodeCompileUnit();
 cu.ReferencedAssemblies.Add("System.dll");//Ensamblados que enlaza (aunque este debería estar por defecto)
 //Espacio de nombres
 var n = new CodeNamespace("EjemploGeneracionCodigo1");
 cu.Namespaces.Add(n);
 n.Imports.Add(new CodeNamespaceImport("System"));//Espacios de nombres que utiliza este namespace para compilar
 //Clase
 var c = new CodeTypeDeclaration("ClaseGenerada");
 n.Types.Add(c);
 c.BaseTypes.Add(new CodeTypeReference(typeof(System.Timers.Timer)));//Su clase padre
 c.IsPartial = true;
 
 //Atributo de la clase
 CodeMemberField mf = new CodeMemberField(typeof(string),"_atributo");
 c.Members.Add(mf);
 //Propiedad de la clase
 CodeMemberProperty cp = new CodeMemberProperty();
 c.Members.Add(cp);
 cp.Attributes = MemberAttributes.Public | MemberAttributes.Final;//lo de Final para que no sea virtual (por defecto si es público es virtual)
 cp.Type = new CodeTypeReference(typeof(string));
 cp.Name = "atributo";
 CodeFieldReferenceExpression cfre = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_atributo"); 
 CodeMethodReturnStatement mrs = new CodeMethodReturnStatement(cfre);
 cp.GetStatements.Add(mrs);
 //Metodo de la clase
 CodeMemberMethod cmm = new CodeMemberMethod();
 c.Members.Add(cmm);
 cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
 cmm.Name = "Metodo1";
 cmm.ReturnType = new CodeTypeReference(typeof(int));
 CodeParameterDeclarationExpression pde = new CodeParameterDeclarationExpression(typeof(int),"enteroDeEntrada");
 cmm.Parameters.Add(pde);
 pde = new CodeParameterDeclarationExpression(typeof(string),"cadenaDeEntrada");
 cmm.Parameters.Add(pde);
 //Declaración de variable
 CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(typeof(string),"aux",new CodePrimitiveExpression("Prueba1") );
 cmm.Statements.Add(vds);
 //Llamar a método arbitrario
  //variable a llamar y método
  CodeMethodReferenceExpression  ctr = new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("Console"),"WriteLine");
  //Llamada en sí con sus parámetros
  CodeMethodInvokeExpression invoke1 = new CodeMethodInvokeExpression( ctr, new CodeExpression[] {new CodePrimitiveExpression("Hola mundo")} );
 cmm.Statements.Add(invoke1);
  
 
 //Código a pelo. Ojo no se puede generar, por ejemplo, un foreach.
 cmm.Statements.Add(new CodeSnippetStatement("foreach(string s in cadenas){"));
 cmm.Statements.Add(new CodeSnippetStatement("Console.WriteLine(s);"));
 cmm.Statements.Add(new CodeSnippetStatement("}"));
 mrs = new CodeMethodReturnStatement(new CodePrimitiveExpression(42));
 cmm.Statements.Add(mrs);
                          
 return cu;
}
el código para generar el fuente e incluso compilarlo desde aquí es:
 CodeCompileUnit cu = GeneraCodigo();
 CodeDomProvider dp = CodeDomProvider.CreateProvider("CSharp");
 //Imprimir el código
 StringWriter sw = new StringWriter();
 System.CodeDom.Compiler.IndentedTextWriter itw = new IndentedTextWriter(sw);
 CodeGeneratorOptions go = new CodeGeneratorOptions();
 go.BlankLinesBetweenMembers = false;
 dp.GenerateCodeFromCompileUnit(cu,sw,go);
 this.tbFuenteGenerado.Text = sw.ToString();
 
 //Compilar desde dom
 CompilerParameters cp = new CompilerParameters(new string[]{},"borrame.dll");
 CompilerResults cr = dp.CompileAssemblyFromDom(cp,cu);
 tbErrores.Text = "";
 foreach(CompilerError ce in cr.Errors){
  tbErrores.Text += String.Format("{0}){1} in {2} at line {3} column {4} isWarning{5}",ce.ErrorNumber,ce.ErrorText,ce.FileName,ce.Line,ce.Column,ce.IsWarning);
 }

En teoría se podría generar tanto VB con C# pero supongo que con el uso se abusará de CodeSnippetStatement (“pon esto y no preguntes”) dado que hay construcciones importantes de C# (foreach, using) que no se pueden generar como tal con lo que solo se podrá generar C#.
Referencias: