顯示具有 教學 標籤的文章。 顯示所有文章
顯示具有 教學 標籤的文章。 顯示所有文章

[Android x86]安裝在SD卡上

序

心血來潮~想在我的NB試試Android~
不過因為原本的硬碟是空間小小的SSD~
我也不想把原本安裝在上面的Windows直接覆蓋掉~
所以就想著如果能直接把Android裝在SD卡或USB上~這樣似乎不錯~
如果能直接安裝在SD卡上更好,因為我的NB上有內建讀卡機~
這樣機器就不會凸出一個大大的USB隨身碟~
而實際上嘗試過後~雖然一開始不順利~但最後還真的可以達成~
以下是我的作法~

安裝環境

  • 最少要有個支援USB的電腦(我的有支援用讀卡機開機~所以也能支援使用SD卡)
  • 以下步驟是使用Windows7建立安裝用的USB與預訂安裝Android的SD卡
  • SD卡~建議準備一張2G以上速度快一點的~最少要有1G會比較實用
  • 一個500MB以上的隨身碟,要當作安裝來源開機USB

下載檔案與工具

安裝步驟

1.分割SD卡

基本上不分割也能執行~也可以在電腦上同時外接多個USB當作額外的儲存空間~
不過我比較希望我這張SD卡既能當主硬碟又能當額外的空間~
So~~~我打算把SD卡切成兩個區塊~一個當主硬碟一個當儲存空間
  • 開啟MiniTool Partition Wizard(操作方法可自行參考網路上的文章)
  • 選擇SD卡後,把所有的空間都刪除(當然如果你裡面有資料請先移到別的地方去…)
  • 我這邊希望的是資料空間也能被Windows讀取,所以第一個區塊是資料區塊。設成Primary,格式化為Fat32,空間大小隨便,但建議剩餘空間留個1G以上~最好有2G給第二個區塊
  • 第二個區塊式系統區塊,設成Primary,格式化為Ext3,空間大小為1G以上~最好有2G
  • 最後點Apply,開始進行分割與格式化

2.建立安裝用的USB

這一步是把下載下來的Android x86 ISO檔放到USB裡做為安裝來源的開機USB~
  • 開啟Unetbootin(操作方法可自行參考網路上的文章)
  • 選擇ISO檔與目標的USB,再來就開始建立

3.開機設定

再來就可以把USB與SD卡都插上,重新開機,然後進BIOS畫面
把第一個Boot的優先權設為USB,把第二優先權設為SD卡(讀卡機)

4.安裝Android x86到SD卡

使用USB開機後,會出現Live CD與安裝的選單
  • 選擇最底下的[Installation - Install Android-x86 to harddisk]
  • 選擇分割區,選到剛才在SD卡建立的Ext3分割區
  • 如果他問你要不要Format,使用Ext3
  • 然後會問要不要安裝GRUB開機管理程式,選擇Yes(我試過不安裝,會無法順利開機)
  • 然後問要不要讓system可讀寫,選擇是
  • 再來就會開始安裝,這中間會有段時間只有藍色畫面,不要心急,等他跳出詢問要不要直接執行或是重新開機
  • 選擇重新開機,並把開機用的USB隨身碟拔除,讓它用SD卡開機
  • 再來就是耐心的等Android開機完成就大功告成了(這時候就是不成功~便成仁~禱告吧XD)

5.BIOS開機順序

成功後~我把BIOS開機順序設定成 先讀讀卡機,再讀硬碟~

這樣想用Android就把SD卡插進去開機,平常還是可以用原本的windows~

6.安裝檔案瀏覽器

安裝ES檔案瀏覽器或Root browser lite後,就可以在mnt/USB0目錄找到SD卡中分割的區塊

之後如果外接更多儲存設備也可以這樣存取

後記

使用上雖然還是有些小問題,像是youtube 不能用HD播放~輸入法不容易習慣~
還有一堆以ARM為基礎的App都不能裝(雖然有文章有提到解決方法-ARM emulation,但我還是試不出來)
但能在NB用Abdroid還是很感動~~~

[4Shared]網路硬碟上傳下載教學(Desktop程式版)

序言

