星期三, 11月 26, 2014

星期二, 11月 25, 2014

[Win] iSCSI 目標伺服器 - Initiator

以下為利用 iSCSI 啟動器連接 iSCSI 目標筆記,該伺服器名稱為 iSCSIInitiator

Step 1:iSCSI  啟動器在 Windows Vista 和 Windows Server 2012 之後版本變成內鍵功能

[Win] iSCSI 目標伺服器 -Initiator-1

Step 2:執行 iSCSI 啟動器且該服務未啟動時,會有下列訊息出現

[Win] iSCSI 目標伺服器 -Initiator-2

Step 3:建立目標 192.168.3.1 並按 "快速連線" 按鈕

[Win] iSCSI 目標伺服器 -Initiator-3

Step 4:會顯示 iSCSI 目標的 IQN 並顯示登入成功,假如快速連線沒有找到 iSCSI 目標,請檢查 iSCSI 目標內的存取伺服器,是否有把嘗試存取 iSCSI 目標的伺服器加入存取清單內

[Win] iSCSI 目標伺服器 -Initiator-4

Step 5:重覆執行新增目標,把 192.168.3.2 也加入目標中,然後就可以在 探索 Tag 中看見,下圖目標入口資訊

[Win] iSCSI 目標伺服器 -Initiator-5

Step 6:到 iSCSI 啟動器內的 "磁碟區和裝置" tag,按下"自動設定",這樣就可以把 iSCSI Target 內的虛擬硬碟抓進來,因為只在 Target 內建立一顆虛擬硬碟,所以磁碟清單內只有一筆資料

[Win] iSCSI 目標伺服器 -Initiator-7

Step 7:到電腦管理中就可以看見該伺服器內多一顆硬碟,把它掛載,就可以正常使用該 iSCSI 目標

[Win] iSCSI 目標伺服器 -Initiator-6

星期一, 11月 24, 2014

