2014年7月3日 星期四

VB.NET 登錄檔Regedit本機與遠端,寫入與讀取

        在自動化產業上,單站Tektime的處理時間越短,相對的產能也就會越高 ; 在軟體方面,有時候為了達到有充裕的效能,或者節省成本的考量,常常會出現一台電腦(主機)對多台電腦(子機)的搭配使用,以達效率的提升.

        這樣的模式下,主機對子機間,或子機對子機間的溝通,就顯得非常重要,一般我們常見的溝通模式可能是透過讀取.txt或.ini,或者用WinSocket的傳遞方式,取得相關資訊來判斷該做什麼動作,這些方式都可以達到一對多的控制,但考慮穩定度與處理時間,這邊介紹一個通訊的方法,透過Regedit的模式來達到一樣的效果,且方法簡單,穩定,也快速.

本文的環境設定為 Win7 64bit
a.確保多台電腦 連接網路,且網域要一致,IP不重複
b.確保多台電腦 同群組
c.確保多台電腦 控制台->系統及安全性->系統管理工具->服務 裡面的Remote Registry 已啟動
d.確保多台電腦 防火牆關閉

主機端 :

開啟 regedit.exe ,在資料夾圖示上可按右鍵新增,請建立好
HKEY_CURRENT_USER\Software\ATMA\ATAE57 機碼

ATAE57 機碼內新增一個Is_Alive(Type:DWORD)的子機碼,數值暫設為99(10進位)

依據電腦身分設定ATAE57 機碼的使用權限,在資料夾圖示上方按右鍵便可看到



到這邊為止,基本上已經建立好通訊的目錄了,接著介紹如何透過程式讀取與寫入

假設.主機IP = 192.168.1.99 / 子機IP = 192.168.1.1

主機對主機 讀取語法 GetValue承接讀取的值
Dim RegistryKey As Microsoft.Win32.RegistryKey
Dim GetValue As String
RegistryKey = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, Microsoft.Win32.RegistryView.Registry64).OpenSubKey("HKEY_CURRENT_USER\Software\ATMA\ATAE57", False)
GetValue = RegistryKey.GetValue("Is_Alive", "")
RegistryKey.Close()

主機對主機 寫入語法 將值改為22
Dim RegistryKey As Microsoft.Win32.RegistryKey
RegistryKey = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, Microsoft.Win32.RegistryView.Registry64).OpenSubKey("HKEY_CURRENT_USER\Software\ATMA\ATAE57", True)
RegistryKey.SetValue("Is_Alive", "22")
RegistryKey.Close()

子機對主機 讀取語法 GetValue承接讀取的值
Dim RegistryKey As Microsoft.Win32.RegistryKey
Dim GetValue As String
RegistryKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, "192.168.1.99", Microsoft.Win32.RegistryView.Registry64).OpenSubKey("HKEY_CURRENT_USER\Software\ATMA\ATAE57", False)
GetValue = RegistryKey.GetValue("Is_Alive", "")
RegistryKey.Close()

子機對主機 寫入語法 將值改為33
Dim RegistryKey As Microsoft.Win32.RegistryKey
RegistryKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, "192.168.1.99", Microsoft.Win32.RegistryView.Registry64).OpenSubKey("HKEY_CURRENT_USER\Software\ATMA\ATAE57", True)
RegistryKey.SetValue("Is_Alive", "33")
RegistryKey.Close()

以上,可以同時與regedit.ext(不會自動更新 需要按F5)搭配確認是否讀取與寫入無誤!!

VB.NET 實現UI介面語言切換功能

一套完整的軟體產品,有可能因為客戶的不同,而需要切換UI介面的語言顯示功能;要達到這樣的功能,其實有許多種方法可以達成,如..直接寫死再程式碼,或者透過文字檔來搭配等,但就管理與擴充面而言,VB.NET其實有提供ComponentResourceManager的方式來達到這樣的功能,以下就開始介紹如何達到UI介面語言切換功能!

Step 1.
開啟VB.NET -> 檔案 -> 新增專案 -> 選擇Visual Basic -> 選擇Windows Form 應用程式 -> 按下確定




Step 2.
專案內新增兩個Form(Form1 與 Form2)


Setp 3.
點選Form1 -> 顯示屬性 -> 找到Language欄位 -> 選擇英文
Form2也一樣如法炮製
Step 4.
接著進行編輯Form1與Form2內,各元件屬性的text欄位

