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

27/11/17

Scrapping con C#. Listas de Contratación Temporal de la Xunta.

url es la variable con la url a scrapear //valga el palabro

"//td[@align='left']" es una expresión xpath que devolvería los TD con alineación izquierda

Para hacer el scrapping con cSharp usamos ScrapySharp

Hay ejemplo completo en GitHub aquí

Código:

ScrapingBrowser Browser = new ScrapingBrowser();
Browser.UserAgent = new FakeUserAgent("primero", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");
Browser.AllowAutoRedirect = true; // Browser has settings you can access in setup
Browser.AllowMetaRedirect = true;
WebPage PageResult = await Browser.NavigateToPageAsync(new Uri(url));
IEnumerable TDs = PageResult.Html.SelectNodes("//td[@align='left']");
this.lNombre.Clear();
foreach (HtmlNode item in TDs) {
    this.lContenidosTDs.Add(item.InnerText);
}

20/11/17

Test. Clase de ayuda para envío de pulsaciones de teclas.

SSk: Static Send Keys.

Es un envoltorio para facilitar el uso de la función "SendKeys.SendWait(string keys)" y algunas utilidades más como introducir un tiempo de espera entre pulsación y pulsación. También permite generar apropósito tiempo de espera (Tread.Sleep(miliseconds)) y facilita el envío de algunas teclas especiales.

Se encuentra en github como parte del proyecto Utils pero es, de momento, muy independiente y no necesita nada del resto del proyecto.

https://github.com/IvanCruzFraguela/UtilNs/blob/master/Test/SSk.cs

15/5/17

Otro de envío de teclas.

Ejecuta un chrome y le envía las teclas para probar la página

Parece funcionar. Habría luego que comprobar que la página ha hecho lo que se le ha pedido



Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe";
p.StartInfo.Arguments = @"file:///C:/Users/usuario/Desktop/borrame.html";//html que se quiere probar
p.Start();
p.WaitForInputIdle();
Thread.Sleep(1000);
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("hola a todos");
SendKeys.SendWait("{Tab}");
SendKeys.SendWait("{Enter}");
Thread.Sleep(1000);
p.CloseMainWindow();

Lectura de datos de usuario de directorio activo a un fichero.

Está también en github aquí
using System;

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.IO;

namespace udaExe {
    class Program {
        static void Main(string[] args) {
            string ldapEntry;
            string fileName;
            int cantUsuarios = 0;
            if (!GetParameters(args, out ldapEntry, out fileName)) {
                Console.Out.WriteLine("uso: udaExe ldap fichero");
                Console.Out.WriteLine("Ejemplo: udaExe \"LDAP://OU=Users,dc=microsoft,dc=local\" \"c:\\usuarios.txt\"");

            } else {
                Console.Out.WriteLine("Buscando usuarios:");

                using (StreamWriter sw = File.CreateText(fileName)) {
                    try {
                        DirectoryEntry directoryObject = new DirectoryEntry(ldapEntry);
                        foreach (DirectoryEntry child in directoryObject.Children) {
                            string displayName = GetProperty(child, "displayName");
                            string distinguishedName = GetProperty(child, "distinguishedName");
                            string samAccountName = GetProperty(child, "samAccountName");
                            child.Close();
                            child.Dispose();
                            sw.WriteLine($"{displayName}#{samAccountName}#{distinguishedName}");
                            cantUsuarios++;
                        }
                        directoryObject.Close();
                        directoryObject.Dispose();
                    } catch (DirectoryServicesCOMException ex) {
                        Console.Error.WriteLine("Error: " + ex.Message.ToString());
                    }
                }
                Console.Out.WriteLine(cantUsuarios.ToString() + " usuarios encontrados, fichero generado: " + fileName);
            }
        }

        public static string GetProperty(DirectoryEntry de, string PropertyName) {
            if (de.Properties.Contains(PropertyName)) {
                return de.Properties[PropertyName][0].ToString();
            } else {
                return string.Empty;
            }
        }

        public static bool GetParameters(string[] args, out string ldap, out string fileName) {
            ldap = String.Empty;
            fileName = @"c:\users.txt";
            if (args.Length < 1) {
                return false;
            }
            ldap = args[0];
            if (args.Length >= 2) {
                fileName = args[1];
            }
            return true;
        }
    }
}

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);
}

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

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());

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();

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:

12/9/11

Compilando desde bajada de svn

svn co svn://desarrollo.dxx.xudicial.xunta.es/repositorio/csharp/InventarioDHCP_1.10
svn co svn://desarrollo.dxx.xudicial.xunta.es/repositorio/csharp/Util

cd InventarioDHCP_1.10
c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild /p:Configuration=Release
Baja el código a donde se encuentre el fichero .bat y lo compila.

24/5/11

Envío de teclas a aplicaciones (para pruebas automáticas)

Uno de los problemas se produce cuando se muestra un MessageBox. No hay manera de cerrarlo así que: a enviar teclas.

// Código para enviar las pulsaciones de teclas
Microsoft.VisualBasic.Interaction.AppActivate(f.Text);//Activa la aplicación. f es el formulario creado anteriormente para pruebas
f.Focus();// Hace falta también esto por lo visto.
Util.EnviarTeclas(5000, "{TAB}");//Cuadro de diálogo. Pasar a "no"
Util.EnviarTeclas(6000, "{ENTER}");//Cuadro de diálogo. ENTER.

// Código en Utils
    public static void EnviarTeclas(int TiempoEspera, string teclas) {
      Thread t = new Thread(new ParameterizedThreadStart(AEjecutarPorEnvioTeclas));
      EnvioTeclas et = new EnvioTeclas(TiempoEspera,teclas);
      t.Start(et);

    }
    public static void AEjecutarPorEnvioTeclas(Object EnvTecl) {
      EnvioTeclas aux = EnvTecl as EnvioTeclas;
      Thread.Sleep(aux.espera);
      SendKeys.SendWait(aux.teclas);
    }
  public class EnvioTeclas {
    public int espera;
    public string teclas;
    public EnvioTeclas(int espera, string teclas) {
      this.espera = espera;
      this.teclas = teclas;
    }
  }

27/4/11

Comparar el contenido de dos filas

public static bool ContenidoRowsEsIgual<T>(T row1, T row2) where T : DataRow {
bool result = true;
if (!row1.GetType().Equals(row2.GetType())) {
throw new Exception("Las filas no son del mismo tipo");
}
DataRow r1 = row1 as DataRow;
DataRow r2 = row2 as DataRow;
for (int i = 0; i < r1.ItemArray.Length; i++) {
if (!r1[i].Equals(r2[i])) {
result = false;
}
}
return result;
}