[C#] 改變 GroupBox 內 Label 的背景顏色

技術論壇問題
groupBox 裡 放幾個label 想改變 label 的背景顏色
以往尋找物件都是利用 Controls.Find() 和 foreach 搭配 ofType<控件類型> 來找出控件並進行處理,在這個討論中發現,把欲尋找控件加入 List<控件類型> 中,再掃 List <控件類型>,也是一種處理方式,檢單筆記一下
namespace GroupLabel
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cboSelect.DropDownStyle = ComboBoxStyle.DropDownList;
            for (int i = 1; i <= 10; i++)
            {
                string item = string.Format("Label{0}", i);
                cboSelect.Items.Add(item);
            }

            btnOdd.Click += btnClick;
            btnEven.Click += btnClick;
        }

        private void cboSelect_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 利用 Control.Find 來尋找 Label 控件
            string target = cboSelect.SelectedItem.ToString();
            if (string.IsNullOrEmpty(target)) return;

            Control[] labels = gbLabel.Controls.Find(target, false);
            if (labels.Length == 0) return;
            if (!(labels[0] is Label)) return;

            Label lbl = labels[0] as Label;
            if (lbl == null) return;

            colorReset();
            lbl.ForeColor = Color.White;
            lbl.BackColor = Color.Red;
        }

        private void colorReset()
        {
            // 掃 gpLabel 內的 Label 控件
            foreach (Label lbl in gbLabel.Controls.OfType<Label>())
            {
                lbl.BackColor = SystemColors.Control;
                lbl.ForeColor = Color.Black;
            }
        }

        private void btnClick(object sender, EventArgs e)
        {
            // 把欲變色的 Label 控件,加入 List<Label> 中,掃 List<Label> 來進行變色
            string btnName = ((Button)sender).Name;

            List<Label> lstLabels = new List<Label>();
            if (btnName == "btnOdd")
            {
                lstLabels.Add(label1);
                lstLabels.Add(label3);
                lstLabels.Add(label5);
                lstLabels.Add(label7);
                lstLabels.Add(label9);
            }
            else
            {
                // btnName == "btnEven"

                lstLabels.Add(label2);
                lstLabels.Add(label4);
                lstLabels.Add(label6);
                lstLabels.Add(label8);
                lstLabels.Add(label10);
            }

            colorReset();
            foreach (Label lbl in lstLabels)
            {
                lbl.ForeColor = Color.White ;
                lbl.BackColor = Color.Red;
            }
        }
    }
}
[C#] 改變 GroupBox 內 Label 的背景顏色

星期五, 11月 21, 2014

[SQL] Sequence

MSDN Sequence 說明
建立順序物件,並指定其屬性。 順序是使用者定義之結構描述繫結的物件,該物件會根據建立順序所使用的規格產生數值序列。 數值序列會在定義的間隔依照遞增或遞減順序來產生,而且在用完時可設定為重新啟動 (循環)。 順序不會與特定資料表產生關聯,與識別欄位不同。 應用程式會參考順序物件,以擷取它的下一個值。 順序與資料表之間的關聯性是由應用程式所控制。 使用者應用程式可以參考順序物件,並協調跨越多個資料列和資料表的值。
  • 建立 Sequence 語法
[SQL] Sequence - 6
  • 預設值 Sequence
IF EXISTS(SELECT 1 FROM sys.sequences WHERE name = 'DefaultSeq')
    DROP SEQUENCE dbo.DefaultSeq

CREATE SEQUENCE dbo.DefaultSeq
[SQL] Sequence - 1
  • Sequence 物件設定值查詢語法
SELECT 
    S.Name AS N'順序物件',
    S.start_value AS N'起始值',
    S.increment AS N'遞增值',
    S.current_value AS N'目前值',
    T.name AS N'資料類型',
    S.minimum_value AS N'最小值',
    S.maximum_value AS N'最大值',
    S.is_cycling AS N'循環',
    S.is_cached AS N'快取',
    S.cache_size AS N'快取大小',
    S.create_date AS N'建立日期',
    S.modify_date AS N'修改日期',
    S.cache_size AS N'快取值'
FROM sys.sequences AS S 
    JOIN sys.types AS T ON S.system_type_id = T.system_type_id
[SQL] Sequence - 8

星期二, 11月 18, 2014

[Win] iSCSI 目標伺服器 - Target

以下為建立 iSCSI 目標筆記,該伺服器名稱為 iSCSITarget

Step 1:建立 "iSCSI 目標伺服器" 伺服器角色

[Win] iSCSI 目標伺服器 -Target-1

Step2:伺服器管理員 => 檔案和存放服務 => iSCSI => 工作 => 新增 iSCSI 虛擬磁碟

[Win] iSCSI 目標伺服器 -Target-2


星期一, 11月 17, 2014

[C#] 檔案系統監視

論壇問題上看見這個 FileSystemWatcher 這個功能,趕快找資料來了解並筆記

官方文件 - FileSystemWatcher 類別 備註說明
Windows 作業系統會在所建立的緩衝區中通知您檔案變更的元件 FileSystemWatcher 。 如果短時間內有許多變更,緩衝區可能會溢位。 這會導致元件無法追蹤目錄中的變更,而且只會提供總通知。 使用屬性來增加緩衝區的大小 InternalBufferSize 會很昂貴,因為它來自無法交換至磁片的非分頁式記憶體,因此請將緩衝區保持在夠大的小,而不會遺漏任何檔案變更事件。 若要避免緩衝區溢位,請使用 NotifyFilter 和 IncludeSubdirectories 屬性,讓您可以篩選掉不必要的變更通知。
Code 
using System;
using System.IO;
using System.Windows.Forms;

namespace FileMonitor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txtLog.Multiline = true;
            txtLog.Dock = DockStyle.Bottom;

            // 預設監視資料夾
            txtPath.Text = @"D:\WatchDemo";

            // 檔案篩選選項
            cboExtension.Items.Add("");
            cboExtension.Items.Add("*.txt");
            cboExtension.Items.Add("*.jpg");
            cboExtension.Items.Add("*.docx");
            cboExtension.Items.Add("*.xlsx");

            // 預設篩選的副檔名
            cboExtension.Text = "*.txt";
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();

            // 預設開啟位置為使用者桌面
            fbd.RootFolder = Environment.SpecialFolder.Desktop;
            if (fbd.ShowDialog() != DialogResult.OK || string.IsNullOrEmpty(fbd.SelectedPath))
                return;

            txtPath.Text = fbd.SelectedPath;
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            string path = txtPath.Text;
            if (string.IsNullOrEmpty(path))
                return;

            FileSystemWatcher fsw = new FileSystemWatcher();

            //設定監視資料夾
            fsw.Path = path;

            // 是否包含子目錄,預設為 true
            fsw.IncludeSubdirectories = true;

            // 設定篩選條件
            string extension = cboExtension.Text;
            if (!string.IsNullOrEmpty(extension))
                fsw.Filter = extension;

            // 設定監視檔案變化類型
            fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite;

            // FileSystemWatcher 偵測事件是否啟動,預設為 true
            fsw.EnableRaisingEvents = true;

            // 事件觸發時,藉由 delegate 引用 WatchMessage 方法
            fsw.Deleted += WatchMessage;
            fsw.Changed += WatchMessage;
            fsw.Created += WatchMessage;
            fsw.Renamed += WatchMessage;
        }

        private void WatchMessage(object sender, FileSystemEventArgs e)
        {
            string message = $"檔案 {e.FullPath} 被 {e.ChangeType}";
            txtLog.Text += message + Environment.NewLine;
        }

    }
}

