Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, June 7, 2015

Use Java library in C# - IKVM.NET

[1] IKVM.NET
[2] http://en.wikipedia.org/wiki/IKVM.NET

From [2]:

IKVM.NET is an implementation of Java for Mono and the Microsoft .NET Framework. IKVM is free software, distributed under a permissive free software licence.[1]

IKVM.NET includes the following components:

    A Java Virtual Machine implemented in .NET
    A .NET implementation of the Java class libraries
    A tool that translates Java bytecode (JAR files) to .NET IL (DLLs or EXE files).
    Tools that enable Java and .NET interoperability

With IKVM.NET you can run compiled Java code (bytecode) directly on Microsoft .NET or Mono. The bytecode is converted on the fly to CIL and executed.


Therefore if you want to use a java Jar library as C# assembly, you can use IKVM for the conversion.

This is great.

Tuesday, July 9, 2013

Visual C# 2008/2012. By John Sharp

p.151. Nullable type.
   int i = null; // wrong
   int? i = null; // right

p.152. ref, out (must assign value in method).
   Need to declare variable as ref/out at both calling site and function definition.

p.176. Class & Struct
                                                                          struct                    class
type                                                                    value                    reference
live on                                                                 stack                   heap
can declare default ctor?                                      no                       yes
after declare ctor, default ctor auto-created?        yes                      no
automatic initialize fields?                                     no                       yes
can initialize instance fields at declaration?            no                       yes

- Collection:
   - Hashtable
   - SortedList - sorted hash table (RB tree?)

p.207. Parameter Arrays. - variable param list.
    - void func(params int[] a) {...}

p.217. CH 12. Inheritance
   - new, virtual, override, hiding/overriding, protected.
   - extension methods?
   - public, protected, private, internal, protected internal 
   - internal: Internal types or members are accessible only within files in the same assembly,
   - protected v.s. protected internal:
      - protected; derived types may access the member.
      - protected internal; only derived types or types within the same assembly can access that member,
        so they need to be in the same Dynamic Link Library or an executable file.

p.239. Interface, Abstract class, Sealed class.
   - interface => virtual => override => sealed

p.274. Property, get/set

p.295. CH 16. Indexer?

p.311. delegate, event

p.333. CH 18. Generics.
    Queue myQ = new Queue();

p.371. LINQ. Language Integrated Query
   - LINQ, DLINQ, XLINQ.
     - Linq is a programming model that introduces queries as a first-class concept into any Microsoft .NET language
     - DLinq (Linq to SQL) is an extension to Linq that allows querying a database and do object-relational mapping.
     - XLinq (Linq to XML) is an extension to Linq that allows querying/creating/transforming XML documents.
   - After ASP.NET 4.0, emphasis is on Entity Framework, which replaces LINQ.

   - Linq v.s. Entity Framework. (some explanation)
     - LINQ to SQL only supports 1 to 1 mapping of database tables, views, sprocs and functions available in Microsoft SQL Server. It's a great API to use for quick data access construction to relatively well designed SQL Server databases. LINQ2SQL was first released with C# 3.0 and .Net Framework 3.5.
    - LINQ to Entities (ADO.Net Entity Framework) is an ORM (Object Relational Mapper) API which allows for a broad definition of object domain models and their relationships to many different ADO.Net data providers. As such, you can mix and match a number of different database vendors, application servers or protocols to design an aggregated mash-up of objects which are constructed from a variety of tables, sources, services, etc. ADO.Net Framework was released with the .Net Framework 3.5 SP1.

p.420. XAML. Extensible Application Markup Language.
    - WPF - XAML - define interface by XML(XAML), independent from application logic.

p.523. DLINQ. Based on ADO.NET. Data LINQ.

p.557. PART VI. Build web app.
   - ASP.NET server control
   - HTML control (runat="server")
   - theme
   - web forms validation controls.

p.623. Web service
   - REST: request by specifically formatted URL
   - SOAP: request by XML message.

Friday, November 30, 2012

Monitor process memory and CPU usage in C#

There are relevant libraries to monitor process memory and CPU usage.

[1] Process Class
[2] How to get CPU usage of processes and threads
[3] Pushing the Limits of Windows: Physical Memory

It's a little confusing with multiple functions on memory usage, but WorkingSet64() is one that can be used.

Multi-threading with C#

Ok, I worked on multi-threaded applications in C# in the past. Now I'm back to do something again.

Some notes:

1. Below 2 are the same for C# 2.0 and after, ThreadStart can be omitted (but can be useful say when you want to start a group of functions):

    1) Thread newThread = new Thread(new ThreadStart(this.checkProcesses)); 
    2) Thread newThread = new Thread(this.checkProcesses); 

2. The new thread by default is not a background process, which means when the GUI exits, it continues to run in the background. If you set it as a background process, then GUI exit will cause it to exit as well (usually this is desired):

    newThread.IsBackground = true; // usually desired.

3. Access of GUI control needs special handling using Invoke() method:

    delegate void SetTextCallback(string a, string b);
    private void setMsg(string a, string b) {
        if (this.textBox1.InvokeRequired) {
            SetTextCallback d = new SetTextCallback(setMsg);
            this.Invoke(d, new object[] { s, b });
        }
        else { this.textBox1.Text = a + b; }
    }