幾年前曾經為了分享照片給別人,所以我曾經開發過一個FriendShare的網站。
不過當時是因為自己有個上傳速度夠快的環境所以架站很方便,這個網站也隨著這樣的環境消失而消失了。
後來我找了幾個免費的網路硬碟服務想看看有沒有能方便使用,限制的部份與我的使用習慣較不抵觸的環境,但一直都沒有結論。
最近分享照片時我心血來潮又找了一回,發現4shared的網路評價不錯,限制又比較符合我所想的。
除了網頁上傳下載外,它自己也有提供上傳下載的程式可用(連手機版的都有,可惜還沒有Android版)~
我試了一下還滿好用的,不過網路上對程式版使用這部份的網路教學好像沒看到,所以我就乾脆自己寫。
希望有要分享照片的朋友能學會使用,以後就不用MSN傳半天傳不到我手裡了。

以下我分成三部份來跟大家介紹這個網路硬碟的桌面程式使用方式

服務限制

在大家很開心的分享檔案之前,我建議還是要看一下免費帳號的限制,免得被砍帳號都不知道:
  • 三十天內沒登入,你就會被砍帳號與檔案。只要你沒被砍帳號,檔案都有效~
    (基本上我想分享檔案後30天內大概想要檔案的人都抓完了,所以真的被砍帳號下回要分享時再申請一次帳號就不成問題了)
  • 空間限制:每個帳號10G,上傳的一個檔案上限200MB(付費帳號就不同了)
完整內容請參考官方的使用條款

桌面程式安裝與帳號申請


到http://www.4shared.com/首頁的下載4shared 桌面程式,下載完後開使安裝

安裝過程中有出現是不是要安裝Tool bar,這個看個人,我圖上的操作是不安裝

安裝完成後啟動程式

程式剛啟動時回讓你選【我是4Shared新手】,就是要註冊一個帳號。註冊時選擇計劃【Free】就是免費帳號

或是你已經有帳號就選登錄現有帳戶。
登入成功後,會顯示使用提示,然後告訴你它有個同步用的資料夾讓你可以指定,這些看看就選跳過與結束就可以了,這看個人使用需求自己玩玩看吧。

上傳教學


上傳的時候壓縮時選一下分割檔為200Mb,這樣上傳才不會失敗。
然後在右下角的上傳區選擇要上傳的檔案(也可以點upload鈕選檔案或目錄)
選好檔案就會看到它開始上傳了
上傳完成就會出現在上面的區塊,這時想要把上傳的檔案分享給別人,只要右鍵選獲得鍊結
然後選擇下面的連結,再點複製,就會得到檔案連結,就可以把這個下載連結告訴要分享的人囉。

下載教學

(最近發現JDownloader這個工具可以很方便的下載4Shared的檔案,教學與下載文可參考[下載&教學] JDownloader 0.9.581 中文免安裝版 ~ 最強的免費空間下載器 by 海芋)
拿到別人分享的連結一打開,就會出現這個畫面。這時你有兩種下載的方式:
第一種就是選【現在下載】(這個方式要等倒數,沒耐心請直接往下看第二種方式)
就會進到一個倒數的畫面
倒數結束就會出現【現在下載檔案】可以點選下載。
第二種就是點選加到我的帳戶(如果檔案本來就是你的就沒這項,你就直接到程式介面就能下載了)
然後沒登入的話就會要你登入,登入後會看到一個網頁版的檔案管理畫面,不過我們要下載是用程式下載,所以回到桌面程式畫面。
這時如果你的檔案中沒出現剛才的檔案就右鍵選單選【Reflash】
然後就可以選想下載的檔案來下載了。
第一次下載會問你要下載到哪
這就是下載中的樣子

總結

上手後就超簡單的,當然如果不安裝桌面程式的人也可以用網頁登入管理檔案或是找免安裝版的來用

相關連結

[JBoss]Java的工作排程套件-Quartz

序言

作為一個Application Server,JBoss裡的應用程式開發起來主要都是被動的等待Client呼叫啟動。但實際應用上還是有可能需要有個程序能夠在特定時間執行某些命令,例如於午夜12點整進行資料的Reset這種工作。
在不依賴作業系統或是另外執行一支程式處裡工作的狀況,其實JBoss預設就有推薦使用的工作排程套件-Quartz。
就Quartz的功能而言,有的功能是與Java內建的Timer重複的,但它功能更多更強大,所以相對的要做一些設定才能使用。
以下我就舉幾個我用的方法來一探Quartz的設定(當然,這不見得是最好的作法)。

