2015年4月25日 星期六

[C#]取得螢幕畫面

C# 取得螢幕畫的方式很容易,直接來看程式碼吧


 using System;  
 using System.Collections.Generic;  
 using System.ComponentModel;  
 using System.Data;  
 using System.Drawing;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Windows.Forms;  
 namespace screenshoot  
 {  
   public partial class Form1 : Form  
   {  
     public Form1()  
     {  
       InitializeComponent();  
     }  
     private static Graphics gfxScreenshot;  
     private static Bitmap bmpScreenshot;  
     private void button1_Click(object sender, EventArgs e)  
     {  
       //最小化程式視窗  
       this.WindowState = FormWindowState.Minimized;  
       //停個一秒避免有最小化殘影  
       System.Threading.Thread.Sleep(1000);  
       //建立一個新的Bitmap  
       bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);  
       //從Bitmap建立一個Graphics  
       gfxScreenshot = Graphics.FromImage(bmpScreenshot);  
       //把螢幕畫面內容複製到Graphics(Screen.PrimaryScreen表示只複製主螢幕)  
       gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);  
       //把畫面儲存  
       bmpScreenshot.Save(string.Format(@"d:\temp\{0}.jpg", DateTime.Now.Ticks.ToString()), System.Drawing.Imaging.ImageFormat.Png);  
       //把程式重新顯示在螢幕上  
       this.WindowState = FormWindowState.Normal;  
     }  
   }  
 }  


執行畫面























只要點下儲存螢幕畫面的Button時,程式自動會縮到最小,等截完畫面後,


再回復,之後圖檔就存到D:\temp資料夾中,上述範例只有截取主要螢幕。


參考資料
http://www.dotblogs.com.tw/puma/archive/2008/08/21/4967.aspx

2015年4月24日 星期五

[Java] 透過SSH連線到Linux

Java要透過SSH連到Linux主機,可以用JSch這個現成的Library,

簡化開發流程,以下是官網對JSch的簡述。

JSch is a pure Java implementation of SSH2.
JSch allows you to connect to an sshd server and use port forwarding,
 X11 forwarding, file transfer, etc.

北七的理解是:

JSch是一個用Java來實作 SSH Protocol  ,支援你連線到sshd 服務,並且使用port forwarding ,

X11 forwarding 等功能。

資料來源
http://www.jcraft.com/jsch/


以下是一個連接SSH並且輸入指令的範例
 
package ssh;


import java.io.ByteArrayInputStream;
import java.io.InputStream;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

/** Demonstrates a connection to a remote host via SSH. **/
public class SSH
{
  // 使用者的帳號
  private static final String user = "Jhon";
   //主機的IP
  private static final String host = "192.168.0.203";
  //使用者的密碼
  private static final String password = "abcd123456";
  //要輸入的指令
  private static final String command = "ls -l\n";
  
  public static void main(String args[]) throws JSchException, InterruptedException
  {
      //初始代JSch
    JSch jsch = new JSch();
   
   //建立一個Session代入username , host , ssh port
    Session session = jsch.getSession(user, host, 22);

    //設定密碼
    session.setPassword(password);

    //SSH客户端的配置文件中有一个选项StrictHostKeyChecking,
    //默认是“ask”,可以把它改为“no”,
    //这样主机密钥就会在连接时自动加入到known_hosts中去。
    session.setConfig("StrictHostKeyChecking", "no");

    //開始Sesiion連接(Timeout 10 sec)
    session.connect(10*1000);
    //從Session建立一個Chanel並啟用Shell模式
    Channel channel = session.openChannel("shell");

    //將指令轉換成InputStream
    InputStream is = new ByteArrayInputStream(command.getBytes());
    //將指令的InputStream給Chanel
    channel.setInputStream(is);
    
    //將Chanel的輸出流設成標準輸出
    channel.setOutputStream(System.out);

    //Chanel啟動連接
    channel.connect(15 * 1000);
    
    //停頓3秒鐘等待指令執行完畢
    Thread.sleep(3*1000);
    
    //中斷連線
    channel.disconnect();
    session.disconnect();
  }
} 

程式碼來源 http://www.examplesample.com/recipe?recipe=execute-command-over-ssh

執行結果



補充資料

Port forwarding via SSH (SSH tunneling) creates a secure connection between a local computer and a remote machine through which services can be relayed. Because the connection is encrypted, SSH tunneling is useful for transmitting information that uses an unencrypted protocol, such as IMAP, VNC, or IRC.

資料來源
https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding


SSH客戶端的配置文件中有一個選項StrictHostKeyChecking,默認是“ask”,

可以把它改為“no”,這樣主機密鑰就會在連接時自動加入到known_hosts中去。

ssh會把你每個你訪問過計算機的公鑰(public key)都記錄在~/.ssh/known_hosts。當下次訪問相

同計算機時,OpenSSH會核對公鑰。如果公鑰不同,OpenSSH會發出警告,避免你受到DNS 

Hijack之類的攻擊。

SSH對主機的public_key的檢查等級是根據StrictHostKeyChecking變量來配置的。默認情況

下,StrictHostKeyChecking=ask。簡單所下它的三種配置值:

1.StrictHostKeyChecking=no

最不安全的級別,當然也沒有那麽多煩人的提示了,相對安全的內網測試時建議使用。如果連接server的key在本地不存在,那麽就自動添加到文件中(默認是known_hosts),並且給出一個警告。

2.StrictHostKeyChecking=ask

默認的級別,就是出現剛才的提示了。如果連接和key不匹配,
給出提示,並拒絕登錄。



3.StrictHostKeyChecking=yes 

最安全的級別,如果連接與key不匹配,就拒絕連接,不會提示詳細信息。

資料來源
http://bbs.51osos.com/thread-12198-1-1.html