Then call the setMsg method in the thread method: this.setMsg("hello, ", "world");

Ways of using multi-threading:

    // Method 1. basic method.
    Thread newThread = new Thread(this.checkProcesses); 
    newThread.IsBackground = true; 
    newThread.Start();

    // Method 2. use BackgroundWorker. 

References:

[1] Multi-process: http://msdn.microsoft.com/en-us/library/6x4c42hc.aspx
[2] Multiple process, access form control: http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx
[3] Background worker: http://stackoverflow.com/questions/363377/c-sharp-how-do-i-run-a-simple-bit-of-code-in-a-new-thread

Friday, October 5, 2012

"using" keyword in C#, and large file processing

1. Using

The "using" keywork in C# is used to either import a library, or to cause a local variable to be disposed immediately after use.

To design a class that can be used in the using(...) clause, the class needs to implemented the IDisposable interface. This mostly means to implement the Dispose() and Dispose(boolean) methods, and deallocate local resources in the Dispose(boolean) method. See http://msdn.microsoft.com/en-us/library/system.idisposable.aspx.

2. Processing large data file

Processing of large data file may run out of memory if everything is done inside memory, for example, XmlSerializer may do this. The solution is to do the processing chunk by chunk (e.g., line by line, or block by block if no line separator).

For example, processing a file of 13GB will exhaust almost 16GB memory, causes the machine to hang for 30 minutes and fail. Using line by line processing, it takes 15 minutes and works successfully. Of course, for line by line processing, output can use buffering to avoid too many IO which also can be slow.

Another example is when reading a large file, in C/C++, read by line is much faster than read by char. But, for a binary file, you will not be able to read by line.

So processing large file requires careful handling of memory and IO.

Also, when a file is large, for example the 13GB file which does not contain any new line character (so read by line does not work), it can't be open by any common editor on windows including notepad, wordpad or VS.NET studio; it also can't be open on linux by vi. Well, when use vi to open it, it waits and seems there is never an end to the waiting. Search google shows that vi will have difficulty opening file with more than 9070000 character or file of size 2GB. Also for openning large file under 2GB, it will be faster for vi by disabling swap file, syntax parsing or undo history, see How to open big size file using vi editor or Faster loading of large files.

Use Perl to open the file also waits for ever. Actually using Perl it should also work if read as byte stream. Using C or Java to read as byte stream it works immediately.

Below is Java code to read as a byte stream:

import java.lang.*;
import java.io.*;

public class readByteFile {
  public static void main(String[] args) {
    InputStream is = null;
    ByteArrayOutputStream os = null;

    try  {
      File f = new File("filename");
      byte[] b = new byte[100];      // byte buffer.
      is = new FileInputStream(f);
      os = new ByteArrayOutputStream();

      int read = 0;
      int len = 0;
      while ( (read = is.read(b)) != -1 ) {
        os.write(b, 0, read);
        System.out.print(new String(b));
        len += read;
        if (len > 1000) break;
      }

      System.out.println(new String(b));
    } catch (Exception e) {

    } finally {
      try { if (os != null) os.close(); } catch (IOException e) {}
      try { if (is != null) is.close(); } catch (IOException e) {}
    }
  }
}
Or read in C using fgetc():
#include 

int main() {
  FILE * f = fopen("filename", "r");
  char ch;
  long ct = 0;      // char count.
  long line_ct = 0; // line count.

  if (f != NULL) {
    while (1) {
      ch = fgetc(f);
      ct ++;
      if (ch == '\r' || ch == '\n') line_ct ++;

      if (ch == EOF) break;

      putchar(ch);

      if (ct > 1000) break;
      if (line_ct > 5) break;
    }
  }
  printf("\n");
  fclose(f);
  return 0;
}

Monday, April 25, 2011

C# Mapping a network drive

C# can map a network drive by calling OS commands [1] or using native win32 API [2].

The code below is from [1]:

System.Diagnostics.Process.Start("net.exe", "use K: \\Server\URI\\path\\here");
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();
psi.FileName = "C:\\application.exe";
psi.WorkingDirectory = "K:\\working\\directory";
psi.WindowStyle = System.Diagnostics.
ProcessWindowStyle.Maximized;
System.Diagnostics.Process p =
System.Diagnostics.Process.Start(psi);

[1] http://forum.codecall.net/c-programming/1119-c-mapping-network-drive.html
[2] http://bytes.com/topic/c-sharp/answers/812115-mapping-network-drive-c

Thursday, February 17, 2011

C# script to strip comment

This code extracts comment from a line of string. Feeding a stream of lines to it, it concatenates the comment and non-comment parts and return them. Comment is defined by "/**/" or "//" as in C/C++.