星期三, 11月 12, 2014

[HyperV] VM 上新增虛擬硬碟

準備練習 iSCSI 目標伺服器時,想在 Target Server 上再多掛上一顆硬碟來使用,下面為筆記紀錄

在 Hyper-V 管理員內,選擇要新增虛擬硬碟的 VM(iSCSCTarget)=> IDE 控制器 0 => 硬碟 => 新增

[HyperV] VM 上新增虛擬硬碟-0

在該 VM IDE 控制器 0 清單內可以看見多出一顆硬碟 => 新增虛擬硬碟

[HyperV] VM 上新增虛擬硬碟-1


星期二, 11月 11, 2014

[Win] iSCSI 目標伺服器

Windows Server 2012 R2 伺服器資料安全管理 學習時,老師有 Demo iSCSI 目標伺服器這個主題,自己找些資料來了解並時作練習一下
理解這些內容,就可以完成 iSCSI Target + MPOI + 容錯功能,以下為自己練習環境的簡易說明
伺服器名稱網路卡 IP 位置
iSCSITarget192.168.3.1、192.168.3.2
iSCSIInitiator192.168.3.3、192.168.3.4

星期一, 11月 10, 2014

[C#] 拖放應用 - ListBox

在論壇上看見這篇文章 如何提供視覺 C# 應用程式中的檔案拖放功能,才想到之前練習時,並沒有真的了解 DragEnter 內的 Code,代表甚麼意義,趁這個機會了解一下,並延伸這篇文章,拖曳物件假如是資料夾,必須把資料夾內的檔案也列出
using System.IO;

namespace DragDropList
{
    public partial class DragDropList : Form
    {
        public DragDropList()
        {
            InitializeComponent();
        }

        private void DragDropList_Load(object sender, EventArgs e)
        {
            listBox.AllowDrop = true;
            listBox.Dock = DockStyle.Fill;
        }

        private void listBox_DragEnter(object sender, DragEventArgs e)
        {
            // 判斷物件是否可以拖曳進入控件,EX:垃圾桶無法拖曳進入控件,
            // 拖曳過程中可以在控件上透過圖示來顯示該物件是否可以進行拖曳
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                // 控件上會出現 + 圖示,DragDrop 才會被觸發
                e.Effect = DragDropEffects.All;
            else
                // 控件上會出現禁止圖示,DragDrop 不會被觸發
                e.Effect = DragDropEffects.None;
        }

        private void listBox_DragDrop(object sender, DragEventArgs e)
        {
            // 避免重覆操作,無法正確顯示結果
            listBox.Items.Clear();
            // GetData() 回傳 string[],內容為物件路徑,允許使用者一次拖曳多個物件
            string[] entriesPath = (string[])e.Data.GetData(DataFormats.FileDrop,false) ;
            foreach (string entryPath in entriesPath)
            {
                listBox.Items.Add(entryPath);
                dirFiles(entryPath);
            }   
        }

        private void dirFiles(string _entryPath)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(_entryPath);
            if (dirInfo.Exists == false) return;

            // DirectoryInfo.GetFileSystemInfos() 會回傳 Directory 和 File 兩種類型檔案,
            // 相當於執行 DirectoryInfo.GetFiles 和 DirectoryInfo.GetDirectories
            foreach (FileSystemInfo info in dirInfo.GetFileSystemInfos())
            {
                listBox.Items.Add(info.FullName);
                dirFiles(info.FullName);
            }
        }
    }
}
[C#] 拖放應用 - ListBox

星期五, 11月 07, 2014

[SQL] 利用 sqlcmd 來執行 T-SQL script

利用 sqlcmd 來執行 TSQL script,這個方法最廣泛的應用,莫過於在 SQL Express 排程備份資料庫
  • 遠端連線
要利用 sqlcmd 連接 SQL Server instance,必須先開啟 Express 版本的遠端連線(預設關閉)
  • T-SQL Script
在 Script 內下 T-SQL 語法來進行資料庫備份、交易紀錄備份,並設定好備份檔案名稱
DECLARE @date char(8) = CONVERT(char(8),getdate(),112)
DECLARE @bakpath varchar(100) = CONCAT('D:\AdventureWorks2012-',@date,'.bak')
BACKUP DATABASE [AdventureWorks2012] TO DISK = @bakpath
  • sqlcmd
參數說明:
  1. -S:指定要連接的 SQL Server 執行個體
  2. -i:識別包含 SQL 陳述式或預存程序的批次之檔案
在命令提示字元中測試,輸入
sqlcmd -S win7-jengting\sql2012 -i C:\TSQL.sql
執行畫面如下

[SQL] 利用 sqlcmd 來執行 T-SQL script-1
  • Windows 排程
新增 txt 檔案,內容為上述 sqlcmd 執行 TSQL 語法,輸入後把副檔名的 txt 改為 bat 檔案,並在 Windows 上設定排程來執行該 bat 檔案,重要步驟如下(下圖為 Win7 排程設定畫面)

Windows 7 工作排程 => 新增工作 => 一般 tag => 輸入排程名稱

[SQL] 利用 sqlcmd 來執行 T-SQL script-2

觸發程序 tag => 新增 button (觸發程序就是排程時間設定)

[SQL] 利用 sqlcmd 來執行 T-SQL script-3

動作 tag => 新增 button => 程式或指令碼,請選擇之前建立的 TSQLbat 檔案

[SQL] 利用 sqlcmd 來執行 T-SQL script-4

手動執行就可以看見備份出來的 bat 檔案

[SQL] 利用 sqlcmd 來執行 T-SQL script-5

星期三, 11月 05, 2014

[Win] 重覆資料刪除

Windows Server 2012 R2 伺服器資料安全管理 學習時,老師有 Demo 重覆資料刪除這個主題,自己找些資料來了解並時作練習一下

Step 1 :新增 "重覆檔案刪除" 伺服器角色

[Win] 重覆刪除資料-1

Step 2:磁碟區 => 磁碟 => 選擇磁碟區 => 滑鼠右鍵 => 設定重覆資料刪除

[Win] 重覆刪除資料-2

Step 3:
  • 重覆資料刪
    1. 一般用途的檔案伺服器:就ㄧ般用途,^_^''
    2. Virtual DeskTop Infrastructure(VDI)伺服器:HyperV 用,重覆刪除資料比率會比一般用途更高
  • 可以設定排除刪除的副檔名
  • 排除設定重覆刪除磁碟內的資料夾
  • 設定排程:重覆資料刪除並不是檔案一放進磁碟內就會判斷是否重覆,必須透過排程定期定時去檢查並刪除資料
[Win] 重覆刪除資料-3

此為排程設定畫面

[Win] 重覆刪除資料-4

 Step 4:設定完成後,可以在工作排程中看見重覆資料刪除排程

[Win] 重覆刪除資料-5

Step 5:檢查該磁碟區可以看見重覆刪除相關資訊

[Win] 重覆刪除資料-6

星期一, 11月 03, 2014

[C#] FlowLayoutPanel

之前練習動態物件加入 container 時,最令人討厭的,莫過於要計算控件位置,現在才發現 Winform 有 FlowLayoutPanel 控件可以解決計算位置這個問題,這篇就利用 FlowLayoutPanel 來作每 5 個控件一欄的練習,並把 CheckedChanged 事件進行註冊,當點選 CheckBox 時,必須顯示現在勾選哪一個 CheckBox

FlowLayoutPanel MSDN 說明
FlowLayoutPanel 控制項會以水平或垂直流向來排列它的內容。 其內容可以從某一資料列換行至下一個資料列,或從某一資料行換行至下一個資料行。 此外,也可裁剪該內容而不換行。
namespace FlowLayoutPanelDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 使用者輸入預設值
            numInput.Value = 10;
            // FlowDirection 預設值為 LedtToRight 
            flowDemo.FlowDirection = FlowDirection.TopDown;
            // WrapContents 預設值為 true
            flowDemo.WrapContents = true;
            // 設定 FlowLayoutPanel 具有 Scroll 功能
            flowDemo.AutoScroll = true;
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            decimal count = numInput.Value;
            if (count <= 0) return;

            // 避免重覆操作,無法顯示正確結果
            flowDemo.Controls.Clear();

            for (int i = 1; i <= count; i++)
            {
                CheckBox cb = new CheckBox();
                cb.Name = "cb" + i;
                cb.Text = "cb" + i;
                cb.CheckedChanged += cb_CheckedChanged;

                // 預設是碰到 FlowLayoutPanel Border 時會自動折行
                // 在這改用每 5 個控件就進行折行
                if (i % 5 == 0)
                    flowDemo.SetFlowBreak(cb, true);

                flowDemo.Controls.Add(cb);
            }
        }

        void cb_CheckedChanged(object sender, EventArgs e)
        {
            lblMessage.Text = string.Format("{0} 正被勾選", ((CheckBox)sender).Name);
        }
    }
}
[C#] FlowLayoutPanel