開發環境

JBoss設定

JBoss內建就有Quartz的套件,但版本很老舊,從網路上得到的資訊來看,可能會有一些問題存在。
因此建議的作法是把內建的套件刪除掉,換上新的版本。
  1. 刪除Jboss下common\lib\目錄的quartz.jar檔
  2. 刪除Jboss下server發佈目錄下的quartz-ra.rar,如jboss\server\default\deploy目錄的quartz-ra.rar
  3. quartz套件的壓縮檔打開,將裡面的quartz-all-1.7.3.jar檔案複製到jboss\common\lib(或jboss\server\default\lib)

Quartz設定檔

Quartz 提供了兩種不同的方式用來把排程工作存在記憶體(RAMJobStore)或資料庫(JDBCJobStore。)中。
  • RAMJobStore:是預設的方法,因為所有資料都存在記憶體中,所以速度最快,但是如果伺服器停止後,所有排程的工作都會消失
  • JDBCJobStore:透過 JDBC 把所有工作排成資訊存在資料庫中,但代價就是效能降低和設定複雜度的提高(尤其是有參數要透過JobDataMap在工作執行時使用時)。
在這邊我使用最簡單的RAMJobStore來進行工作排程。
這時會需要建立一個設定檔【quartz-service.xml】來設定工作排程套件的參數。這個檔案會放在JBoss的發佈目錄下,如jboss\server\default\deploy
<?xml version="1.0" encoding="UTF-8"?>

<server>

<mbean code="org.quartz.ee.jmx.jboss.QuartzService" name="user:service=QuartzService,name=QuartzService">
<attribute name="JndiName">Quartz</attribute>
<attribute name="StartScheduler">true</attribute>
<attribute name="Properties">
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.xaTransacted = false

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
</attribute>
</mbean>

</server>

工作類別

工作要執行的內容必須實作【org.quartz.Job】介面,如
package control;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MyJob implements Job {
static int jobs=0;
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
JobDataMap dataMap = arg0.getJobDetail().getJobDataMap();
Object data1 =dataMap.get("data1");
Object data2 =dataMap.get("data2");
System.out.println("Start MyJob");
System.out.println("data1="+data1);
System.out.println("data2="+data2);
}

}

排程工作

排程的方式有兩種,一種是設定多久執行工作一次(SimpleTrigger),一種是設定什麼時間要執行工作一次(CronTrigger)。
兩者最主要差別在於描述方式。相同的是兩者都可以設定排程啟動時間,結束時間,重複次數等設定。
  • 使用SimpleTrigger
 String groupName = "Default";  //工作群組
String jobName = "MySimpleJob"; //工作名稱
InitialContext ctx;
ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
//如果工作已排程,則刪除同樣工作群組-工作名稱的工作
if (scheduler.getJobDetail(jobName, groupName) != null) {
scheduler.deleteJob(jobName, groupName);
}
JobDetail jobDetail = new JobDetail(jobName, groupName,MyJob.class); //設定工作執行的類別為MyJob
//設定要傳給工作的參數
jobDetail.getJobDataMap().put("data1", "Job1");
jobDetail.getJobDataMap().put("data2", jobName);
SimpleTrigger simpleTrigger = new SimpleTrigger(jobName, groupName); //Trigger也會設定群組與名稱,但我不確定是有什麼功用
simpleTrigger.setRepeatCount(-1); //設定-1無限次重複,如果設為0則就只會執行一次
simpleTrigger.setRepeatInterval(15*60*1000); //每15分鐘做一次

Calendar curCal = Calendar.getInstance();
curCal.add(Calendar.MINUTE, 10);
simpleTrigger.setStartTime(curCal.getTime()); //現在時間的10分鐘後啟動工作,如果不設定的話排程開始就會執行第一次

scheduler.scheduleJob(jobDetail, simpleTrigger);
if (!scheduler.isShutdown()) {
scheduler.start();
}
  • 使用CronTrigger
 String groupName = "Default";  //工作群組