/// <summary>
/// Input: line.
/// Output:
/// rStr - The non-comment part is concatenated to rStr.
/// rCmt - The comment part is concatenated to rCmt.
/// </summary>
private void stripComment(string line, ref string rStr, ref string rCmt)
{
bool debug = false;
bool comment_block = false, comment_line = false;
int index, index2;
string NEWLINE = "\r\n";
string s = "";
string cmt = "";

if (line.Trim() == "") return; // ignore empty line.

string subline = line;
while (subline.Length > 0)
{
// if not in both comments mode:
// if find /*, start comment_block from the point on.
// elsif find --, start comment_line from here to end of line.
// Since both "/*" and "--" may exist on this line, find the one occur first.
if (comment_block == false)
{
index = subline.IndexOf("/*");
index2 = subline.IndexOf("--");
if (index != -1 && index2 != -1)
{
if (index < index2) { comment_block = true; }
else { comment_line = true; }
}
else if (index != -1) { comment_block = true; }
else if (index2 != -1) { comment_line = true; }

if (comment_block)
{
// comment_block start found.
// print the substring before "/*".
if (debug) Console.WriteLine(subline.Substring(0, index));
s += subline.Substring(0, index);
// strip the first part.
subline = subline.Substring(index);
continue;
}
else if (comment_line)
{
// comment_line found.
cmt += subline.Substring(index2) + NEWLINE; // comment part.
// print the substring before "--".
subline = subline.Substring(0, index2);
if (subline.Trim() != "")
{
if (debug) Console.WriteLine(subline);
s += subline + NEWLINE;
}
comment_line = false;
break;
}
else
{
// is a normal line.
if (subline.Length > 0)
{
if (debug) Console.WriteLine(subline);
s += subline + NEWLINE;
break;
}
}

}
else
{
// $comment_block == 1. In comment_block,
// search for */, if found, ends comment_block.
// Note that in comment_block mode, "--" has no effect.
index = subline.IndexOf("*/");
if (index != -1)
{
cmt += subline.Substring(0, index + 2); // comment part.
comment_block = false;
if (debug) Console.WriteLine("comment_block end found.");
subline = subline.Substring(index + 2);
continue;
}
else
{
// entire line is in comment_block.
cmt += subline; // comment part.
if (subline != line)
{
if (debug) Console.WriteLine(NEWLINE);
s += NEWLINE;
cmt += NEWLINE; // comment part.
}
break;
}
}

}

rStr += s;
rCmt += cmt;
}

Monday, July 26, 2010

C# read Excel, get Access schema

///
/// Reference: How To Open and Read an Excel Spreadsheet into a ListView in .NET
///
public static void readExcel(string fullpath) {
Excel.Application excelObj = new Excel.Application();
if (excelObj == null) {
MessageBox.Show("Error: Excel cannot be started.");
return;
}

excelObj.Visible = false;

Excel.Workbook theWorkbook = excelObj.Workbooks.Open(fullpath, 0, true, 5, "", "",
true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, false, false, false);
// get the collection of sheets in the workbook
Excel.Sheets sheets = theWorkbook.Worksheets;
// get the first and only worksheet from the collection of worksheets
Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);

// getExcelSize(worksheet); // get row/col: ws.Rows.Count, ws.Columns.Count

// loop through 10 rows of the spreadsheet and place each row in the list view
for (int i = 1; i <= 10; i++)
{
Excel.Range range = worksheet.get_Range("A"+i.ToString(), "FB" + i.ToString());
System.Array myvalues = (System.Array)range.Cells.Value2;
string str = ConvertArrayToString(myvalues);
MessageBox.Show(str);
}
}


///
/// Reference: How to read an Excel file with OleDb and a simple SQL query?
/// To use this, the Excel version should be 8.0 or compatible.
///
/// The link http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=107963&SiteID=1
/// says that to use this method, it takes a little setup in your Excel document.
/// Basically, you need to define "named objects" in Excel that are synonymous to
/// tables in a database. The first row of the named object are the column headers.
/// To set up a named object, first select the range of cells (your "table," with
/// the first row being the column headers), then go to menu Insert->Names->Define.
/// Name your object and press "Add." Now you have an object which can be read by
/// ADO.NET.
///
public static void readExcel2(string fullpath) {
String sConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + fullpath + ";" + "Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"";
MessageBox.Show(sConnectionString);

try
{
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();

string sheetName = filename.Substring(0, filename.IndexOf(".xls"));
MessageBox.Show("sheetName: " + sheetName);

//OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM [Sheet1$]", objConn);
OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM [" + sheetName + "$]", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
DataSet objDataset1 = new DataSet();
objAdapter1.Fill(objDataset1);

string str = objAdapter1.ToString();
MessageBox.Show(str);

objConn.Close();
}
catch (Exception e) {
MessageBox.Show("error: " + e.Message);
}
}