[C#] 含藥化粧品詳細處方成分資料集 -以成份做分類

將以下網址
http://data.fda.gov.tw/frontsite/data/DataAction.do?method=doDetail&infoId=43





















XML下載下來





































接下來用C#程式處理資料


 using System;  
 using System.Collections.Generic;  
 using System.ComponentModel;  
 using System.Data;  
 using System.Drawing;  
 using System.IO;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Windows.Forms;  
 using System.Xml;  
 using System.Collections;  
 namespace Data  
 {  
   public partial class Form1 : Form  
   {  
     public Form1()  
     {  
       InitializeComponent();  
     }  
     List<dataXML> list43 = new List<dataXML>();  
     Hashtable element = new Hashtable();  
     FileStream fs = new FileStream("element_class.txt", FileMode.Create);  
     StreamWriter sw;  
     private void button1_Click(object sender, EventArgs e)  
     {  
       //讀取  
       read43();  
       //寫檔  
       sw = new StreamWriter(fs);  
       writeFile();  
       sw.Flush();  
       //關閉流  
       sw.Close();  
       fs.Close();  
     }  
     private void writeFile()  
     {  
       dataXML data;  
       ArrayList akeys = new ArrayList(element.Keys); //別忘了導入System.Collections  
       akeys.Sort(); //按字母順序進行排序  
       foreach (string skey in akeys)  
       {  
         if (skey.Trim() == String.Empty)  
         {  
           continue;  
         }  
         ArrayList array= (ArrayList)element[skey];  
         sw.Write(skey+"\n\n");  
         for (int i=0;i<array.Count;i++)  
         {  
           data=(dataXML)array[i];  
           sw.WriteLine(data.許可證字號);  
         }  
         sw.WriteLine("\n");  
       }  
     }  
     private void read43()  
     {  
       Hashtable hs =new Hashtable();  
       dataXML d43;  
       XmlDocument xd = new XmlDocument();  
       //Load裡放xml的路徑就可去讀取  
       xd.Load("43_1.xml");  
       //可將xml裡的<rows>元素都存到nodelist裡  
       XmlNodeList nodelist = xd.SelectNodes("//rows");  
       //再用迴圈去跑出來  
       foreach (XmlNode item_File in nodelist)  
       {  
         XmlNodeList childnodelist = item_File.ChildNodes;  
         d43 = new dataXML();  
         foreach (XmlNode childXmlNode in childnodelist)  
         {  
           switch (childXmlNode.Name)  
           {  
             case "許可證字號":  
               d43.許可證字號 = childXmlNode.InnerText.Replace("'", "''");  
               break;  
             case "處方標示":  
               d43.處方標示 = childXmlNode.InnerText.Replace("'", "''");  
               break;  
             case "成分名稱":  
               d43.成分名稱 = childXmlNode.InnerText.Replace("'", "''");  
               break;  
             case "含量描述":  
               d43.含量描述 = childXmlNode.InnerText.Replace("'", "''");  
               break;  
             case "含量":  
               d43.含量 = childXmlNode.InnerText.Replace("'", "''");  
               break;  
             case "含量單位":  
               d43.含量單位 = childXmlNode.InnerText.Replace("'", "''");  
               break;  
             default:  
               break;  
           }  
         }  
         if (!element.ContainsKey(d43.成分名稱))  
         {  
           ArrayList array = new ArrayList();  
           array.Add(d43);  
           element.Add(d43.成分名稱, array);  
         }  
         else  
         {  
           ArrayList oldArray =(ArrayList) element[d43.成分名稱];  
           element.Remove(d43.成分名稱);  
           oldArray.Add(d43);  
           element.Add(d43.成分名稱, oldArray);  
         }  
         list43.Add(d43);  
       }  
     }  
     struct dataXML  
     {  
       public string 許可證字號;  
       public string 處方標示;  
       public string 成分名稱;  
       public string 含量描述;  
       public string 含量;  
       public string 含量單位;  
     }  
   }  
 }  


執行結果

2015年4月21日 星期二

[C#] 產生AES每次加密出來字串皆不同

假設我加密10次1234567890ABC出來的加密字串皆不同,但都可以解回原文的方式。


程式碼如下

 using System;  
 using System.Collections.Generic;  
 using System.ComponentModel;  
 using System.Data;  
 using System.Drawing;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Windows.Forms;  
 using System.Security.Cryptography;  
 namespace WindowsFormsApplication7  
 {  
   public partial class Form1 : Form  
   {  
     public Form1()  
     {  
       InitializeComponent();  
     }  
     private void button1_Click(object sender, EventArgs e)  
     {  
       Random r = new Random();  
       int[] ramdon3=new int[3];  
       //確保TextBox1的長度符合要求  
       while (textBox1.Text.Length < 13)  
       {  
         textBox1.Text+=" ";  
       }  
       //產生3組不同長度亂數  
       ramdon3[0] = r.Next(0, 9);  
       ramdon3[1]=r.Next(10,99);  
       ramdon3[2] = r.Next(1000, 9999);  
       string newString = ramdon3[0] + textBox1.Text.Substring(0, 3)+ramdon3[1]+textBox1.Text.Substring(3,5)+ramdon3[2] +textBox1.Text.Substring(8,5);  
       byte[] b=encrypt(newString,"abcd1234");  
       string encryptStr = Convert.ToBase64String(b);  
       label1.Text = encryptStr;  
       label2.Text = String.Empty;  
     }  
     //加密函式  
     private byte[] encrypt(string string_secretContent, string string_pwd)  
     {  
       //密碼轉譯一定都是用byte[] 所以把string都換成byte[]  
       byte[] byte_secretContent = Encoding.UTF8.GetBytes(string_secretContent);  
       byte[] byte_pwd = Encoding.UTF8.GetBytes(string_pwd);  
       //加解密函數的key通常都會有固定的長度 而使用者輸入的key長度不定 因此用hash過後的值當做key  
       MD5CryptoServiceProvider provider_MD5 = new MD5CryptoServiceProvider();  
       byte[] byte_pwdMD5 = provider_MD5.ComputeHash(byte_pwd);  
       //產生加密實體 如果要用其他不同的加解密演算法就改這裡(ex:AES)  
       RijndaelManaged provider_AES = new RijndaelManaged();  
       ICryptoTransform encrypt_AES = provider_AES.CreateEncryptor(byte_pwdMD5, byte_pwdMD5);  
       //output就是加密過後的結果  
       byte[] output = encrypt_AES.TransformFinalBlock(byte_secretContent, 0, byte_secretContent.Length);  
       return output;  
     }  
     //解密函式  
     private string decrypt(byte[] byte_ciphertext, string string_pwd)  
     {  
       //密碼轉譯一定都是用byte[] 所以把string都換成byte[]  
       byte[] byte_pwd = Encoding.UTF8.GetBytes(string_pwd);  
       //加解密函數的key通常都會有固定的長度 而使用者輸入的key長度不定 因此用hash過後的值當做key  
       MD5CryptoServiceProvider provider_MD5 = new MD5CryptoServiceProvider();  
       byte[] byte_pwdMD5 = provider_MD5.ComputeHash(byte_pwd);  
       //產生解密實體  
       RijndaelManaged provider_AES = new RijndaelManaged();  
       ICryptoTransform decrypt_AES = provider_AES.CreateDecryptor(byte_pwdMD5, byte_pwdMD5);  
       //string_secretContent就是解密後的明文  
       byte[] byte_secretContent = decrypt_AES.TransformFinalBlock(byte_ciphertext, 0, byte_ciphertext.Length);  
       string string_secretContent = Encoding.UTF8.GetString(byte_secretContent);  
       return string_secretContent;  
     }  
     private void button2_Click(object sender, EventArgs e)  
     {  
       //防呆  
       if (label1.Text == String.Empty)  
         return;  
       //解密  
       byte[] b = Convert.FromBase64String(label1.Text);  
       string newString = decrypt(b, "abcd1234");  
       //拆掉亂數  
       label2.Text = newString.Substring(1, 3) + newString.Substring(6, 5) + newString.Substring(15, 5);  
     }  
   }  
 }  

執行畫面如下

第一次執行加密

















執行解密
第2次執行加密


執行解密



AES加解密函式程式碼來源
http://blog.wahahajk.com/2008/08/c-demo-aes-3des.html

2015年4月20日 星期一

「分享」健保藥價OpenData

健保藥價不定期會更改,今天北七做一個示範 ,如何去找到健保藥品資料



首先,藥價檔案在這個網頁內

http://117.56.91.4/node/9385





































這是政府的Open Data,所以不必擔心來源不明。

下載後是一個CSV檔,可以用Excel開起來看,也很方便用程式做存取。





















藥品代號,中、英名、成份、價格等有都有了。

2015年4月18日 星期六

[Java]Servelet 存取 properties

需要寫一個PropertyUtils.java 來存取專案中的 config.properties






















以下是程式碼

PropertyUtils.java
 

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;

/**
 *
 * @author bert
 */
public class PropertyUtils {
  //  private static final Logger log = LoggerFactory.getLogger(PropertyUtils.class);
    
    public PropertyUtils(){
        
    }
    
    /**
     * 透過Key取得參數
     * @param key
     * @return String
     */
    public  static String getPropert(String key){
        String result = null;
        try {

            Properties prop = new Properties();
            String propFileName = "config.properties";
     
            InputStream is = PropertyUtils.class.getClassLoader().
                    getResourceAsStream(propFileName);
            prop.load(is);
            if (is == null) {
                throw new FileNotFoundException("property file '" + 
                        propFileName +
                        "' not found in the classpath");
            }
     
            Date time = new Date(System.currentTimeMillis());
     
            // get the property value and print it out            
            result = prop.getProperty(key);

            if(is != null){
                is.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        return result;
    }
    
    
}

使用方式
 
private final String DB_Name = PropertyUtils.getPropert("db_name");
private final String IP = PropertyUtils.getPropert("db_location");
private final String USER = PropertyUtils.getPropert("db_user");
private final String PSW = PropertyUtils.getPropert("db_password");


config.properties

db_user = dbuser
db_password = abcd1234
db_location=192.168.1.100
db_name=DemoDB

[Java] 若資料夾不存在則建立資料夾

 

/**
* 建立資料夾(先檢查存不存在)
*/
public void createFold(String foldName) {
    File theDir = new File(foldName);
    // if the directory does not exist, create it
    if (!theDir.exists()) {
        System.out.println("creating directory: " + foldName);
        boolean result = false;

        try {
            theDir.mkdir();
            result = true;
        } catch (SecurityException se) {
            //handle it
       }
        if (result) {
            System.out.println("DIR created");
        }
    }
}

[C#] DataGridView 轉成 DataTable

DataGridView轉成DataTable

  //Converts the DataGridView to DataTable  
     public static DataTable DataGridView2DataTable(DataGridView dgv, String tblName="", int minRow = 0)  
     {  
       DataTable dt = new DataTable();  
       // Header columns  
       foreach (DataGridViewColumn column in dgv.Columns)  
       {  
         //DataColumn dc = new DataColumn(column.Name.ToString());  
         DataColumn dc = new DataColumn(column.HeaderText.ToString());  
         dt.Columns.Add(dc);  
       }  
       // Data cells  
       for (int i = 0; i < dgv.Rows.Count; i++)  
       {  
         DataGridViewRow row = dgv.Rows[i];  
         DataRow dr = dt.NewRow();  
         for (int j = 0; j < dgv.Columns.Count; j++)  
         {  
           dr[j] = (row.Cells[j].Value == null) ? "" : row.Cells[j].Value.ToString();  
         }  
         dt.Rows.Add(dr);  
       }  
       // Related to the bug arround min size when using ExcelLibrary for export  
       for (int i = dgv.Rows.Count; i < minRow; i++)  
       {  
         DataRow dr = dt.NewRow();  
         for (int j = 0; j < dt.Columns.Count; j++)  
         {  
           dr[j] = " ";  
         }  
         dt.Rows.Add(dr);  
       }  
       return dt;  
     }  

[C#] ascii 與Char 轉換

ascii轉 Char

  /// <summary>  
     /// ascii 轉成 Char  
     /// </summary>  
     /// <param name="Num">AscII CODE數值</param>  
     /// <returns>字元</returns>  
     public static char Chr(int Num)  
     {  
       char C = Convert.ToChar(Num);  
       return C;  
     }  

Char 轉ascii

  /// <summary>  
     /// 轉成ASCii   
     /// </summary>  
     /// <param name="C">要轉的字元</param>  
     /// <returns>ASCII Code數值</returns>  
     public static int ASC(char C)  
     {  
       int N = Convert.ToInt32(C);  
       return N;  
     }  

[C#] 3DES解密

開發上用過的Method,紀錄在此。

  /// <summary>  
  /// 解密  
  /// </summary>  
  /// <param name="encrypt">要解密的字串</param>  
  /// <param name="key">KEY</param>  
  /// <param name="IV">IV</param>  
  /// <returns>解密後的字串</returns>  
  private static string desDecryptBase64(string encrypt, string key, string IV)  
  {  
    DESCryptoServiceProvider des = new DESCryptoServiceProvider();  
    byte[] key = Encoding.ASCII.GetBytes(key);  
    byte[] iv = Encoding.ASCII.GetBytes(IV);  
    des.Key = key;  
    des.IV = iv;  
    byte[] dataByteArray = Convert.FromBase64String(encrypt);  
    using (MemoryStream ms = new MemoryStream())  
    {  
      using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))  
      {  
        cs.Write(dataByteArray, 0, dataByteArray.Length);  
        cs.FlushFinalBlock();  
        return Encoding.UTF8.GetString(ms.ToArray());  
      }  
    }  
  }  

[C#][JAVA] 3DES─C# 加密,JAVA 解密

C# 3DES 加密,JAVA 解密程式碼筆記

C#
  /// <summary>  
     /// 加密  
     /// </summary>  
     /// <param name="source">欲加密的字串</param>  
     /// <returns>加密後的字串</returns>  
     private static string desEncryptBase64(string source,string key, string iv)  
     {  
       DESCryptoServiceProvider des = new DESCryptoServiceProvider();  
       byte[] dataByteArray = Encoding.UTF8.GetBytes(source);  
       byte[] key = Encoding.ASCII.GetBytes(key);  
       byte[] iv = Encoding.ASCII.GetBytes(iv);  
       des.Key = key;  
       des.IV = iv;  
       string encrypt = "";  
       using (MemoryStream ms = new MemoryStream())  
       using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))  
       {  
         cs.Write(dataByteArray, 0, dataByteArray.Length);  
         cs.FlushFinalBlock();  
         encrypt = Convert.ToBase64String(ms.ToArray());  
       }  
       return encrypt;  
     }  


Java

 
 //解密
public String decryptDES(String decryptString, String decryptKey, String IV) {

String text = null;
try {
    //byte[] byteMi = new BASE64Decoder().decodeBuffer(decryptString);
    byte[] byteMi = Base64.decodeBase64(decryptString);
    IvParameterSpec zeroIv = new IvParameterSpec(IV.getBytes());
    SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
    byte decryptedData[] = cipher.doFinal(byteMi);

    text = new String(decryptedData, "UTF8");
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidAlgorithmParameterException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    } catch (UnsupportedEncodingException ex) {
        Logger.getLogger(Func.class.getName()).log(Level.SEVERE, null, ex);
    }
    return text;
   }

[Java] 產生不重覆的亂數

今天如果需要產生不重覆的亂數,可以用類似玩撲克牌的方式洗牌。

1.先產生所需要的範圍陣列。

2.依序填入數值 (ex: 1 ,2 ,3 ,4 , ...,N)

3.將陣列中每一個值都與位置R互換,R是由亂數產生的,

  亂數範圍由0~陣列長度-1 ,這樣最終可以求得不重覆亂數。

 
package random;

import java.util.Random;

/**
 *
 * @author bert
 */
public class Demo {

    public static void main(String[] args) {

        Demo demo = new Demo();
        int[] poko = demo.DemoRandom();

        for (int i = 0; i < poko.length; i++) {
            System.out.print(poko[i] + ",");
        }
        System.out.println();
    }

    private int[] DemoRandom() {
        int[] poko = new int[52];
        int R = 0;
        Random random = new Random();
        int temp = 0;
        //先產生要的數值出來
        for (int i = 0; i < poko.length; i++) {
            poko[i] = i;
        }

        //洗牌
        for (int i = 0; i < poko.length; i++) {
            //產生亂數
            R = random.nextInt(poko.length);
            temp = poko[i];
            poko[i] = poko[R];
            poko[R] = temp;
        }

        return poko;
    }
}



執行結果

[Java]以Java發送E-mail

Java 要寄送E-mail,需要透過JavaMail以及JavaBeans Activation Framework (JAF) 。

JAF的用途主要是用來識別檔案的類型。

首先到http://www.oracle.com/technetwork/java/index-138643.html

下載JavaMail ,除非你使用的是Java 1.6以前的版本,否則JAF己內建於Java 1.6中了。

如果你使用的一般非gmail的SMTP伺服器,gmail有啟用SSL,之後再補另一篇來紀錄。


一開始先寄一封純文字的信件,主要寄信程式碼:


 
package javaemail;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 *
 * @author flowercatswets
 */
public class JavaEmail {

    public static void main(String[] args) {

        //user
        String user = "username";
        //password
        String pwd = "abcd1234";

        //接收者的email.
        String to = "abcd@yahoo.com.tw";

        //寄件人的email
        String from = "aa@taida.com.tw";

        // 寄件的smtp伺服器
        String host = "mail.taida.com.tw";

        // 主旨
        String subject = "Java 寄來的信";

        //內文
        String body = "Java程式發送出來的信";

        // 建立一個Properties來設定Properties
        Properties properties = System.getProperties();

        //設定傳輸協定為smtp
        properties.setProperty("mail.transport.protocol", "smtp");
        //設定mail Server
        properties.setProperty("mail.smtp.host", host);
        properties.setProperty("mail.smtp.port", "25");
        //需要驗證帳號密碼
        properties.put("mail.smtp.auth", "true");
        //Bypass the SSL authentication
        properties.put("mail.smtp.ssl.enable", false);
        properties.put("mail.smtp.starttls.enable", false);

        //帳號,密碼
        SmtpAuthenticator authentication = 
                new SmtpAuthenticator(user, pwd);

        // 建立一個Session物件,並把properties傳進去
        Session mailSession = Session.
                getDefaultInstance(properties, authentication);

        try {
            //建立一個 MimeMessage object.
            MimeMessage message = new MimeMessage(mailSession);

            // 設定寄件人
            message.setFrom(new InternetAddress(from));

            // 設定收件人
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(to));

            // 設定主旨
            message.setSubject(subject);

            //設定內文
            message.setText(body);

            Transport transport = mailSession.getTransport();

            // 傳送信件         
            transport.send(message);

            System.out.println("發送成功");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }

}

接下來是認證帳號密碼用的class ,它是繼承Authenticator,

覆寫其中的getPasswordAuthentication,使其可傳回具有帳密碼的

PasswordAuthentication物件
 
package javaemail;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

/**
 *
 * @author flowercatswets
 */
public class SmtpAuthenticator extends Authenticator {

    private String USER;
    private String PASSWORD;

    //空的建構子
    public SmtpAuthenticator() {

        super();
    }

    //可以讓外部傳送帳號密碼進來的建構子
    public SmtpAuthenticator(String user, String password) {
        this();
        this.USER = user;
        this.PASSWORD = password;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        String username = USER;
        String password = PASSWORD;
        if ((username != null) && (username.length() > 0)
                && (password != null)
                && (password.length() > 0)) {

            return new PasswordAuthentication(username, password);
        }

        return null;
    }

}


來看一下執行結果
 


接下來來附加檔案 ,差異只在寄信的主程式

package javaemail;

import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 *
 * @author flowercatswets
 */
public class JavaEmail {

    public static void main(String[] args) {

        //user
        String user = "username";
        //password
        String pwd = "abcd1234";

        //接收者的email.
        String to = "abcd@yahoo.com.tw";

        //寄件人的email
        String from = "aa@taida.com.tw";

        // 寄件的smtp伺服器
        String host = "mail.taida.com.tw";

        // 主旨
        String subject = "Java 寄來的信";

        //內文
        String body = "Java程式發送出來的信";

        // 建立一個Properties來設定Properties
        Properties properties = System.getProperties();

        //設定傳輸協定為smtp
        properties.setProperty("mail.transport.protocol", "smtp");
        //設定mail Server
        properties.setProperty("mail.smtp.host", host);
        properties.setProperty("mail.smtp.port", "25");
        //需要驗證帳號密碼
        properties.put("mail.smtp.auth", "true");
        //Bypass the SSL authentication
        properties.put("mail.smtp.ssl.enable", false);
        properties.put("mail.smtp.starttls.enable", false);

        //帳號,密碼
        SmtpAuthenticator authentication
                = new SmtpAuthenticator(user, pwd);

        // 建立一個Session物件,並把properties傳進去
        Session mailSession = Session.
                getDefaultInstance(properties, authentication);

        try {
            //建立一個 MimeMessage object.
            MimeMessage message = new MimeMessage(mailSession);

            // 設定寄件人
            message.setFrom(new InternetAddress(from));

            // 設定收件人
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(to));

            // 設定主旨
            message.setSubject(subject);

            //宣告一個BodyPart用以夾帶內文      
            BodyPart messageBodyPart = new MimeBodyPart();

            //設定內文
            messageBodyPart.setText(body);
            // 宣告一個multipart , 它可以使內文有不同的段落,
            //使其可以用用來夾帶內文及檔案
            Multipart multipart = new MimeMultipart();
            //把BodyPart加入Multipart(這個part夾帶內文)
            multipart.addBodyPart(messageBodyPart);
            //宣告一個BodyPart用以夾帶附加檔案
            BodyPart fileBodyPart = new MimeBodyPart();
            //要夾帶的檔案名稱
            String filename = 
                    "/Users/flowercatswets/Documents/lena.jpg";
            //讀取檔案
            DataSource source = new FileDataSource(filename);
            fileBodyPart.setDataHandler(new DataHandler(source));
            //設定附加檔案的名稱
            fileBodyPart.setFileName(filename);
            //把BodyPart加入Multipart(這個part夾帶檔案)
            multipart.addBodyPart(fileBodyPart);
            //設定eMultipart為messag的Content
            message.setContent(multipart );
            Transport transport = mailSession.getTransport();

            // 傳送信件         
            transport.send(message);

            System.out.println("發送成功");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }

}

差異只在於原本單純的內文

//設定內文
message.setText(body);


變成多個part,一個part帶內文,一個part帶檔案
//宣告一個BodyPart用以夾帶內文      
BodyPart messageBodyPart = new MimeBodyPart();

//設定內文
messageBodyPart.setText(body);
// 宣告一個multipart , 它可以使內文有不同的段落,
//使其可以用用來夾帶內文及檔案
Multipart multipart = new MimeMultipart();
//把BodyPart加入Multipart(這個part夾帶內文)
multipart.addBodyPart(messageBodyPart);
//宣告一個BodyPart用以夾帶附加檔案
BodyPart fileBodyPart = new MimeBodyPart();
//要夾帶的檔案名稱
String filename = 
    "/Users/flowercatswets/Documents/lena.jpg";
//讀取檔案
DataSource source = new FileDataSource(filename);
fileBodyPart.setDataHandler(new DataHandler(source));
//設定附加檔案的名稱
fileBodyPart.setFileName(filename);
//把BodyPart加入Multipart(這個part夾帶檔案)
multipart.addBodyPart(fileBodyPart);
//設定eMultipart為messag的Content
message.setContent(multipart )


執行結果













資料來源
http://www.tutorialspoint.com/java/java_sending_email.htm

http://stackoverflow.com/questions/6610572/javax-mail-authenticationfailedexception-failed-to-connect-no-password-specifi

2015年4月16日 星期四

[分享]Dlink dns320 更新韌體

首先到這個網頁

http://www.dlink.com/uk/en/support/product/dns-320-2-bay-sharecenter-network-storage-enclosure?revision=deu_reva#downloads


接下來選擇你的hardware revision(硬體版本),在機身上的序號貼紙上有。












網站上也有貼心的說明




依照手上的機型選擇了A,接下來是選擇最新版的Firmware 點選Download


解壓縮下載的檔案
看起來還有在壓縮一層,再解壓縮一次,之後就出現我們要的檔案了

登入NAS



選擇『管理』 -> 系統管理


選擇韌體升級
選擇好剛才下載的檔案->套用


升級中
大概3分鐘後升級完成
重開機中
來確定一下版本已經升級

[linux] 收到信同時轉發給其他人(設定別名)

以ssh登入後,轉換為root身份

編輯 /etc/aliases

 vi /etc/aliases  

在最底下加入要轉信的人 :  轉給誰












如上圖,我要把 group 收到的信轉給user1以及user2(但group本身不會收到)。

若要三個人都收到要這樣打 group: group,user1,user2。

存檔並離開,再輸入newaliases














[C#] 簡易#字遊戲

井字遊戲是一簡單又好玩的小東西,剛好上星期新同事在看有關Graphics的部份,

便出這個題目給他練習一下繪圖並完成小作品,北七也抽空寫了一個小範例。

































程式說明

region 陣列用來紀錄以下9個位子是否有被填入O或X,

region陣列內若為1,則會繪上O,為2則會繪上X。





















透過覆寫OnPaint 事件,會依照region以及bingo內的結果作繪圖。

至於Form1_MouseMove中取得滑鼠位置,這點需要注意一下,

北七一開始用如下方式取得滑鼠座標

 int x= MousePosition.X;

 int y= MousePosition.Y;


取出來的位置與Form上所用的座標不同,以下面這一段CODE舉例

private void Form1_MouseMove(object sender, MouseEventArgs e) {


mouse_location_x = e.Location.X;


mouse_location_y = e.Location.Y;


int x= MousePosition.X;


int y= MousePosition.Y; 

Console.WriteLine(mouse_location_x+"\t"+mouse_location_y+"\n"+x+"\t"+y); }

輸出結果如下,可以看到差距是頗大的,這一點需要注意一下。

256 340
514 620

附上完整程式碼

 using System;  
 using System.Collections.Generic;  
 using System.ComponentModel;  
 using System.Data;  
 using System.Drawing;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Windows.Forms;  
 namespace 井字遊戲  
 {  
   public partial class Form1 : Form  
   {  
     //紀錄九宮格狀態  
     int[] region = new int[9];  
     public Form1()  
     {  
       InitializeComponent();  
       this.Width = 561;  
       this.Height = 561;  
     }  
     //計算每一個欄的寬度  
     float column;  
     //計算每一個列的高度  
     float row ;  
     //O先  
     bool o_x = true;  
     //滑鼠X  
     int mouse_location_x;  
     //滑鼠Y  
     int mouse_location_y;  
     //是否有勝利連線  
     int[] bingo = new int[8];  
     //已結束  
     bool finish = false;  
     //繪圖  
     protected override void OnPaint(PaintEventArgs pe)  
     {  
       //取得Graphics  
       Graphics g = pe.Graphics;  
       //取得Pen  
       Pen p=new Pen(Color.Black);  
       //取得畫面大小  
       float width = this.Width-20;  
       float height = this.Height-20;  
       //計算出要畫的範圍  
       column = width / 3;  
       row = height / 3;  
       //畫橫線        
       g.DrawLine(p, 0, row, width, row);  
       g.DrawLine(p, 0, row*2, width, row*2);  
       //畫直線  
       g.DrawLine(p, column, 0, column, height);  
       g.DrawLine(p, column * 2, 0, column*2, height);  
       //判斷是否需要畫OX  
       for (int i = 0; i < region.Length; i++)  
       {  
         if (region[i] == 1)  
         {  
           g.DrawEllipse(p, (i % 3) * (column) + 30, (i / 3) * (row) + 30, column - 60, row - 60);  
         }  
         if (region[i] == 2)  
         {  
           g.DrawLine(p, (i % 3) * column + 20, (i / 3) * row + 20, ((i % 3) + 1) * column - 20, (i / 3 + 1) * row - 20);  
           g.DrawLine(p, ((i % 3) + 1) * column - 20, (i / 3) * row + 20, (i % 3) * column + 20, ((i / 3) + 1) * row - 20);  
         }  
       }  
       //畫出勝利直線  
       for (int i = 0; i < bingo.Length; i++)  
       {  
         //0,1,2  
         if (bingo[0]==1)  
         {  
           g.DrawLine(p, 0,row/2,width,row/2);  
           finish = true;  
         }  
         //3,4,5  
         if (bingo[1] == 1)  
         {  
           g.DrawLine(p, 0, row*2 -row/2, width, row*2-row/2);  
           finish = true;  
         }  
         //6,7,8  
         if (bingo[2] == 1)  
         {  
           g.DrawLine(p, 0, row * 3 - row / 2, width, row * 3 - row / 2);  
           finish = true;  
         }  
         //0,3,6  
         if (bingo[3] == 1)  
         {  
           g.DrawLine(p, column-(column/2), 0, column-(column/2),height);  
           finish = true;  
         }  
         //1,4,7  
         if (bingo[4] == 1)  
         {  
           g.DrawLine(p, column*2 - (column / 2), 0, column *2- (column / 2), height);  
           finish = true;  
         }  
         //2,5,8  
         if (bingo[5] == 1)  
         {  
           g.DrawLine(p, column * 3 - (column / 2), 0, column * 3 - (column / 2), height);  
           finish = true;  
         }  
         //0,4,8  
         if (bingo[6] == 1)  
         {  
           g.DrawLine(p, 0 , 0, width , height);  
           finish = true;  
         }  
         //2,4,6  
         if (bingo[7] == 1)  
         {  
           g.DrawLine(p,width, 0,0,height);  
           finish = true;  
         }  
       }  
     }  
     //滑鼠點下去後要做的事  
     private void Form1_Click(object sender, EventArgs e)  
     {  
       //取得滑鼠座標  
       int x = mouse_location_x;  
       int y = mouse_location_y;  
       if (finish == false)  
       {  
         //判斷點下的區域是那一個  
         //左邊第一排0,3,6  
         if (x < column)  
         {  
           //0  
           if (y > 0 && y < row)  
           {  
             if (region[0] == 0)  
             {  
               region[0] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
           //3  
           if (y > row && y < row * 2)  
           {  
             if (region[3] == 0)  
             {  
               region[3] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
           //6  
           if (y > row * 2 && y < row * 3)  
           {  
             if (region[6] == 0)  
             {  
               region[6] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
         }  
         //中間那一排  
         if (x > column && x < column * 2)  
         {  
           //1  
           if (y > 0 && y < row)  
           {  
             if (region[1] == 0)  
             {  
               region[1] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
           //4  
           if (y > row && y < row * 2)  
           {  
             if (region[4] == 0)  
             {  
               region[4] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
           //7  
           if (y > row * 2 && y < row * 3)  
           {  
             if (region[7] == 0)  
             {  
               region[7] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
         }  
         //右邊那一排  
         if (x > column * 2 && x < column * 3)  
         {  
           //2  
           if (y > 0 && y < row)  
           {  
             if (region[2] == 0)  
             {  
               region[2] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
           //5  
           if (y > row && y < row * 2)  
           {  
             if (region[5] == 0)  
             {  
               region[5] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
           //8  
           if (y > row * 2 && y < row * 3)  
           {  
             if (region[8] == 0)  
             {  
               region[8] = o_x == true ? 1 : 2;  
               o_x = !o_x;  
             }  
           }  
         }  
       }  
        //檢查是否有連線(8種組合)  
       //第一列  
       if (region[0] == region[1] && region[1]== region[2] && region[0]!=0)  
       {  
         bingo[0] = 1;  
       }  
       //第二列  
       else if (region[3] == region[4] && region[4] == region[5] && region[3] != 0)  
       {  
         bingo[1] = 1;  
       }  
       //第三列  
       else if (region[6] == region[7] && region[7] == region[8] && region[6] != 0)  
       {  
         bingo[2] = 1;  
       }  
       //第一行  
       else if (region[0] == region[3] && region[3] == region[6] && region[0] != 0)  
       {  
         bingo[3] = 1;  
       }  
       //第二行  
       else if (region[1] == region[4] && region[4] == region[7] && region[1] != 0)  
       {  
         bingo[4] = 1;  
       }  
       //第三行  
       else if (region[2] == region[5] && region[5] == region[8] && region[2] != 0)  
       {  
         bingo[5] = 1;  
       }  
       // \連線  
       else if (region[0] == region[4] && region[4] == region[8] && region[0] != 0)  
       {  
         bingo[6] = 1;  
       }  
       // /連線  
       else if (region[2] == region[4] && region[4] == region[6] && region[2] != 0)  
       {  
         bingo[7] = 1;  
       }  
       this.Refresh();  
       //檢查和局  
       int check=0;  
       for (int i = 0; i < region.Length; i++)  
       {  
         if (region[i] > 0)  
           check++;  
       }  
       if (check == 9)  
       {  
         for (int i = 0; i < bingo.Length; i++)  
         {  
           if (bingo[i] > 0)  
           {  
             check--;  
           }  
         }  
       }  
       if (check == 9)  
       {  
         DialogResult dialogResult = MessageBox.Show("平手,要不要再來一局?", "分出勝負", MessageBoxButtons.YesNo);  
         if (dialogResult == DialogResult.Yes)  
         {  
           for (int i = 0; i < region.Length; i++)  
           {  
             region[i] = 0;  
           }  
           for (int i = 0; i < bingo.Length; i++)  
           {  
             bingo[i] = 0;  
           }  
           o_x = true;  
           finish = false;  
           this.Refresh();  
         }  
         else if (dialogResult == DialogResult.No)  
         {  
           this.Close();  
         }  
       }  
       //已分出勝負  
       if (finish)  
       {  
         DialogResult dialogResult = MessageBox.Show(o_x ? "X獲勝,要不要再來一局?" : "O獲勝,要不要再來一局?", "分出勝負", MessageBoxButtons.YesNo);  
         if (dialogResult == DialogResult.Yes)  
         {  
           for (int i = 0; i < region.Length; i++)  
           {  
             region[i] = 0;  
           }  
           for (int i = 0; i < bingo.Length; i++)  
           {  
             bingo[i] = 0;  
           }  
           o_x = true;  
           finish = false;  
           this.Refresh();  
         }  
         else if (dialogResult == DialogResult.No)  
         {  
           this.Close();  
         }  
       }  
     }  
     //取得滑鼠位置  
     private void Form1_MouseMove(object sender, MouseEventArgs e)  
     {  
       mouse_location_x = e.Location.X;  
       mouse_location_y = e.Location.Y;  
     }  
   }  
 }  

[C#] 取得電腦上所有磁碟代號

程式碼
 using System;  
 using System.Collections.Generic;  
 using System.ComponentModel;  
 using System.Data;  
 using System.Drawing;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Windows.Forms;  
 namespace Dispaly_all_logic_driver  
 {  
   public partial class Form1 : Form  
   {  
     public Form1()  
     {  
       InitializeComponent();  
       //把裝置代碼加入ListBox裡  
       List<string> list = get_all_logic_driver();  
       foreach (string drive in list)  
         listBox1.Items.Add(drive);  
     }  
     /// <summary>  
     /// 取得電腦上所有邏輯裝置代碼  
     /// </summary>  
     /// <returns></returns>  
     private List<string> get_all_logic_driver()  
     {  
       List<string> list = new List<string>();  
       foreach (string drive in Environment.GetLogicalDrives())  
       {  
         list.Add(drive);  
       }  
       return list;  
     }  
   }  
 }  


執行畫面如下













如果要識別出那個是光碟機需要呼叫WINDOWS API 來判斷DviveType

  [DllImport("kernel32", SetLastError = true)]  
     public static extern int GetDriveType(string driveLetter);  

完整程式如下

 using System;  
 using System.Collections.Generic;  
 using System.ComponentModel;  
 using System.Data;  
 using System.Drawing;  
 using System.Linq;  
 using System.Runtime.InteropServices;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Windows.Forms;  
 namespace Dispaly_all_logic_driver  
 {  
   public partial class Form1 : Form  
   {  
     [DllImport("kernel32", SetLastError = true)]  
     public static extern int GetDriveType(string driveLetter);  
     public Form1()  
     {  
       InitializeComponent();  
       //把裝置代碼加入ListBox裡  
       List<string> list = get_all_logic_driver();  
       foreach (string drive in list)  
         listBox1.Items.Add(drive);  
     }  
     /// <summary>  
     /// 取得電腦上所有邏輯裝置代碼  
     /// </summary>  
     /// <returns></returns>  
     private List<string> get_all_logic_driver()  
     {  
       List<string> list = new List<string>();  
       foreach (string drive in Environment.GetLogicalDrives())  
       {  
         if (GetDriveType(drive) == 5)  //CDROM type  
           list.Add(drive);  
       }  
       return list;  
     }  
   }  
 }  

執行結果













我的裝置




type代碼

ValueConstantMeaning
1SYSTEM_WINDRIVE_ERRORNon-existent drive or other error
2SYSTEM_WINDRIVE_REMOVABLERemovable drive (e.g. floppy)
3SYSTEM_WINDRIVE_FIXEDHarddisk
4SYSTEM_WINDRIVE_REMOTENetwork share
5SYSTEM_WINDRIVE_CDROMCD-Rom or DVD
6SYSTEM_WINDRIVE_RAMDISKRAM disk

參考資料請參考這一篇
https://pear.php.net/manual/fr/package.system.windrives.windrives.getdrivetype.php


2015年4月13日 星期一

[C#] 以SMTP 發送E-mail

簡單來講就是建立一個MailMessage物件,再透過SmtpClient物件將信透過SMTP(Simple

Mail Transport Protocol)傳送到SMTP伺服器做傳送的動作。

分成3個部份

1.發送mail函式。

  /// <summary>  
     /// 完整的寄信函數  
     /// </summary>  
     /// <param name="MailFrom">寄信人Email Address</param>  
     /// <param name="MailTos">收信人Email Address</param>  
     /// <param name="Ccs">副本Email Address</param>  
     /// <param name="MailSub">主旨</param>  
     /// <param name="MailBody">內文</param>  
     /// <param name="isBodyHtml">是否為Html格式</param>  
     /// <param name="files">要夾帶的附檔</param>  
     /// <returns>回傳寄信是否成功(true:成功,false:失敗)</returns>  
     public bool Send_Mail(string MailFrom, string[] MailTos, string[] Ccs, string MailSub, string MailBody, bool isBodyHtml, Dictionary<string, Stream> files)  
     {         
       try  
       {  
         //沒給寄信人mail address  
         if (string.IsNullOrEmpty(MailFrom))  
         {//※有些公司的Smtp Server會規定寄信人的Domain Name須是該Smtp Server的Domain Name,例如底下的 system.com.tw  
           MailFrom = "sysadmin@system.com.tw";  
         }  
         //建立MailMessage物件  
         MailMessage mms = new MailMessage();  
         //指定一位寄信人MailAddress  
         mms.From = new MailAddress(MailFrom);  
         //信件主旨  
         mms.Subject = MailSub;  
         //信件內容  
         mms.Body = MailBody;  
         //信件內容 是否採用Html格式  
         mms.IsBodyHtml = isBodyHtml;  
         if (MailTos != null)//防呆  
         {  
           for (int i = 0; i < MailTos.Length; i++)  
           {  
             //加入信件的收信人(們)address  
             if (!string.IsNullOrEmpty(MailTos[i].Trim()))  
             {  
               mms.To.Add(new MailAddress(MailTos[i].Trim()));  
             }  
           }  
         }//End if (MailTos !=null)//防呆  
         if (Ccs != null) //防呆  
         {  
           for (int i = 0; i < Ccs.Length; i++)  
           {  
             if (!string.IsNullOrEmpty(Ccs[i].Trim()))  
             {  
               //加入信件的副本(們)address  
               mms.CC.Add(new MailAddress(Ccs[i].Trim()));  
             }  
           }  
         }//End if (Ccs!=null) //防呆  
            //附件處理  
           if (files != null && files.Count > 0)//寄信時有夾帶附檔  
           {  
             foreach (string fileName in files.Keys)  
             {  
               Attachment attfile = new Attachment(files[fileName], fileName);  
               mms.Attachments.Add(attfile);  
             }//end foreach  
           }//end if  
           using (SmtpClient client = new SmtpClient(smtpServer,smtpPort))//或公司、客戶的smtp_server  
           {  
             if (!string.IsNullOrEmpty(mailAccount) && !string.IsNullOrEmpty(mailPwd))//.config有帳密的話  
             {                             
               client.Credentials = new NetworkCredential(mailAccount, mailPwd);//寄信帳密  
             }  
             client.Send(mms);//寄出一封信  
           }//end using  
           //釋放每個附件,才不會Lock住(不過即使附加檔案失敗,也會寄出信去)  
           if (mms.Attachments != null && mms.Attachments.Count>0)  
           {  
             for (int i = 0; i < mms.Attachments.Count;i++ )  
             {  
               mms.Attachments[i].Dispose();  
               //mms.Attachments[i] = null;  
             }  
           }  
         return true;//成功  
       }  
       catch (Exception ex)  
       {  
         //寄信失敗,寫Log文字檔  
         Console.WriteLine("寄信失敗" + ex.StackTrace);  
         return false;  
       }  
     }//End 寄信  

2.將附加檔案轉換成Stream。

  /// <summary>  
     /// 將附加檔案轉換成Stream  
     /// </summary>  
     /// <param name="file">檔案完整路徑</param>  
     /// <returns>回傳Stream</returns>  
     private Stream FileToStream(string file)  
     {  
       Stream sf = File.OpenRead("d:\\cpu.txt");  
       System.IO.MemoryStream data = new System.IO.MemoryStream();  
       sf.CopyTo(data);  
       data.Seek(0, SeekOrigin.Begin);  
       byte[] buf = new byte[data.Length];  
       data.Read(buf, 0, buf.Length);  
       //再移到位置0,附加檔案時才可以被讀取  
       data.Seek(0, SeekOrigin.Begin);  
       return data;  
     }  


3.主程式

     private string smtpServer = "your mail smtp server";  
     private int smtpPort = 25;  
     private string mailAccount="sample";  
     private string mailPwd = "sampelPW";  
     private void button1_Click(object sender, EventArgs e)  
     {  
       //收件人名單  
       string receiveMails = "sample1@yahoo.com.tw,sample2@yahoo.com.tw";  
       //主旨  
       string mailTitle = "C# 寄信來了";  
       //寄件人(通常是寄件本人)  
       string sendMail = "sample1@yahoo.com.tw";  
       //副件名單  
       string[] Cc ={"sample3@gmail.com"};  
       //信件內容  
       string mailbody="test send mail by c#" ;        
       //切割收件人名單  
       string[] _receiveMail=receiveMails.Split(new string[]{","},StringSplitOptions.RemoveEmptyEntries);  
       //附加檔案  
       string filename="d:\\CPU.TXT";  
       Dictionary<string, Stream> listFile = new Dictionary<string, Stream>();  
       //把檔案轉換成Stream  
       listFile.Add(Path.GetFileName(filename), FileToStream(filename));  
       //寄信  
       Send_Mail(sendMail, _receiveMail, Cc, mailTitle, mailbody, true, listFile);  
     }  


程式碼中的Email以及帳密已經過變更,請以自己的為主,以下截圖為真實收到信的情況
















接下來我們來打開附檔,是本機的CPU資訊檔案。


















































其實是可以發送HTML格式的內文。

例如我們把

string mailbody="test send mail by c#" ;

改成

 string mailbody="test <br />send <br />mail ";  


則會有如下的結果












還有另一件事就是寄件人的問題,一般而言是應該要寫在smtp伺服器上你自己的e-mail,

但有些伺服器並不會擋,所以即使你亂寫,它還是會讓你寄,有些則會擋下假的email

地址,所以還是要守規矩,建立良好的信用,本篇純教學用途。


參考資料來源

http://www.dotblogs.com.tw/shadow/archive/2011/05/23/25887.aspx

2015年4月12日 星期日

[分享] 平板OTG 條碼掃描器

某日北七突發奇想,公司用的這款條碼掃描器貌似是模擬鍵盤輸入,

那應該也可以接在平板上做輸入吧!!!!



不過有個小叮寧丫~條碼掃描器一拿出來並不一定能直接使用,它必須先透過盒子內的一本

手冊,上面有特殊的設定條碼,決定你的掃描器是要讀取何種格式的條碼,例如EAN13、

Code39、EAN 8 或是ISSN等條碼格式。

[分享] 小米LED隨身燈

最近趁著特價,買了一支小米LED隨身燈。




光源額定功率1.2W / 5V =0.24A ,所以應不必太大的電流即可驅動。

照片看中到的那一塊白色的其實是背面的散熱片,並不會發光,只是

要小心長時間使用可能會發燙。


並不一定要搭配小米行動電源,小米行動電源只是有個按鈕,按一下

會熄掉LED,再按一下會亮起來這樣,配上有開關的行動電源應也可

以達到相同的開關效果(下圖他牌行動電源只能輸出1A)。




北七覺得身為一個工具人,一定要有一支LED身燈,照機殻內部超好用。

































比手電桶好用,北七的小小手電桶照出來的光只有一個圓形區域,亮度又不是很高。


拿來檢查註牙也頗實用,感謝工具人2號好友熱情讚助。




接下來我們來試試看手機OTG是不是也OK
































別問北七為何買粉紅色,因為上週特價不能選色。