此時 方案總管點選上方的"顯示所有檔案"圖示,並展開Form1.vb與Form2.vb
會發現各多了一個.en-US.resx的檔案


Step 5.
點開.resx後會看到剛剛對各元件編輯的列表

Step 6.
點選Form1 -> 顯示屬性 -> 找到Language欄位 -> 選擇中文 -> 重複Step 4 ~ 5




Step 7.
將Form1中用來更換語言的Button,其屬性的Name改為Btn_Main,此Button也為觸發主要按鈕

Step 9.
使用方式主要為修改與更新

語法使用如下:

設定要顯示的語言

System.Threading.Thread.CurrentThread.CurrentUICulture = New Globalization.CultureInfo("en-US")

更新表格元件內容

_C_UILanguage._Main(Me)_C_UILanguage._Main(Form2)

其中紅色字樣部分的地方,可參考方案總管內,各.resx檔名來填入,以本文為例,可填en-US 或者 zh-TW

而更新表格元件,已被我包到Class裡面,可以直接使用,如想更了解,下列貼上完整的程式碼,可供參考!!

執行結果如下





完整程式碼範例:


類別
Imports System
Imports System.ComponentModel
Imports System.Windows.Forms

Public Class C_UILanguage

    Dim CRM As System.ComponentModel.ComponentResourceManager

    Public Sub _Main(ByVal _Form As Windows.Forms.Form)

        '檢查引數
        If _Form Is Nothing Then
            _Form.Text = "Form"
            Throw New ArgumentNullException(_Form.Text)
        End If

        CRM = Nothing

        '切換介面顯示的語言
        Try
            CRM = New ComponentResourceManager(_Form.GetType)
            For Each Control As Control In _Form.Controls
                Control.Text = "Control"
                _Control_Resource(Control, CRM)
            Next
        Finally
            CRM = Nothing
        End Try

    End Sub

    Private Sub _Control_Resource(ByRef _Control As Control, ByRef _CRM As ComponentResourceManager)

        '檢查引數
        If _Control Is Nothing Then
            Throw New ArgumentNullException("Control")
        End If
        If _CRM Is Nothing Then
            Throw New ArgumentNullException("CRM")
        End If

        _CRM.ApplyResources(_Control, _Control.Name)

        If TypeOf _Control Is MenuStrip Then
            Dim MS As MenuStrip = CType(_Control, System.Windows.Forms.MenuStrip)
            For Each TSI As ToolStripItem In MS.Items
                _Strip_Resource(TSI, _CRM)
            Next
        ElseIf TypeOf _Control Is ToolStrip Then
            Dim TS As ToolStrip = CType(_Control, ToolStrip)
            For Each TSI As ToolStripItem In TS.Items
                _Strip_Resource(TSI, _CRM)
            Next
        ElseIf _Control.Controls.Count > 0 Then
            For Each Control As Control In _Control.Controls
                _Control_Resource(Control, _CRM)
            Next
        End If
    End Sub

    Private Sub _Strip_Resource(ByRef _TSI As ToolStripItem, ByRef _CRM As ComponentResourceManager)

        '檢查引數
        If _TSI Is Nothing Then
            Throw New ArgumentNullException("TSI")
        End If

        If _CRM Is Nothing Then
            Throw New ArgumentNullException("CRM")
        End If

        _CRM.ApplyResources(_TSI, _TSI.Name)

        If TypeOf _TSI Is ToolStripMenuItem Then
            Dim TSM As ToolStripMenuItem = CType(_TSI, ToolStripMenuItem)
            For Each TS As ToolStripItem In TSM.DropDownItems
                _Strip_Resource(TS, _CRM)
            Next
        End If

    End Sub

End Class

主程式
Public Class Form1

    Dim _C_UILanguage As New C_UILanguage

    Private Sub Btn_Main_Click(sender As Object, e As EventArgs) Handles Btn_Main.Click

        If Btn_Main.Text = "English" Then

            System.Threading.Thread.CurrentThread.CurrentUICulture = New Globalization.CultureInfo("zh-TW")
            _C_UILanguage._Main(Me)
            _C_UILanguage._Main(Form2)
            Btn_Main.Text = "中文"

        ElseIf Btn_Main.Text = "中文" Then

            System.Threading.Thread.CurrentThread.CurrentUICulture = New Globalization.CultureInfo("en-US")
            _C_UILanguage._Main(Me)
            _C_UILanguage._Main(Form2)
            Btn_Main.Text = "English"

        End If

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Form2.Show()

    End Sub
End Class