///
/// Get Access Schema.
///
public void getSchema(string path)
{
int i, j;
string result = "";
DataTable userTables = null;
DataTable userTable = null;
System.Windows.Forms.TreeNode node = null;
System.Windows.Forms.TreeNode[] nc;

try
{
OleDbConnection conn = new OleDbConnection();
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path;
conn.Open();

userTables = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
new object[] {null, null, null, "TABLE"});

this.treeViewDBSchema.Nodes.Clear();
// Add list of table names to listBox
for (i=0; i < userTables.Rows.Count; i++)
{
result += userTables.Rows[i][2].ToString() + " { ";
userTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,
new object[] {null, null, userTables.Rows[i][2].ToString(), null});

nc = new TreeNode[userTable.Rows.Count];
for (j = 0; j < userTable.Rows.Count - 1; j ++)
{
result += userTable.Rows[j][3].ToString() + ", "; // [2].ToString();
nc[j] = new TreeNode("Field: " + userTable.Rows[j][3].ToString());
nc[j].Tag = userTable.Rows[j][3].ToString();
}
// for the last item.
result += userTable.Rows[j][3].ToString(); // [2].ToString();
nc[j] = new TreeNode("Field: " + userTable.Rows[j][3].ToString());
nc[j].Tag = userTable.Rows[j][3].ToString();

result += " }\n";
node = new TreeNode("Table: " + userTables.Rows[i][2].ToString(), nc);
node.Tag = userTables.Rows[i][2].ToString();
this.treeViewDBSchema.Nodes.Add(node);
}
conn.Close();
//MessageBox.Show(this, result);
this.frmMain.setOutput(result);
}
catch (Exception ex)
{
MessageBox.Show(this, "Error: " + ex.Message);
}
}

C# work with local IP address

/// 
/// Ref: How To Get IP Address Of A Machine
/// Ref: WMI or How to change my IP address
/// using System.Management;
///

public string getLocalIP()
{
string localIP = "";
string strHostName = Dns.GetHostName();

IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
IPAddress [] addr = ipEntry.AddressList;

/* what if more than one instance exists? */
for (int i = 0; i < addr.Length; i++)
{
localIP = addr[i].ToString();
}

return localIP;
}


public bool setLocalIP(string newIP) {
try
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (!(bool) mo["IPEnabled"]) continue;
inPar = mo.GetMethodParameters("EnableStatic");
inPar["IPAddress"] = new string[] {newIP};
inPar["SubnetMask"] = new string[] {subnetMask};
outPar = mo.InvokeMethod("EnableStatic", inPar, null);
break;
}

this.currentIP = newIP;
return true;
}
catch (Exception e)
{
this.setErrMsg(e.Message + "\nsource: " + e.Source);
return false;
}
}


static void SwitchToDHCP()
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo["IPEnabled"] )
continue;

inPar = mo.GetMethodParameters("EnableDHCP");
outPar = mo.InvokeMethod( "EnableDHCP", inPar, null );
break;
}
}


static void SwitchToStatic()
{
string newIP;
string subnetMask = "255.255.255.0";
newIP = (curIP.Equals("192.168.168.209"))?"192.168.168.204":"192.168.168.209";

ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo[ "IPEnabled" ] )
continue;

inPar = mo.GetMethodParameters( "EnableStatic" );
inPar["IPAddress"] = new string[] { newIP };
inPar["SubnetMask"] = new string[] { subnetMask };
outPar = mo.InvokeMethod( "EnableStatic", inPar, null );
break;
}
}


static void ReportIP()
{
Console.WriteLine( "****** Current IP addresses:" );
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo[ "IPEnabled" ] )
continue;

Console.WriteLine( "{0}\n SVC: '{1}' MAC: [{2}]", (string) mo["Caption"],
(string) mo["ServiceName"], (string) mo["MACAddress"] );

string[] addresses = (string[]) mo[ "IPAddress" ];
string[] subnets = (string[]) mo[ "IPSubnet" ];

Console.WriteLine( " Addresses :" );
foreach(string sad in addresses)
Console.WriteLine( "\t'{0}'", sad );

Console.WriteLine( " Subnets :" );
foreach(string sub in subnets )
Console.WriteLine( "\t'{0}'", sub );

curIP = addresses[0];
}
}

C# GET/POST request, login, download, axWebBrowser

///
/// Example of HTTP Get request.
///
private string requestURL(string url, int timeout)
{
HttpWebRequest wr;
HttpWebResponse resp = null;
Stream stream;
StreamReader reader;
string strResponse = "";

try {
wr = (HttpWebRequest) WebRequest.Create(url);
wr.Timeout = timeout; // in milliseconds.
resp = (HttpWebResponse) wr.GetResponse();
stream = resp.GetResponseStream();
reader = new StreamReader(stream);
try { strResponse = reader.ReadToEnd(); }
finally { reader.Close(); }
resp = null;
}
catch (Exception ex) {
this.output_response("::" + ex.Message);
}
finally {
if (resp != null) resp.Close();
}
return strResponse;
}


///
/// Example of HTTP Post request.
/// Call the following function: e.g.
/// string html = HttpPost("http://abcde.com", "a=1&b=2");
///
private string HttpPost(string URI, string Parameters)
{
WebRequest req = WebRequest.Create(URI);
//req.Proxy = new System.Net.WebProxy(ProxyString, true);

req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";

byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
req.ContentLength = bytes.Length;

Stream os = req.GetRequestStream ();
os.Write (bytes, 0, bytes.Length);
os.Close ();

WebResponse resp = req.GetResponse();
if (resp== null) return null;

StreamReader sr = new StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}


///
/// Example of using HTTP Post to log into a site.
///
private void login() {
HTMLDocument myDoc = new HTMLDocumentClass();
myDoc = (HTMLDocument) axWebBrowser1.Document;

try
{
HTMLInputElement oUser = null, oPass = null;

oUser = (HTMLInputElement) myDoc.all.item("username", 0);
oPass = (HTMLInputElement) myDoc.all.item("password", 0);

if (oUser == null || oPass == null) return;

oUser.value = "username_value";
oPass.value = "password_value";

HTMLFormElement frm = (HTMLFormElement) myDoc.all.item("login", 0);
frm.submit();

this.Task = 1;
}
catch (Exception ex)
{
this.showInfo("test() error: " + ex.Message);
}
}