String jobName = "MyCronJob"; //工作名稱
InitialContext ctx;
ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
//如果工作已排程,則刪除同樣工作群組-工作名稱的工作
if (scheduler.getJobDetail(jobName, groupName) != null) {
scheduler.deleteJob(jobName, groupName);
}
JobDetail jobDetail = new JobDetail(jobName, groupName,MyJob.class); //設定工作執行的類別為MyJob
//設定要傳給工作的參數
jobDetail.getJobDataMap().put("data1", "Job2");
jobDetail.getJobDataMap().put("data2", jobName);
CronTrigger trigger = new CronTrigger(jobName, groupName,"0 0 0 * * ?"); //每天0點整執行
scheduler.scheduleJob(jobDetail, trigger);
if (!scheduler.isShutdown()) {
scheduler.start();
}

在應用程式第一次被呼叫時排程工作

在Java Web Application中目前我還沒找到方法能在Jboss啟動時呼叫某個function,只能想到兩種方式當有第一個人啟動這個網站中的網頁時進行第一次的初始設定。
第一種方法是在static instance建立時在被New的物件建構函式中寫要做的工作,像是下面的程式。
但這種做法最大壞處是你沒辦法餵給它關於Web的Session、ServletContext等資訊,因為他是在Web內容還沒建立起來時就產生的。
import java.util.Calendar;

import javax.naming.InitialContext;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleTrigger;

