Dónde guardar los archivos de configuración en ClickOnce
ctg | 02 Noviembre, 2011 23:53
En ocasiones, las aplicaciones necesitan generar fichero de log o utlizar archivos de configuración, o simplemente necesitan acceder a bases de datos. En definitiva, necesitan acceder a cualquier recurso disponible y para ello deben tener algún tipo de información acerca del recurso en cuestión.
Como en una aplicación ClickOnce, cada versión es instalada en una carpeta aparte, no existe una forma automática de guardar y acceder a este tipo de recursos sin perder la información en cada actualización.
Por ello, si no se quiere perder el contenido de los ficheros, no queda más remedio que guardarlos fuera de la instalación de ClickOnce.
Si se esta utilizando Windows Vista o Windows 7, existen algunos lugares donde es posible guardar este tipo de ficheros. Por ejemplo, se pueden colocar en la carpeta Mis Documentos. Pero hay que tener cuidado, pues el usuario puede acceder a la infomación, consultarla o incluso borrar ficheros.
Otra solución, más recomendada, es crear una carpeta dentro de Local Application Data dónde guardar todos los datos que la aplicación necesite.
Únicamente es necesario comprobar si existe o no la carpeta dónde se guardan los datos necesarios. Si la carpeta no existe (porque es la primera vez que se ejecuta el programa), será necesario crear la carpeta y guardar los archivos de configuración con unos valores por defecto.
Ejemplo:
string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string userFilePath = Path.Combine(localAppData, "MyCompany");
if (!Directory.Exists(userFilePath))
{
Directory.CreateDirectory(userFilePath);
// Create here your default config,log files
}
// Read config files
El único problema al utilizar este modo es en el momento en que el usuario desinstala la aplicación, quedándose todos los archivos en la carpeta Local Application Data sin desisntalar.
Publicado en C# . Comentario: (1). Retroenlaces:(0). Enlace
What's new in C# 4
ctg | 04 Mayo, 2010 13:15
2 years ago, Stuart Celarier made a set of short webcast about new languages features in C# 2.0 in .NET 2.0.
.NET Framework 4 was released on 12th April and new version with C# 4.0 was included on it.
A new 'What's new ...' webcast had been done to introducing new C# 4.0 features and describes them.
You can find all webcast (including old ones) on Channel 9
Publicado en C#, .NET . Comentario: (0). Retroenlaces:(0). Enlace
VS & VB Spanish Tour 2008
ctg | 18 Noviembre, 2008 13:39
Ayer asistí al VS & VB Spanish Tour 2008, donde pude conocer personalmente a Lisa Feigenbaum, Jonathan Aneja y Pep Lluis Blano.
Las dos conferencias estuvieron muy bien. Jonathan Aneja muestra unos ejemplos muy claros e instructivos sobre las novedades de Visual Basic 9 (y por ello también aplicables a C# 3.0). Y mucho más espectacular fue la charla de Lisa, donde mostro lo fácil que es hacer refactoring, trabajar con snippets, corrección de errores y varias técnicas para ser mucho más productivo a la hora de realizar nuestro trabajo.
Recomiendo todas las personas que puedan asistir a las charlas que lo hagan, pues durante esta semana estan realizando un tour por varias provincias españolas.
Many thanks to Jonathan and Lisa for your time after conference. I hope you enjoyed this short stay in Tarragona... and Happy Birthday Lisa !!!!
Publicado en C#, .NET . Comentario: (0). Retroenlaces:(0). Enlace
Crear archivo Excel desde C#
ctg | 08 Septiembre, 2008 22:33
Aunque Microsoft Excel es capaz de interpretar ficheros separados por comas (*.csv), también es posible generar un fichero Excel (*.xls) desde C# utilizando Interop. De este modo, se podrán utilizar funciones como autosuma o simplemente cambiar ciertos aspectos de una determinada celda.
El único problema, es que es necesario que el ordenador tenga instalado Microsoft Office (XP, 2003 ó 2007) asegurándose que la opción ".NET Programmability support" esté seleccionada. Si se ha seleccionado instalación Completa (en Microsoft Office), no hace falta preocuparse por nada por se tuvo que instalar.
Aunque no lo he probado, pero puede ser que una versión reducida de Office (instalación mínima) junto con Redistributable Primary Interop Assemblies sea posible crear XLS desde código .NET.
En este enlace, (http://msdn.microsoft.com/en-us/library/aa159923.aspx) informa de varias formas de instalar y usar Office 2003 para usar Interop.
Para crear un fichero XLS, desde un proyecto Windows de C#, añadir una referencia a Microsoft xx.0 Object Library que la encontrarás en la pestaña COM. Si utilizas Microsoft Office XP ó 2003, la versión será la 11.0. En cambio, con Office 2007, la versión es la 12.0. Es puede ser una fuente de problemas y por ello es importante prestar atención a la versión porque ciertos tipos no son compatibles unos con otros.
Dentro del espacio de nombres Microsoft.Office.Interop.Excel se encuentra todo lo necesario para poder crear el fichero Excel. Dejo aquí un pequeño ejemplo de una simple clase para ayudarme a crear ficheros XLS, para poder "acordarme" en un futuro...
using System;
using Microsoft.Office.Interop;
using System.Reflection;
using MyExcel = Microsoft.Office.Interop.Excel;
// Use this class to create a Microsoft Excel (*.xls) file
// Please, read this notes
// Microsoft Office XP, 2003 or 2007 must be installed on target computer to create *.xls file.
// VERY IMPORTANT: Office Primary Interop Assemblies (PIA) must be selected on Microsoft Office installation. Use "Complete installation" in Office setup
// http://msdn.microsoft.com/en-us/library/kh3965hw(VS.80).aspx
//
// Add Microsoft Excel Library xx.0 (Microsoft.Office.Interop.Excel.dll) reference on COM tab
// Also VERY IMPORTANT
// Double check Microsoft Excel Library version. 11.0 = Office 2003, 12.0 = Office 2007. Certain types are NOT compatibles!!!
public class ExcelFile : IDisposable
{
MyExcel.Application theExcel = null;
MyExcel.Workbook theWorkbook = null;
string theExcelFileName;
public ExcelFile(string fileName)
{
theExcel = new MyExcel.Application();
theWorkbook = theExcel.Workbooks.Add(System.Reflection.Missing.Value);
theExcelFileName = fileName;
}
~ExcelFile()
{
Dispose(false);
}
public void AddSheet(string sheetName)
{
var newSheet = (MyExcel.Worksheet)theWorkbook.Sheets.Add(Missing.Value, Missing.Value, 1, MyExcel.XlSheetType.xlWorksheet);
newSheet.Name = sheetName;
}
public void SetCell(int row, int column, string text)
{
SetCell(null, row, column, text);
}
public void SetCell(string sheetName, int row, int column, string text)
{
MyExcel.Worksheet theSheet = (null == sheetName ? (MyExcel.Worksheet) theWorkbook.ActiveSheet : (MyExcel.Worksheet)theWorkbook.Sheets[sheetName]);
theSheet.Cells[row, column] = text;
}
public void Close()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if(disposing)
{
theWorkbook.SaveAs(theExcelFileName, MyExcel.XlFileFormat.xlExcel7, Missing.Value, Missing.Value, Missing.Value, Missing.Value, MyExcel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, null);
theWorkbook.Close(false, Missing.Value, Missing.Value);
theExcel.Quit();
}
}
void IDisposable.Dispose()
{
Dispose(true);
}
}
Publicado en C# . Comentario: (5). Retroenlaces:(0). Enlace
Make a beep using internal PC speaker using C#
ctg | 17 Julio, 2008 23:56
Some computers doesn't enable sound card or simply, doesn't have it.
If you want make a beep to force to user to pay attention you can also use P/Invoke to call Beep funciton on Kernel32.dll.
It takes two arguments, the first one the frequency, and the second one the duration and returns a bool for success.
Frequency must be from 37 to 32,767.
using System.Runtime.InteropServices;
public class Foo
{
[DllImport("Kernel32.dll")]
public static extern bool Beep(UInt32 frequency, UInt32 duration);
public static void beepTime()
{
Beep(1000, 300);
System.Threading.Thread.Sleep(300);
Beep(2000, 400);
System.Threading.Thread.Sleep(300);
Beep(500, 200);
System.Threading.Thread.Sleep(300);
}
}
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Get more 100 matched results using Paypal TransactionSearch
ctg | 07 Julio, 2008 14:11
One of the main problems using TransactionSearch on Paypal API is only returns last 100 records. In this case, TransactionSearch returns a SuccessWithWarning ack to indicate this problem.
To fix it, I made a code to get the status of one day transactions doing a "hack" to avoid 100 records problem.
// Sets user, password and signature
UserIdPasswordType user = new UserIdPasswordType();
user.Username = this.user;
user.Password = this.password;
user.Signature = this.signature;
// Define TransactionSearchResponseType. Inside loop we add params to adjust search
TransactionSearchResponseType transactionSearchResponseType = null;
// Paypal only can get 100 results at time.
do
{
// Prepare the interface with user
using (PayPalAPISoapBinding paypalInterfaceSearch = new PayPalAPISoapBinding())
{
paypalInterfaceSearch.RequesterCredentials = new CustomSecurityHeaderType();
paypalInterfaceSearch.Url = "https://api-3t.paypal.com/2.0/";
paypalInterfaceSearch.RequesterCredentials.Credentials = user;
// Prepare TransactionSearch request
TransactionSearchRequestType transactionSearchRequestType = new TransactionSearchRequestType();
transactionSearchRequestType.Version = "3.2";
transactionSearchRequestType.TransactionClass = PaymentTransactionClassCodeType.All;
transactionSearchRequestType.TransactionClassSpecified = true;
// Adjust the dates according is in loop or not
if (null != transactionSearchResponseType)
{
// StartDate always is 0:00:00 hours
transactionSearchRequestType.StartDate = new DateTime(
transactionSearchResponseType.PaymentTransactions[99].Timestamp.Year,
transactionSearchResponseType.PaymentTransactions[99].Timestamp.Month,
transactionSearchResponseType.PaymentTransactions[99].Timestamp.Day,
0, 0, 0);
// EndDate is last PaymentTransactions less 1 second. This way we obtain left results
transactionSearchRequestType.EndDate = transactionSearchResponseType.PaymentTransactions[99].Timestamp;
transactionSearchRequestType.EndDate.AddSeconds(-1);
}
else
{
transactionSearchRequestType.StartDate = startDate;
transactionSearchRequestType.EndDate = endDate;
if (startDate == endDate)
{
transactionSearchRequestType.EndDate = transactionSearchRequestType.EndDate.AddDays(1);
}
}
transactionSearchRequestType.EndDateSpecified = true;
TransactionSearchReq transactionSearchRequest = new TransactionSearchReq();
transactionSearchRequest.TransactionSearchRequest = transactionSearchRequestType;
// Get results and Ack
transactionSearchResponseType = paypalInterfaceSearch.TransactionSearch(transactionSearchRequest);
// Check Ack, if OK, get results
if (AckCodeType.Success == transactionSearchResponseType.Ack || AckCodeType.SuccessWithWarning == transactionSearchResponseType.Ack)
{
if (null != transactionSearchResponseType.PaymentTransactions)
{
foreach (PaymentTransactionSearchResultType paymentTransactionSearchResultType in transactionSearchResponseType.PaymentTransactions)
{
// PaymentTransaction only include PayPal TransactionID. To get JShop order number it's necessary get more details using TransactionID
// Its necessary prepare again the interface if not fails.
using(PayPalAPISoapBinding paypalInterfaceDetails = new PayPalAPISoapBinding())
{
paypalInterfaceDetails.RequesterCredentials = new CustomSecurityHeaderType();
paypalInterfaceDetails.Url = "https://api-3t.paypal.com/2.0/";
paypalInterfaceDetails.RequesterCredentials.Credentials = user;
// Prepare TransactionDetails
GetTransactionDetailsRequestType transactionDetailsRequesType = new GetTransactionDetailsRequestType();
transactionDetailsRequesType.Version = "3.2";
transactionDetailsRequesType.TransactionID = paymentTransactionSearchResultType.TransactionID; // Set TransactionID to search
GetTransactionDetailsReq transactionDetailsRequest = new GetTransactionDetailsReq();
transactionDetailsRequest.GetTransactionDetailsRequest = transactionDetailsRequesType;
// Get results
GetTransactionDetailsResponseType transactionDetailsResponseType = paypalInterfaceDetails.GetTransactionDetails(transactionDetailsRequest);
if (AckCodeType.Success == transactionDetailsResponseType.Ack)
{
if (null != transactionDetailsResponseType)
{
// Check paymentTransactionSearchResultType to see the transaction status
}
}
else
{
// Log message here. TransactionDetailsResponseType not successful searching TransactionID
}
}
}
}
else
{
// Log message here. TransactionSearchResponseType not sucessful
}
}
}
} while (transactionSearchResponseType.Ack == AckCodeType.SuccessWithWarning);
Publicado en C#, Paypal . Comentario: (0). Retroenlaces:(0). Enlace
Whirlwind
ctg | 18 Marzo, 2008 11:37
Whirlwind are a few videos, created by Stuart Celarier,
about new features about C# 2.0 and 3.0. These videos are usually
shorts and there are focus in one or two topics. As Stuart explains, a
lot of new features are not C# related but are new .NET Framework.
You can find videos at: http://channel9.msdn.com/Showpost.aspx?postid=390556
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Comprobar la conectividad de un equipo
ctg | 27 Febrero, 2008 00:15
Hace ya tiempo, e incluso, en mi anterior trabajo, uno de los problemas principales era la conectividad del equipo a la red local y por ello, no era posible acceder a internet.
Nunca supimos porque y tampoco perdimos tiempo en averiguarlo. Lo único que haciamos era reintentar de nuevo pasado un cierto tiempo.
Hoy, me he encontrado con un problema parecido y he decidido investigar un poco y he encontrado unos post de Jose Manuel Alarcón que me han sido muy útiles. Como siempre, los dejo aquí por si alguna vez necesito consultarlos de nuevo.
Detectar si hay conectividad en el equipo (Metodo 1)
Detectar si hay conectividad en el equipo (Metodo 2)
Detectar si hay conectividad en el equipo (Metodo 3)
Detectar si hay conectividad en el equipo (Metodo 4 y 5)
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Emtpy recyble bin in C#
ctg | 13 Noviembre, 2007 00:41
On 2006, I wrote a post to send a file to Recycle Bin. But, at the same, I need a code to empty recycle bin. Here is the code:
using System.Runtime.InteropServices;
enum RecycleFlags : uint
{
SHERB_NOCONFIRMATION = 0x00000001,
SHERB_NOPROGRESSUI = 0x00000002,
SHERB_NOSOUND = 0x00000004
}
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
static extern uint SHEmptyRecycleBin
(IntPtr hwnd,
string pszRootPath,
RecycleFlags dwFlags);
public static void Main()
{
uint result = SHEmptyRecycleBin (IntPtr.Zero, null, 0);
Console.WriteLine ("Result: {0}", result);
}
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Frequently asked questions in C#
ctg | 23 Octubre, 2007 00:01
A good friend, sent me this link, Frequently asked questions in C#. Is a list with few frequently asked questions. For me, exist a couple tips so interesting like how calculate a MD5 and play default songs, useful when you code show a error message or important info.
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Revista MYGNET
ctg | 18 Octubre, 2007 00:31
MYGNET es una revista con una cantidad de artículos interesantes. He descargado unos cuantas revistas y de momento me ha sorprendido gratamente.
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Lo nuevo en C#
ctg | 03 Julio, 2007 23:36
La nueva versión de C#, la 3.0, esta a punto de salir al mercado de forma oficial. En este artículo se encuentran de forma resumida, C# Especificación de la versión 3.0
Lamentablemente, no dice ni una sola palabra de LINQ, que a mi mode de ver, será la "estrella"
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Expresiones regulares con C#
ctg | 12 Junio, 2007 23:29
Aunque siempre se ha dicho que cuando quieres resolver un problema con expresiones regulares, no tienes un problema, sino dos, pongo aquí un enlace al siguiente artículo Introducción a las expresiones regulares.
Aunque
ya he hablado varias veces en sobre las expresiones regulares (sobre
todo con PHP), este artículo tiene la particularidad de utilizar el
objecto Regex de la plataforma .NET.
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Send a file to the recycle bin in C#
ctg | 26 Mayo, 2006 00:02
using System;
using System.IO;
using System.Runtime.InteropServices;
/// <summary>
/// Class to delete a file and move it to Recycle bin
/// </summary>
class RecycleBin
{
private const int FO_DELETE = 3;
private const int FOF_ALLOWUNDO = 0x40;
private const int FOF_NOCONFIRMATION = 0x0010;
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto, Pack=1)]
public struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
[MarshalAs(UnmanagedType.U4)] public int wFunc;
public string pFrom;
public string pTo;
public short fFlags;
[MarshalAs(UnmanagedType.Bool)] public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);
/// <summary>
/// Delete a file and move it to Recycle bin
/// </summary>
/// <param name="fileName">File to delete</param>
public static void Send(string fileName)
{
if (File.Exists(fileName) )
{
SHFILEOPSTRUCT shf = new SHFILEOPSTRUCT();
shf.hwnd = IntPtr.Zero;
shf.wFunc = (int) FO_DELETE;
shf.pTo = null;
shf.pFrom = fileName + "\0\0";
shf.fFlags = (ushort) FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
shf.fAnyOperationsAborted = false;
shf.hNameMappings = IntPtr.Zero;
SHFileOperation(ref shf);
}
}
}
Publicado en C# . Comentario: (0). Retroenlaces:(0). Enlace
Use foreach in hashtable
ctg | 16 Mayo, 2006 00:00
Two ways for use a “foreach” in a Hashtable
foreach (string key in hash.Keys) Response.Write(key + '=' + hash[key] + "<br>");
Or
foreach (DictionaryEntry myDE in hash) Response.Write(myDE.Key + "=" + myDE.Value + "<br>");