///
/// Example of using HTTP Post to download an Excel file.
///
private void getExcel() {
HttpWebResponse resp = null;
Stream stream;
string filename = this.downloadFolder + "/download.xls";

try
{
wr = (HttpWebRequest) WebRequest.Create(this.excel_url);
wr.Method = "POST";
wr.ContentType = "application/x-www-form-urlencoded";
wr.ContentLength = byteArray.Length;
wr.Timeout = 100000; // in ms. Set this bigger than the site timeout value.
MyUtil.appendLog("wr.contentlength: " + wr.ContentLength);

wr.CookieContainer = new CookieContainer();
wr.CookieContainer.SetCookies(new Uri(this.excel_url) ,
((mshtml.HTMLDocumentClass) this.axWebBrowser1.Document).cookie.ToString());
MyUtil.appendLog("cookie: " +
((mshtml.HTMLDocumentClass) this.axWebBrowser1.Document).cookie);

// Send post request
Stream dataStream = wr.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
resp = (HttpWebResponse) wr.GetResponse();
resp.Cookies = wr.CookieContainer.GetCookies(resp.ResponseUri);
MyUtil.appendLog("resp status: " + resp.StatusDescription);

stream = resp.GetResponseStream();

//MyUtil.appendLog("resp header: " + resp.ContentType );
// Header: usually 'txt/html'. here is 'application/vnd.ms-excel'
StreamReader reader = new StreamReader(stream);
try
{
MyUtil.saveFile(filename, reader.ReadToEnd());
this.downloadSucceed = true;
}
catch (Exception ex)
{
MyUtil.FileDelete(filename);
this.downloadSucceed = false;
}
finally
{
reader.Close();
}
}
catch (Exception ex)
{
this.downloadSucceed = false;
MyUtil.FileDelete(filename);
}
finally
{
if (resp != null) { resp.Close(); }
}
}

///
/// Another way of navigating website: use the axWebBrowser control.
///
this.axWebBrowser1.Navigate(url);

[1] The user32 SendInput windows API. The SendInput function synthesizes
keystrokes, mouse motions, and button clicks to the currently active window.
[2] Capturing binary download via code through axwebbrowser1.

Friday, June 4, 2010

C#.Net recover password by email

In C#.Net 2005, the asp:PasswordRecovery control by default use User Name to recover password. But sometimes the user may forget user name, and User Email is used instead. For this we can do it this way (from here):

In aspx page:
<asp:PasswordRecovery Id="PasswordRecovery1" runat="server" OnVerifyingUser="PasswordRecovery1_VerifyingUser">
</asp:PasswordRecovery>

In Code behind:
protected void PasswordRecovery1_VerifyingUser(object sender, LoginCancelEventArgs e) {
   PasswordRecovery1.UserName = Membership.GetUserNameByEmail(PasswordRecovery1.Us erName);
}

Thursday, February 4, 2010

ASP.NET's Membership, Roles, and Profile

Pretty good introduction to ASP.NET's Membership, Roles, and Profile:
http://www.4guysfromrolla.com/articles/121405-1.aspx

Get UserId:
MembershipUser myObject = Membership.GetUser();
string UserID = myObject.ProviderUserKey.ToString();

Code to update membership property:
MembershipUser u = Membership.GetUser("member");
u.IsApproved = false;
Membership.UpdateUser(u);
Note that must use UpdateUser() method otherwise it won't update.

Friday, August 21, 2009

Manipulate PDF in .NET

To convert PDF into image, we have the GFL SDK/GFLAx library as discussed in an earlier post.

Now the problem is how to convert image into PDF, or how to draw onto PDF. One needs to rely on 3rd party module for this function.