public class InitJob {
private static InitJob instance=new InitJob();
private InitJob(){
try {
String groupName = "Default"; //工作群組
String jobName = "MySimpleJob"; //工作名稱
InitialContext ctx;
ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
//如果工作已排程,則刪除同樣工作群組-工作名稱的工作
if (scheduler.getJobDetail(jobName, groupName) != null) {
scheduler.deleteJob(jobName, groupName);
}
JobDetail jobDetail = new JobDetail(jobName, groupName,MyJob.class); //設定工作執行的類別為MyJob
//設定要傳給工作的參數
jobDetail.getJobDataMap().put("data1", "Job1");
jobDetail.getJobDataMap().put("data2", jobName);
SimpleTrigger simpleTrigger = new SimpleTrigger(jobName, groupName); //Trigger也會設定群組與名稱,但我不確定是有什麼功用
simpleTrigger.setRepeatCount(-1); //設定-1無限次重複,如果設為0則就只會執行一次
simpleTrigger.setRepeatInterval(15*60*1000); //每15分鐘做一次

Calendar curCal = Calendar.getInstance();
curCal.add(Calendar.MINUTE, 10);
simpleTrigger.setStartTime(curCal.getTime()); //現在時間的10分鐘後啟動工作,如果不設定的話排程開始就會執行第一次

scheduler.scheduleJob(jobDetail, simpleTrigger);
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
第二種方法是在Session建立時,設定一個Static 布林變數來判斷是否是第一次啟動,然後在裡面執行要做的工作,像是下面的程式。但相對付出的代價就是每個人進來時都會判斷一次。
如果要用這種方法就要再專案的web.xml中增加listener標籤,如
<?xml version="1.0" encoding="UTF-8"?>
<web-app...>
...
<listener>
<listener-class>control.InitSession</listener-class>
</listener>
...
</web-app>
程式如下
package control;

import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;

public class InitSession implements HttpSessionListener {
static boolean isInited=false;
@Override
public void sessionCreated(HttpSessionEvent arg0) {
if(!isInited){
//可取得Web相關的資訊
ServletContext servletContext = arg0.getSession().getServletContext();
HttpSession session = arg0.getSession();
//工作設定
String groupName = "Default"; //工作群組
String jobName = "MyCronJob"; //工作名稱
InitialContext ctx;
ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
//如果工作已排程,則刪除同樣工作群組-工作名稱的工作
if (scheduler.getJobDetail(jobName, groupName) != null) {
scheduler.deleteJob(jobName, groupName);
}
JobDetail jobDetail = new JobDetail(jobName, groupName,MyJob.class); //設定工作執行的類別為MyJob
//設定要傳給工作的參數
jobDetail.getJobDataMap().put("data1", "Job2");
jobDetail.getJobDataMap().put("data2", jobName);
CronTrigger trigger = new CronTrigger(jobName, groupName,"0 0 0 * * ?"); //每天0點整執行
scheduler.scheduleJob(jobDetail, trigger);
if (!scheduler.isShutdown()) {
scheduler.start();
}
isInited=true;
}
}

@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
}
}

總結

以上就是在JBoss上面我使用Quartz的使用經驗,至於是否有更好的作法或是我的作法有什麼缺陷,歡迎留言告訴我,謝謝

參考資料

[程式]VB.Net2.0資料庫通用存取函式

序言

在VS2005建立VB專案(或Web網站)後,若要進行資料庫存取,我個人比較習慣將連線字串寫在設定檔app.config(或web.config)下。

不過VB專案預設是不會產生這個檔,而且在程式中若要取得連線字串的設定也要對專案的參考進行設定。

以下記錄下我做的設定,並把資料庫存取程式簡化為函式。

開發環境

  • VB.Net 2.0 (VS2005)
  • MSSQL2005 Express

專案設定

  • 建立專案後預設的專案屬性下,參考的元件如下圖:

  • 下面的程式中會用到【ConfigurationManager】這個物件來取得設定檔的連線字串,所以我們需要加入【System.Configuration】這個元件:

    點選加入,在.Net分頁下找到【System.Configuration】這個元件
  • 再來要在專案加入新項目【應用程式組態】,名稱用預設的【app.config】就可以了:

  • 編輯app.config,在【configuration】標籤內加入連線字串的設定如:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    ...
    <connectionStrings>
    <add name="MSSQLDB1"
    connectionString="Data Source=localhost;Initial Catalog=MyTestDB;Integrated Security=True"
    providerName="System.Data.SqlClient" />
    <add name="MSSQLDB2"
    connectionString="Data Source=127.0.0.1;Initial Catalog=MyTestDB;User ID=sa;Password=1234"
    providerName="System.Data.SqlClient" />
    </connectionStrings>
    ...

通用存取函式類別


Imports System.Data.SqlClient
Imports System.Configuration
Public Class DBAccessFunc
    ''' <summary>
    ''' 從ConfigurationManager中的ConnectionStrings找出Initial Catalog
    ''' </summary>
    ''' <param name="ConnName">ConnectionStrings名稱(String)</param>
    ''' <returns>回傳資料庫名稱</returns>
    ''' <remarks>從ConfigurationManager中的ConnectionStrings找出Initial Catalog</remarks>
    Public Shared Function getDBName(ByVal ConnName As String) As String
        Dim val As String = ""
        Dim ConnString As String = ConfigurationManager.ConnectionStrings(ConnName).ConnectionString
        Dim i As Integer = ConnString.IndexOf("Initial Catalog=")
        If i > -1 Then
            val = ConnString.Substring(i + "Initial Catalog=".Length)
            i = val.IndexOf(";")
            If i > -1 Then
                val = val.Substring(0, i)
            End If
        End If
        Return val
    End Function

    Public Shared Function getConnString(ByVal ConnName As String) As String
        Return ConfigurationManager.ConnectionStrings(ConnName).ConnectionString
    End Function


    Public Shared Function getConn(ByVal ConnName As String) As SqlConnection
        Return New SqlConnection(getConnString(ConnName))
    End Function
    ''' <summary>
    ''' 查詢資料庫
    ''' </summary>
    ''' <param name="cn">連線</param>
    ''' <param name="sql">查詢內容</param>
    ''' <returns>回傳查詢結果的DataTable</returns>
    ''' <remarks>查詢資料庫並回傳查詢結果的DataTable</remarks>
    Public Shared Function getTable(ByRef cn As SqlConnection, ByRef sql As String, Optional ByVal isColseConn As Boolean = True) As Data.DataTable
        Dim da As New SqlDataAdapter(sql, cn)
        Dim dt As New Data.DataTable("dt_xml")
        Try
            If cn.State = ConnectionState.Closed Then cn.Open()
            da.SelectCommand.CommandTimeout = 36000000
            da.Fill(dt)
        Catch ex As Exception
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        End Try
        If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        Return dt
    End Function

    ''' <summary>
    ''' 執行命令
    ''' </summary>
    ''' <param name="cn">連線</param>
    ''' <param name="sql">查詢內容</param>
    ''' <returns>回傳受影響的資料筆數</returns>
    ''' <remarks>執行命令並回傳受影響的資料筆數</remarks>
    Public Shared Function doCmd(ByRef cn As SqlConnection, ByRef sql As String, Optional ByRef param() As SqlParameter = Nothing, Optional ByVal isColseConn As Boolean = True) As Integer
        Dim result As Integer = 0
        Dim cmd As New SqlCommand
        Try
            cmd.Connection = cn
            cmd.CommandText = sql
            If Not param Is Nothing Then
                cmd.Parameters.AddRange(param)
            End If
            cmd.CommandTimeout = 36000000
            If cn.State = ConnectionState.Closed Then cn.Open()
            result = cmd.ExecuteNonQuery()
        Catch ex As Exception
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        Finally
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        End Try
        Return result
    End Function


    ''' <summary>
    ''' 取得單一資料
    ''' </summary>
    ''' <param name="cn">連線</param>
    ''' <param name="sql">查詢內容</param>
    ''' <returns>回傳受影響的資料筆數</returns>
    ''' <remarks>執行命令並回傳受影響的資料筆數</remarks>
    Public Shared Function doScalar(ByRef cn As SqlConnection, ByRef sql As String, Optional ByRef param() As SqlParameter = Nothing, Optional ByVal isColseConn As Boolean = True) As Object
        Dim result As Object = Nothing
        Dim cmd As New SqlCommand
        Try
            cmd.Connection = cn
            cmd.CommandText = sql
            If Not param Is Nothing Then
                cmd.Parameters.AddRange(param)
            End If
            cmd.CommandTimeout = 36000000
            If cn.State = ConnectionState.Closed Then cn.Open()
            result = cmd.ExecuteScalar()
        Catch ex As Exception
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        Finally
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        End Try
        Return result
    End Function

    Public Function executeStoredProcedure(ByRef cn As SqlConnection, ByVal procedure As String, Optional ByRef param As SqlParameter() = Nothing, Optional ByRef output As SqlParameter() = Nothing, Optional ByVal isColseConn As Boolean = True) As Integer
        Dim result As Integer = 0
        Dim cmd As New SqlCommand(procedure, cn)
        Try

            cmd.CommandText = procedure
            cmd.CommandTimeout = 36000000
            cmd.CommandType = CommandType.StoredProcedure
            If Not param Is Nothing Then cmd.Parameters.AddRange(param)
            If Not output Is Nothing Then
                For Each o As SqlParameter In output
                    o.Direction = ParameterDirection.Output
                Next
                cmd.Parameters.AddRange(output)
            End If

            '開啟資料庫連線
            If cn.State = ConnectionState.Closed Then cn.Open()
            '設定變數儲存受影響資料列
            result = cmd.ExecuteNonQuery()
        Catch ex As Exception
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        Finally
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        End Try
        Return result
    End Function
End Class


使用範例程式

Dim connStr1 As String = DBGenFunc.getConnStr("MSSQLDB1")
Dim sourceTable As String() = {"[" & DBGenFunc.getDBName("MSSQLDB1") & "].[dbo].[" & "MyTestTab" & "]", _
"[" & DBGenFunc.getDBName("MSSQLDB1") & "].[dbo].[" & "MyContentTab" & "]"}
Dim param() As SqlClient.SqlParameter = {New SqlClient.SqlParameter("P0", SqlDbType.VarChar)}
Dim sql As String

Dim title As String

Console.WriteLine("doCmdScalar Start:")
sql = "SELECT Title" & vbCrLf & _
" FROM " & sourceTable(0) & "" & vbCrLf & _
" WHERE SN=@P0"
param(0).Value = 1
title = DBGenFunc.doCmdScalar(connStr1, sql, param)
Console.WriteLine("doCmdScalar" & vbTab & title)

Console.WriteLine("getTable Start:")
sql = "SELECT Title" & vbCrLf & _
" FROM " & sourceTable(0) & "" & vbCrLf
Dim dt As DataTable = DBGenFunc.getTable(connStr1, sql)
For Each r As DataRow In dt.Rows
title = r.Item(0)
Console.WriteLine("getTable" & vbTab & title)
Next

Console.WriteLine("getTableToArray Start:")
Dim data As String() = DBGenFunc.dataTableToArray(Of String)(dt, 0)
For Each r As String In data
title = r
Console.WriteLine("getTable" & vbTab & title)
Next

Console.WriteLine("doCmd Start:")
sql = "INSERT INTO " & sourceTable(0) & "" & vbCrLf & _
"VALUES(@P0,@P1)"
param = New SqlClient.SqlParameter() {New SqlClient.SqlParameter("P0", SqlDbType.VarChar), _
New SqlClient.SqlParameter("P1", SqlDbType.VarChar)}
param(0).Value = "TNew"
param(1).Value = "SNew"
title = DBGenFunc.doCmd(connStr1, sql, param)
Console.WriteLine("doCmd" & vbTab & title)

Console.WriteLine("getReader Start:")
sql = "SELECT Title, Subject" & vbCrLf & _
" FROM " & sourceTable(0) & "" & vbCrLf
Dim dr As SqlClient.SqlDataReader = DBGenFunc.getReader(connStr1, sql)
While dr.Read()
title = dr.Item(0)
Console.WriteLine("getReader" & vbTab & title & vbTab & dr.Item(1))
End While
DBGenFunc.closeReader()

執行結果

doCmdScalar Start:
doCmdScalar T1
getTable Start:
getTable T1
getTable T2
getTable T3
getTable TNew
getTableToArray Start:
getTable T1
getTable T2
getTable T3
getTable TNew
doCmd Start:
doCmd 1
getReader Start:
getReader T1 S1
getReader T2 S2
getReader T3 S3
getReader TNew SNew
getReader TNew SNew

[教學]設定MSN防毒為小紅傘

序言

不想廢話(這篇應該是目前我在這個Blog最短的一篇文章),總之這樣設定MSN(Live Messenger)傳檔案時就會用小紅傘(Avira AntiVir)掃毒。

步驟

  1. 於MSN的【工具】→【選項】→【檔案傳輸】勾選【使用下列軟體進行病毒掃描】
  2. 在下面的路徑欄位填上:
    "C:\Program Files\AntiVir PersonalEdition Classic\avscan.exe" /GUIMODE=2 /PATH=%FILE%

[教學]重灌/換主機板超好用技術-MergeIDE

序言

雖然廢話一堆的教學文章是不行的~不過我還是習慣開場說說我研究這個免重灌的原因~

就是當每天都有修不完的電腦~而且還每台都要做差不多的設定與軟體安裝後~

我就開始想找出可以不用每次都重灌的方法~

最終試的結果就是用我下面談的MergeIDE來設定囉~

當然,這個方法也可以用在換電腦時,不過我在下面第一步就回提到換電腦時用這個方法不一定會成功的原因。

工作大綱

  1. 挑電腦來安裝Windows
  2. 將Windows該裝軟體該設定的都弄好
  3. 刪掉不必要的檔案(非必要)
  4. 進裝置管理員變更電腦與匯流排驅動為標準,並刪除不必要裝置
  5. 執行MergeIDE,並覆蓋4個IDE硬體驅動檔
  6. 關機後即可製作Ghost檔(非必要)
  7. 在新電腦開機後,更新第一個標準電腦的驅動再重新開機
  8. 安裝新電腦的驅動
  9. 關機後再製作Ghost檔(非必要)

1.挑電腦來安裝Windows

這時候又要廢話一下了~為什麼要挑電腦勒?

因為根據我手邊供我試驗的很多很多台電腦的使用經驗,

A主機板所安裝的Windows使用MergeIDE法可使轉移到B主機板運作時,

B主機板所安裝的Windows卻不一定能以同樣方式轉移到A主機板~

因此,挑主機板就十分運氣了~

以我為例,我目前挑到相容性最高的主機是HP Compaq dc5750的套裝主機,它內建的是AMD64位元的CPU~

但我建議如果沒有很多主機可以試,也可以試試使用VMWare建立雙CPU的虛擬主機來裝Windows,效果可能也不錯~

2.將Windows該裝軟體該設定的都弄好

這不用說,當然就是裝上各電腦你需要的軟體與設定~

也可以把所有的更新更新完(手動下載更新檔可參考 下載Windows更新檔的工具by EcStart PHP 技術討論論壇)

3.刪掉不必要的檔案(非必要)

因為要減小Ghost後的大小,可以刪除些非必要的檔案:

  • 到【控制台】→【系統】→【系統還原】把系統還原關閉。
  • 清除系統文件保護暫存檔,以命令提示字元執行【sfc.exe /purgecache】

4.進裝置管理員變更電腦與匯流排驅動為標準,並刪除不必要裝置

  • 【開始】→【執行】→輸入【devmgmt.msc】/或至【控制台】→【系統管理工具】→【電腦管理】,開啟【裝置管理員】
  • 展開【IDE ATA/ATAPI控制器】分類,如果裡面的IDE控制器不是【標準的雙通道 PCI IDE控制器】,請更新驅動為標準的雙通道 PCI IDE控制器。以右鍵點選IDE控制器的【更新驅動程式】,在打開的【硬體更新精靈】裡選【從列表或指定位置安裝(進階)】選項,並選【不要搜索,我要自己選擇要安裝的驅動程式】,然後選【雙通道 PCI IDE控制器】。再選【否】不重開機。
  • 展開【電腦】分類,以右鍵點選ACPI選【更新驅動程式】,在打開的【硬體更新精靈】裡選【從列表或指定位置安裝(進階)】選項,並選【不要搜索,我要自己選擇要安裝的驅動程式】,然後選【標準電腦】(Standard PC)
  • 同上述方法將【處理器】分類下的CPU改為【處理器】
  • 刪除其他普通驅動程式,如網絡介面卡,滑鼠右鍵單擊其下的網路設備名稱,在彈出菜單上單擊【解除安裝】選項,再用類似的方法卸載通用序列匯流排控制器、音效視訊遊戲控制器、顯示卡、音效卡等設備驅動程式。這裡要注意的是,如果系統提示需要重新啟動,一定【不要】重啟機器

5.執行MergeIDE,並覆蓋4個IDE硬體驅動檔

從將 Windows XP 系統磁片移到另一部電腦之後,收到 Stop 0x0000007B 錯誤(By Microsoft技術支援服務)

這篇文章就可以看到MergeIDE檔的製作方式,網路上也有人用批次檔寫說可以直接將windows裡面的4個IDE硬體驅動檔複製出來用的方法。

而我這邊比較偏好直接用下載後的4個IDE硬體驅動檔來覆蓋,因為有的Windows會找不到這四個檔的原始檔。

我將所有需要的檔案與解壓縮路徑預設好,只要下載Winxpsys執行就可以了。

6.關機後即可製作硬碟映象檔(非必要)

這個映像檔理論上在新電腦就可以用了,不過如同第1部所言,這要看運氣。

7.在新電腦開機後,更新第一個標準電腦的驅動再重新開機

開機後他會開始裝各硬體的驅動程時,如果中間有跳出要求驅動程式的視窗,直接取消不用理他~

因為下一步驟重開後他還是會再重新裝一次驅動程式。

  • 【開始】→【執行】→輸入【devmgmt.msc】,開啟 裝置管理員
  • 展開【電腦】分類,會有兩個標準電腦。以右鍵點選第一個標準電腦,選【更新驅動程式】,依直按下一步讓它安裝適合這台電腦的ACPI
  • 重新開機

8.安裝新電腦的驅動

到裝置管理員移除第二個標準電腦,並且安裝所有這台電腦的驅動後,就完成移機了。

9.關機後再製作硬碟映象檔(非必要)

為什麼之前做過硬碟映象,現在又做一次?

根據我的試驗,這時候的作業系統就變成拿到別台還是能開機來用,所以感覺很像能到處使用,不過我還沒能完整驗證。

所以大家有興趣可以直接拿這個版本的映像檔來玩玩看,就可以再少掉每次到新電腦還要作第7步的動作了。

結論

如前面所言,這是我試過n台電腦後的結果,歡迎大家告訴我更好的做法~

我想這個技術對好人卡收很多的人也有用~哈哈~

相關連結

這裡是關於技術的手札~

也歡迎大家到

倫與貓的足跡

或

到噗浪來

關心一下我唷!
by 倫
 
Copyright 2009 倫倫3號Beta-Log All rights reserved.
Blogger Templates created by Deluxe Templates
Wordpress Theme by EZwpthemes