PDFSharp (http://www.pdfsharp.net/) works well for this. It can create new PDF file, or draw text and image onto existing PDF files. It even can generate barcode image (but guess it can't do recognization). The current version is 1.3, providing both source and assembly download at sourceforge.net. The source code can be used in one's own application, unless is for commercial purpose and needs support. It is written from scratch in C#. The only limit is that it requires .NET version 2.0 or above. To use this in .NET 1.1 or from other framework such as J2EE/LAMP, I think one can do something like a web service call.

Some people say in web applications PDFSharp cannot run under medium security level. I didn't have this problem, probably because I'm running it on a trusted server, so there is no security restriction.

One last word: it seems that PDF is frequently used in business applications. Now we have these open source projects that allows PDF convertion to and from other formats. Good to have these.

Friday, July 24, 2009

C# DataGrid custom paging

In .NET 1.1 (I don't know the later version at this time), datagrid paging navigation is troublesome since it does not include link to the first and last page, and does not show the total number of pages. The pager row can contain no other information, which is also inconvenient when you want to put something there, e.g., a checkbox says "select all" for all checkboxes on the rows in the datagrid.

This is a way of imitating the paging manually, and allows the freedom of specifying "First, Prev, Next, Last" links, as well as total pages and other information on the pager row.

The "Prev, ..., 11, 12, ..., Next" part can be done with the following function. Then you can add "First" and "Last" as link buttons. You can then provide the page count as a Label. Alternatively, the following example also adds the page count as a simulation of the link button "Last".

In .aspx.cs page put:

/// <summary>
/// This function writes a customized navigation bar for datagrid.
///
/// Note that lblNext and lblPrev can be replaced with image icons.
///
/// Example of Calling this function:
/// writeDataGridNavBar(
/// this.DataGrid1.PageCount,
/// this.DataGrid1.CurrentPageIndex,
/// this.DataGrid1.PagerStyle.PageButtonCount,
/// 1
/// );
///
/// The last parameter "1" here is obtained this way:
/// Check the aspx page with default paging, look at the links to "1, 2, ...",
/// javascript:__doPostBack('DataGrid1$_ctl1$_ctl4','')
/// ^
/// Pass this number as the last parameter.
///
/// The optional ctrl_LastPage in the code below is similarly obtained from the
/// "Last" link button.
///
/// </summary>
/// <param name="totalPage">DataGrid.PageCount</param>
/// <param name="currentPage">DataGrid.CurrentPageIndex</param>
/// <param name="pageButtonCount">DataGrid.PagerStyle.PageButtonCount</param>
/// <param name="ctl_val"></param>
/// <returns></returns>
///
/// @Author: HomeTom
/// @Date: 7/24/2009
///
public string writeDataGridNavBar(
int PageCount, int CurrentPageIndex, int PageButtonCount, int ctl_val)
{
string lblNext = "Next";
string lblPrev = "Prev";
string ctrl = "javascript:__doPostBack('DataGrid1$_ctl" + ctl_val + "$_ctl";
// Optional. Use this only when use the "Last" link button.
string ctrl_LastPage = "javascript:__doPostBack('btnLastPage','')";
string s = "";
int i, j, tmp;

int startPage =
((int) (Math.Floor((CurrentPageIndex * 1.0)/PageButtonCount)) * PageButtonCount);

tmp = PageCount - PageButtonCount;
if (tmp > 0 && tmp < startPage) { startPage = tmp; }

if (CurrentPageIndex == 0) { s += lblPrev + " "; }
else
{
j = CurrentPageIndex - startPage;
if (startPage == 0) j -= 1;
s += "<a href=\"" + ctrl + j + "', '')\">" + lblPrev + "</a> ";
}

if (startPage > 0) { s += "<a href=\"" + ctrl + "0','')\">...</a> "; }

for (i = 0; i < PageButtonCount && (i + startPage) < PageCount; i ++)
{
tmp = startPage + i + 1;
j = (startPage == 0) ? i : (i + 1);
if (tmp == CurrentPageIndex + 1) { s += tmp + " "; }
else { s += "<a href=\"" + ctrl + j + "','')\">" + tmp + "</a> "; }
}
if (startPage + PageButtonCount < PageCount - 1) {
j = (startPage == 0) ? PageButtonCount : (PageButtonCount + 1);
s += "<a href=\"" + ctrl + j + "','')\">...</a> ";
}
if (startPage + PageButtonCount < PageCount)
{
s += "<a href=\"" + ctrl_LastPage + "\">" + PageCount + "</a> ";
}

if (CurrentPageIndex >= PageCount - 1) { s += lblNext; }
else
{
j = CurrentPageIndex - startPage + 1;
if (startPage > 0) j += 1;
s += "<a href=\"" + ctrl + j + "','')\">" + lblNext + "</a>";
}

return s;
}

Note that if don't want to use the page count link at the end then replace the red region with the following code:

if (startPage + PageButtonCount < PageCount) {
j = (startPage == 0) ? PageButtonCount : (PageButtonCount + 1);
s += "<a href=\"" + ctrl + j + "','')\">...</a> ";
}

In .aspx page put:

<asp:linkbutton id="btnFirstPage" onclick="DataGrid1_CustomPaging_First" Runat="server">First</asp:linkbutton>
<asp:label id="lblPageNavBar" Runat="server"></asp:label>
<asp:linkbutton id="btnLastPage" onclick="DataGrid1_CustomPaging_Last" Runat="server">Last</asp:linkbutton>


Now set DataGrid1.PagerStyle.visible to False.
Leave DataGrid1.AllowPaging as True, and DataGrid1.AllowCustomPaging as False.

That's it! You are simulating datagrid's default paging with the freedom of customizing the style!

--Appendix on 8/20/2009

Now it's clear that this does not work in later versions of .NET. First the links' format is not DataGrid1$_ctl1$_ctl4, but like DataGrid1$ctl01$ctl04. More importantly, if set the visible property of the link buttons and datagrid pager to false, then __doPostBack won't work for these controls, as they are cleaned from the output. Therefore the above scheme works only for .NET 1.1 :(

In later versions of .NET there is a pager template that can be used to format paging. Hope that's flexible enough.

Another thought is that, the use of datagrid and dataview in later versions of .NET, are mostly for the ease of paging and sorting. Think carefully, I don't see anything else that datagrid and dataview can do special. If these can be handled from scratch, then there is no need to use these cumbersome controls. Actually I would prefer such a build-from-scratch approach, it avoids the burden of version incompatibility and allows the largest flexibility. Once the template is done, it can be used all the time without any more learning curve.

Types of parameters in C#

There are 4 types of parameter passing in C#:
1) Value: pass by value.
2) Out: like pointer in C/C++, allow return value. Don't have to be initialized first.
3) Ref: like reference in C++, allow return value. Must be initialized first.
4) Params: for variable length parameter list.

More detailed explanation and examples:
http://www.csharphelp.com/archives/archive225.html

Wednesday, July 1, 2009

Use ADODB.RecordSet in C#

Usually one can use System.Data.SqlClient to deal with operations on MSSQL server. The corresponding objects are SqlConnection, SqlCommand, SqlDataReader etc.

There is one scenario like this: the user needs to read something from each row in a table, and use the obtained information to update that row. One needs to cycle through all the records, and then use "UPDATE" query for the purpose. If SqlDataReader is used, the efficiency will be slow. SqlDataReader is read only, and uses the current connection exclusively as well. The user needs to open a second connection, and use the second connection to do the update based on a key.

In ADODB.RecordSet, one can use RecordSet.Update() function to directly update the current row and write back to database. No second connection is needed, and no key-based query is needed. This is much more efficient. A similar mechanism in SqlClient may exist, but I don't know yet at this time.

The following is an example using ADODB.RecordSet in C#. Note one needs to add ADODB to the references list of the current C# project first.

Parameters used by RecordSet can be found at http://www.w3schools.com/ADO/met_rs_open.asp.
private void updateTbl_ADODB() {
    ADODB.Connection conn = new ADODB.ConnectionClass();
    ADODB.Recordset rs = new ADODB.RecordsetClass();

    try {
        string strConn = 
            "Provider=SQLOLEDB;Initial Catalog=[database];Data Source=[server];";
        conn.Open(strConn, [user], [pwd], 0);

        string sql = "SELECT * FROM tbl";
        rs.Open(sql, conn, ADODB.CursorTypeEnum.adOpenForwardOnly, 
                ADODB.LockTypeEnum.adLockOptimistic, -1);

        while (rs.EOF == false)  {
            rs.Update("field_name", [new_value]);
            rs.MoveNext();
        }

    } catch (Exception e) {
        MessageBox.Show(this, "Error" + e.Message);
    } finally {
        conn.Close();
    }
}

Wednesday, October 1, 2008

C# convert PDF to image format

The solution generally is provided by 3rd party component. In many cases it is not free. E.g., PDFRasterizer.NET component, PDF4NET etc.

Here's one solution: http://www.mobileread.com/forums/showthread.php?t=10137

The GFL SDK/GFLAx (http://www.xnview.com/en/gfl.html) free library component can be used to convert PDF to image format. It works for ASP, VB, C# etc. GhostScript (http://sourceforge.net/projects/ghostscript/) is required for it to work.

Example code in C#:

{
string file = "D:/test.pdf";
string image = "D:\\test.png";

try
{
GflAx.GflAxClass g = new GflAx.GflAxClass();
g.EpsDpi = 150;
g.Page = 1;
g.LoadBitmap(file);
g.SaveFormat = GflAx.AX_SaveFormats.AX_PNG;
g.SaveBitmap(image);
MessageBox.Show(this, "PDF to PNG conversion ended");
}
catch (Exception ex) {
MessageBox.Show(this, "GflAx error: " + ex.Message);
}
}

Thursday, July 3, 2008

C# simulate mouse and keyboard events

This is achieved by calling windows API functions.
Also see
reference.
using System.Runtime.InteropServices;

public class Form1 : System.Windows.Forms.Form {
public enum VK : ushort
{
SHIFT = 0x10,
CONTROL = 0x11,
MENU = 0x12,
ESCAPE = 0x1B,
BACK = 0x08,
TAB = 0x09,
RETURN = 0x0D,
PRIOR = 0x21,
NEXT = 0x22,
END = 0x23,
HOME = 0x24,
LEFT = 0x25,
UP = 0x26,
RIGHT = 0x27,
DOWN = 0x28,
SELECT = 0x29,
PRINT = 0x2A,
EXECUTE = 0x2B,
SNAPSHOT = 0x2C,
INSERT = 0x2D,
DELETE = 0x2E,
HELP = 0x2F,
NUMPAD0 = 0x60,
NUMPAD1 = 0x61,
NUMPAD2 = 0x62,
NUMPAD3 = 0x63,
NUMPAD4 = 0x64,
NUMPAD5 = 0x65,
NUMPAD6 = 0x66,
NUMPAD7 = 0x67,
NUMPAD8 = 0x68,
NUMPAD9 = 0x69,
MULTIPLY = 0x6A,
ADD = 0x6B,
SEPARATOR = 0x6C,
SUBTRACT = 0x6D,
DECIMAL = 0x6E,
DIVIDE = 0x6F,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7A,
F12 = 0x7B,
OEM_1 = 0xBA, // ',:' for US
OEM_PLUS = 0xBB, // '+' any country
OEM_COMMA = 0xBC, // ',' any country
OEM_MINUS = 0xBD, // '-' any country
OEM_PERIOD = 0xBE, // '.' any country
OEM_2 = 0xBF, // '/?' for US
OEM_3 = 0xC0, // '`~' for US
MEDIA_NEXT_TRACK = 0xB0,
MEDIA_PREV_TRACK = 0xB1,
MEDIA_STOP = 0xB2,
MEDIA_PLAY_PAUSE = 0xB3,
LWIN =0x5B,
RWIN =0x5C
}

#region Dll Imports

[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public uint uMsg;
public ushort wParamL;
public ushort wParamH;
}

[StructLayout(LayoutKind.Explicit)]
struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}

[DllImport("user32.dll", SetLastError=true)]
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

const int INPUT_MOUSE = 0;
const int INPUT_KEYBOARD = 1;
const int INPUT_HARDWARE = 2;
const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
const uint KEYEVENTF_KEYUP = 0x0002;
const uint KEYEVENTF_UNICODE = 0x0004;
const uint KEYEVENTF_SCANCODE = 0x0008;
const uint XBUTTON1 = 0x0001;
const uint XBUTTON2 = 0x0002;
const uint MOUSEEVENTF_MOVE = 0x0001;
const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
const uint MOUSEEVENTF_LEFTUP = 0x0004;
const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
const uint MOUSEEVENTF_RIGHTUP = 0x0010;
const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
const uint MOUSEEVENTF_XDOWN = 0x0080;
const uint MOUSEEVENTF_XUP = 0x0100;
const uint MOUSEEVENTF_WHEEL = 0x0800;
const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
const uint MOUSEEVENTF_ABSOLUTE = 0x8000;


private MOUSEINPUT createMouseInput(int x, int y, uint data, uint t, uint flag) {
MOUSEINPUT mi = new MOUSEINPUT();
mi.dx = x;
mi.dy = y;
mi.mouseData = data;
mi.time = t;
//mi.dwFlags = MOUSEEVENTF_ABSOLUTE| MOUSEEVENTF_MOVE;
mi.dwFlags = flag;
return mi;
}

private KEYBDINPUT createKeybdInput(short wVK, uint flag)
{
KEYBDINPUT i = new KEYBDINPUT();
i.wVk = (ushort) wVK;
i.wScan = 0;
i.time = 0;
i.dwExtraInfo = IntPtr.Zero;
i.dwFlags = flag;
return i;
}

private short getCVal(char c) {
if (c >= 'a' && c <= 'z') return c - 'a' + 0x61;
else if (c >= '0' && c <= '9') return c - '0' + 0x30;
else if (c == '-') return 0x6D; // Note it's NOT 0x2D as in ASCII code!
else return 0; // default
}

///
/// Each time first move the upper left corner, then move from there.
/// x, y: pixel value of position.
///

private void sim_mov(int x, int y) {
INPUT[] inp = new INPUT[2];
inp[0].type = INPUT_MOUSE;
inp[0].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
inp[1].type = INPUT_MOUSE;
inp[1].mi = createMouseInput(x, y, 0, 0, MOUSEEVENTF_MOVE);
SendInput((uint)inp.Length, inp, Marshal.SizeOf(inp[0].GetType()));
}

private void sim_click()
{
INPUT[] inp = new INPUT[2];
inp[0].type = INPUT_MOUSE;
inp[0].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTDOWN);
inp[1].type = INPUT_MOUSE;
inp[1].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTUP);
SendInput((uint)inp.Length, inp, Marshal.SizeOf(inp[0].GetType()));
}

private void sim_type(string txt)
{
int i, len;
char[] c_array;
short c;
INPUT[] inp;

if (txt == null || txt.Length == 0) return;

c_array = txt.ToCharArray();
len = c_array.Length;
inp = new INPUT[2];

for (i = 0; i < len; i ++)
{
c = getCVal(txt[i]);

inp[0].type = INPUT_KEYBOARD;
inp[0].ki = createKeybdInput(c, 0);
inp[1].type = INPUT_KEYBOARD;
inp[1].ki = createKeybdInput(c, KEYEVENTF_KEYUP);

SendInput((uint)inp.Length, inp, Marshal.SizeOf(inp[0].GetType()));
}
}

private void sim_actions() {
sim_mov(x0, y0);
sim_click();
}

public Form1() {
InitializeComponent();
//sim_actions();
}

[STAThread]
static void Main() {
Application.Run(new Form1());
}
}

C# screen capture

This is achieved by calling windows API functions.
Also see Reference.

using System.Runtime.InteropServices;
using System.Drawing.Imaging;

public class Form1 : System.Windows.Forms.Form {
#region Dll Imports
[DllImport("user32.dll")]
private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
#endregion

private void screen_capture() {
try {
Bitmap bm = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(bm);
IntPtr hdc = g.GetHdc();
Form1.PrintWindow(this.Handle, hdc, 0);
//MessageBox.Show("color: " + bm.GetPixel(550, 300));
g.ReleaseHdc(hdc);
g.Flush();
g.Dispose();
//this.pictureBox1.Image = bm;
bm.Save("test.bmp");
} catch (Exception e) {
MessageBox.Show(this, "error: " + e.Message);
}
}

public Form1() { InitializeComponent(); /* screen_capture(); */ }

[STAThread]
static void Main() { Application.Run(new Form1()); }
}

Blog Archive

Followers