2011年8月31日 星期三

WordPress 外掛論壇 (Simple:Press)

Simple:Press 官網
參考架設範例

這支援wordpress的論壇,已漸漸被架設使用!
至於中文化部分,官方報告:70%中文化;所以還要過一些時日才能有全中文化的機會了
控制台的設定還真多,還在研究中..
--
我架設好後的畫面:

insert into , update 另類寫法

參考
---
CREATE TABLE it0815a (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(5) NOT NULL,
sumb INT
);

CREATE TABLE it0815b (
id INT NOT NULL,
valuex INT NOT NULL
);

INSERT INTO it0815a(id,name) VALUES
(1,'A'), (2, 'B'), (3, 'C');

INSERT INTO it0815b VALUES
(1,2),(1,3),(1,2),(2,4),(2,3),(3,1),(3,2),(3,3);
---------------------------
UPDATE it0815a a
LEFT JOIN (SELECT id, sum(valuex) as sumx
FROM it0815b
GROUP BY id) b
ON a.id = b.id
SET a.sumb = b.sumx;

select * from it0815a;
+----+------+------+
| id | name | sumb |
+----+------+------+
| 1 | A | 7 |
| 2 | B | 7 |
| 3 | C | 6 |
+----+------+------+

---
update join 上面是mysql寫法,要調整:
UPDATE BookmarkUrls
SET BookmarkUrls.BlogID = D.BlogID
FROM
dbo.BookmarkUrls INNER JOIN
(
-- 找出Detail Table 最先新增的那筆資料
SELECT LinkID,UrlID,BlogID FROM dbo.BookmarkLinks as i
WHERE LinkID IN
(
SELECT MIN(LinkID )
FROM BookmarkLinks AS i2
GROUP BY(UrlID)
)
) AS D
ON BookmarkUrls.UrlID = D.UrlID

參考

2011年8月30日 星期二

資源檔來做多國語言的介面

參考1
參考2
---
引用參考1範例:

Imports System.Globalization
Imports System.Reflection

Public Class Form1

Dim RM As Resources.ResourceManager
Dim CI As CultureInfo

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
RM = New Resources.ResourceManager("ResourceTest.Resource", Assembly.GetExecutingAssembly)
End Sub

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Select Case ComboBox1.SelectedIndex
Case Is = 0
CI = New CultureInfo("en-US")
Case Is = 1
CI = New CultureInfo("zh-CN")
Case Is = 2
CI = New CultureInfo("zh-TW")
Case Else
Exit Sub
End Select
Threading.Thread.CurrentThread.CurrentUICulture = CI
Label1.Text = RM.GetString("button")
Label2.Text = RM.GetString("text")
End Sub
End Class

---
我自己的範例圖:


net 多國語言

微軟_CultureInfo 類別
--------------------------------------
須:Imports System.Globalization
常用代碼:
zh-HK 0x0C04 中文 - 香港特別行政區
zh-MO 0x1404 中文 - 澳門特別行政區
zh-CN 0x0804 中文 - 中國
zh-CHS 0x0004 中文 (簡體)
zh-SG 0x1004 中文 - 新加坡
zh-TW 0x0404 中文 - 台灣
zh-CHT 0x7C04 中文 (繁體)

2011年8月29日 星期一

Estory 租書(區)網路版,店的優勢:

店實體架構分配:
a.若是有分層樓1和2樓;在1樓可設置1機台,在2可設置1機台;加開辦公室1機台
,運用:進書.查帳.盤點書籍.統計分析各項報表
b.同層樓;設置2機台,可疏通尖峰時段;利用其中1機台(不影響租還作業)排書時可利用查詢書籍資料來分類櫃位,
節省多次至櫃位問題

資料流,採用MS-SQL 2008 R2/SP1 Express:
a.真正網路版的資料庫,非開資源分享方式;市面他套租書軟體多採用DBF資料庫多機,都是採用開資源分享
;這種模式的穩定度到底怎樣,唯用過的店家清楚狀況在哪了
b.MS-SQL 2008 R2/SP1 改進了過往 SQL 2000/MSDE 很多的問題,在速度更上一層且穩定度也提升很多;
在容量上限也增至10GB的空間,這容量在小規模的行業運用上已足夠
c.Express版本並未提供自動備份機制,本工作室也特開發MS-SQL自動備份工具,不會影響租書還書的作業;
而市面他套採用MS-SQL資料庫的租書軟體其資料備份工具,當啟動備份時竟會影響當下的租書/還書作業

系統採用C/S架構:
1.因目前市面需求只到C/S,尚未有店家須B/S+C/S的架構;若店家願意客製付費B/S架構,本工作室會加開此架構
C/S:Client/Server 即是:在一個區網路的範圍運用,無法跨網;運用限在單店多機
B/S:Browser/Server 即是:在廣域的環境提供功能運用,跨網;運用在會員訂預約書.查自己相關記錄等

C/S 與 B/S 區別

B/S結構,即Browser/Server(瀏覽器/服務器)結構,是隨著Internet技術的興起,對C/S結構的一種變化或者改進的結構。在這種結構下,用戶界面完全通過WWW瀏覽器實現,一部分事務邏輯在前端實現,但是主要事務邏輯在服務器端實現,形成所謂3-tier結構。B/S結構,主要是利用了不斷成熟的WWW瀏覽器技術,結合瀏覽器的多種scrīpt語言(VBscrīpt、Javascrīpt…)和ActiveX技術,用通用瀏覽器就實現了原來需要複雜專用軟件才能實現的強大功能,並節約了開發成本,是一種全新的軟件系統構造技術。隨著Windows98/Windows 2000將瀏覽器技術植入操作系統內部,這種結構更成為當今應用軟件的首選體系結構。顯然B/S結構應用程序相對於傳統的C/S結構應用程序將是巨大的進步。

C/S 與 B/S 區別:
  Client/Server一般是建立在局域網的基礎上的.Browser/Server是建立在廣域網的基礎上的.
1.硬件環境不同:
  C/S 一般建立在專用的網絡上, 小範圍裡的網絡環境, 局域網之間再通過專門服務器提供連接和數據交換服務.
  B/S 建立在廣域網之上的, 不必是專門的網絡硬件環境,例與電話上網, 租用設備. 信息自己管理. 有比C/S更強的適應範圍, 一般只要有操作系統和瀏覽器就行
2.對安全要求不同
  C/S 一般面向相對固定的用戶群, 對信息安全的控制能力很強. 一般高度機密的信息系統採用C/S 結構適宜. 可以通過B/S發佈部分可公開信息.
  B/S 建立在廣域網之上, 對安全的控制能力相對弱, 面向是不可知的用戶群.
3.對程序架構不同
  C/S 程序可以更加注重流程, 可以對權限多層次校驗, 對系統運行速度可以較少考慮.
  B/S 對安全以及訪問速度的多重的考慮, 建立在需要更加優化的基礎之上. 比C/S有更高的要求 B/S結構的程序架構是發展的趨勢, 從MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持網絡的構件搭建的系統. SUN 和IBM推的JavaBean 構件技術等,使 B/S更加成熟.
4.軟件重用不同
  C/S 程序可以不可避免的整體性考慮, 構件的重用性不如在B/S要求下的構件的重用性好.
  B/S 對的多重結構,要求構件相對獨立的功能. 能夠相對較好的重用.就入買來的餐桌可以再利用,而不是做在牆上的石頭桌子
5.系統維護不同
系統維護是軟件生存週期中,開銷大, -------重要
  C/S 程序由於整體性, 必須整體考察, 處理出現的問題以及系統升級. 升級難. 可能是再做一個全新的系統
  B/S 構件組成,方面構件個別的更換,實現系統的無縫升級. 系統維護開銷減到最小.用戶從網上自己下載安裝就可以實現升級.
6.處理問題不同
  C/S 程序可以處理用戶面固定, 並且在相同區域, 安全要求高需求, 與操作系統相關. 應該都是相同的系統
  B/S 建立在廣域網上, 面向不同的用戶群, 分散地域, 這是C/S無法作到的. 與操作系統平台關係最小.
7.用戶接口不同
  C/S 多是建立的Window平台上,表現方法有限,對程序員普遍要求較高
  B/S 建立在瀏覽器上, 有更加豐富和生動的表現方式與用戶交流. 並且大部分難度減低,減低開發成本.
8.信息流不同
  C/S 程序一般是典型的中央集權的機械式處理, 交互性相對低
  B/S 信息流向可變化, B-B B-C B-G等信息、流向的變化, 更像交易中心  

比如一些聊天軟件,是c/s結構的因為滿足這種軟件的可維護和升級性,滿足不同的人群的個性和喜好,自己制定自己的界面,安裝自己喜歡的插件,但在b/s結構上實現這一點比較困難,並且可擴展性也不好。

比如說很多人每天上新浪網,只要安裝了瀏覽器就可以了,並不需要瞭解新浪的服務器用的是什麼操作系統,而事實上大部分網站確實沒有使用windows操作系統,但用戶的電腦本身安裝的大部分是windows操作系統
軟件系統的改進和升級越來越頻繁,B/S架構的產品明顯體現的更方便的特性。無論用戶的規模有多大,有多少分支機構都不會增加任何維護升級的工作量,所有的操作只需要針對服務器進行,如果是異地只需要把服務器連接上網即可立即進行維護和升級,這對人力、時間、費用的節省是相當驚人的。
一個稍微大一點單位來說,系統管理人員如果需要在幾百甚至幾千部電腦之間來回奔跑,效率和工作量是可想而知的,但B/S架構的軟件只需要管理服務器就行了,所有的客戶端只是瀏覽器,根本不需要做任何的維護。所以客戶機越來越"瘦"而服務器越來越"胖"是將來軟件的主流發展方向,這使得升級和維護越來越容易而使用越來越簡單。

2011年8月28日 星期日

adodb 使用 SQL Server 「逾時過期」的處理方式

參考
---

程式設定 CommandTimeout 處理的範例:

Dim conn As New ADODB.Connection
conn.Open(ConnStr)
conn.CommandTimeout = 0 '秒
conn.Execute("INSERT INTO A SELECT * FROM B")
conn.Close()
conn = Nothing


但SQL SERVER 本身也須要將:
[連線]-->[遠端查詢逾時] 設定:0


這兩個是相對應的!

若在adodb沒設定;若一遇到大資料量1分鐘即反應:逾期訊息 , 即使sql server 端已設定 0秒!

2011年8月25日 星期四

好用的google 線上日曆

---------------
一直想找 free 的行事曆,要自己掛;結果...東找西找~就是沒有
最後還是選google的日曆,很適合我的習慣;隨想隨記
有時想到專案缺些什麼需補那些,真是太讚了.

MS SQL Server Connection Strings

參考
--
Standard Security:

<% 'declare the variable that will hold the connection string Dim ConnectionString 'define connection string, specify database driver and location of the database ConnectionString="Driver={SQLServer};Server=your_server_name;" &_ "Database=your_database_name;Uid=your_username;Pwd=your_password;" %>
Trusted Connection:

<% 'declare the variable that will hold the connection string Dim ConnectionString 'define connection string, specify database driver and location of the database ConnectionString="Driver={SQLServer};Server=your_server_name;" &_ "Database=your_database_name;Trusted_Connection=yes;" %>
OLE DB and OleDbConnection (.NET framework) Connection Strings

Standard Security:

<% 'declare the variable that will hold the connection string Dim ConnectionString 'define connection string, specify database driver and location of the database ConnectionString="Provider=SQLOLEDB;Data Source=your_server_name;" &_ "Initial Catalog= your_database_name;UserId=your_username;Password=your_password;" %>
Trusted Connection:

<% 'declare the variable that will hold the connection string Dim ConnectionString 'define connection string, specify database driver and location of the database ConnectionString= "Provider=SQLOLEDB;Data Source=your_server_name;" &_ "Initial Catalog=your_database_name;Integrated Security=SSPI;" %>
Connect via an IP address:

<% 'declare the variable that will hold the connection string Dim ConnectionString 'define connection string, specify database driver and location of the database ConnectionString="Provider=SQLOLEDB;Data Source=your_remote_server_ip,1433;Network Library=DBMSSOCN;" &_ "Initial Catalog=your_database_name;User ID=your_username;Password=your_password;" %>
At the end of the Data Source is the port to use (1433 is the default)

2011年8月24日 星期三

租書軟體網路版架構圖


SQL 備份還原


-------------
依前幾篇的參考文件,採SMO方式自己動手寫這個 ; 因實際需求要運用到 !!
加入備份時間+目錄+設定值;為完整!


-----------------
完整版:

2011年8月23日 星期二

Backup SQL Database SMO

參考
--
[VB.NET CODE STARTS]

'--Reference added

Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Common

'--Declare the backup object

Dim WithEvents oBackup As New Backup

'--Method to take backup

Private Sub BackupSqlDatabase()

Dim conn As New ServerConnection(serverName, userName, passWd) ' -- set SQL server connection given the server name, user name and password
Dim oSQLServer As New Server(conn) '--create the SMO server object using connection

Dim OrigBackupPath As String = oSQLServer.Information.MasterDBPath.Replace("\DATA", "\Backup\DB_BACKUP_NAME.BAK") ' -- set the path where backup file will be stored

Dim bkDevItem As New BackupDeviceItem(OrigBackupPath, DeviceType.File) ' -- create SMO.Backupdevice object

With oBackup ' Set the backup object property
.Action = BackupActionType.Database
.Database = YOUR_DATABASE_NAME
.Devices.Add(bkDevItem)
.Initialize = True
.Checksum = True
.ContinueAfterError = True
.Incremental = False
.LogTruncation = BackupTruncateLogType.Truncate
.SqlBackup(oSQLServer) ' backup SQL database
End With

End Sub

[VB.NET CODE ENDS]

Backup and Restore SQL Server databases programmatically with SMO

參考1
參考2
參考3(微軟)

在SQL Server 2008中SQL-DMO被SMO代替

最近想研究通过编程控制操作SQL Server。下载了一个工具叫Sql Buddy。但在使用的时候发生异常,经查,是因为我的机器上安装的SQL Server Express 2008并没有提供SQL-DMO组件库。Google了一番,找到原因:
MSDN上搜到SQL-DMO 参考


后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。 

SQL Server 分布式管理对象 (SQL-DMO) 是封装了 Microsoft SQL Server 数据库管理和复制管理的对象所组成的集合。SQL-DMO 允许您对管理 SQL Server 的应用程序进行计划。SQL-DMO 参考包含有关对象、集合、属性、方法、事件、常量和示例程序的详细信息。

SQL-DMO 已被 SQL Server 管理对象 (SMO) 取代。


于是又查阅了下SMO的概述
SQL Server 管理对象 (SMO) 是针对 Microsoft SQL Server 的编程管理设计的对象。可以使用 SMO 生成自定义 SQL Server 管理应用程序。尽管 SQL Server Management Studio 是用于管理 SQL Server 的使用广泛的强大应用程序,但有时 SMO 应用程序可能对您更为适用。
例如,可能需要简化控制 SQL Server 管理任务的用户应用程序,以满足新用户的需要并且降低培训成本。您可能需要创建自定义 SQL Server 数据库,或创建用于创建和监控索引效率的应用程序。还可以使用 SMO 应用程序将第三方硬件或软件无缝纳入数据库管理应用程序。
SMO 对象模型扩展并取代了分布式管理对象 (SQL-DMO) 对象模型。与 SQL-DMO 相比,SMO 提高了性能、加强了控制,并且更易于使用。SMO 中包括大部分 SQL-DMO 功能,并且还有很多新类用于支持 SQL Server 中的新增功能。该对象模型直观明了,并且尽量使用 SQL-DMO 术语,以帮助您进行技能过渡。
由于 SMO 与 SQL Server 2000、SQL Server 2005 和 SQL Server 2008 兼容,您可以轻松管理多版本环境。
....
SMO 命名空间为 
Microsoft.SqlServer.Management.Smo。SMO 作为 Microsoft .NET Framework 程序集实现。这意味着使用 SMO 对象之前必须先安装 Microsoft .NET Framework 版本 2.0 中的公共语言运行时。SMO 程序集随 SQL Server SDK 选件默认安装到全局程序集缓存 (GAC) 中。这些程序集位于 C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\ 中。有关详细信息,请参阅 Visual Studio .NET Framework 文档。
  SMO 类
SMO 类包括两个类别:实例类和实用工具类。
实例类
实例类表示 SQL Server 对象,如服务器、数据库、表、触发器和存储过程。
 ServerConnection 类用于与 SQL Server 实例建立连接,并且控制发送到它的命令的捕获模式。
SMO 实例对象所构成的层次结构代表了数据库服务器的层次结构。顶部为 SQL Server 实例,其下为数据库,再下面是表、列、触发器等。如果存在一个父级对多个子级的关系(如某个表具有一个或多个列)是符合逻辑的,那么子级将由对象集合来表示。否则子级仅由对象来表示。
实用工具类
实用工具类是为执行特定任务而显式创建的一组对象。根据功能将它们划分为不同的对象层次结构:


    • 传输类。用于向其他数据库传输架构和数据。
    • 备份和还原类。用于备份和还原数据库。
    • 脚本程序类。用于创建脚本文件,以重新生成对象及其依赖关系。



...

SMO 对象模型取代了 SQL-DMO。SMO 支持 SQL Server 2000、SQL Server 2005 和 SQL Server 2008。它支持更多 SQL Server 管理任务并包含 SQL Server 中的许多新功能。SMO 设计用于提高效率和加强控制。

DMO 库是一个 COM 对象模型,而 SMO 作为 .NET Framework 程序集实现。COM 组件是一些库,这些库向应用程序提供可重用的功能并且采用非托管应用程序编程方式。.NET Framework 程序集提供可重用功能,供 .NET Framework 编写托管代码应用程序。

向 .NET Framework 技术过渡的过程中,编写应用程序可采用部分托管代码和部分非托管代码。.NET Framework 支持与 COM 组件建立接口连接,这需要一个主互操作程序集。SQL-DMO 需要运行时包装,以便从基于 .NET Framework 的应用程序进行调用。

看样,学习SQL Server的管理与控制,以后就全面研究SMO这个命名空间了。但是如果你想在SQL Server 2008中使用SQL-DMO,你可以下载Microsoft SQL Server 2008 功能包中的Microsoft SQL Server 2005 向后兼容组件


另注:Sql Buddy这个工具是开源的,用C#代码编写的。我决定使用SMO重写Sql Buddy这个工具以符合潮流。由于我对SQL-DMO和SMO都不熟悉。这可能要花费一段时间。

来源:http://www.cnblogs.com/codeyu/

SQLDMO 備份和還原Microsoft SQL Server 資料庫

///

/// 数据库备份

/// 参数信息要备份的数据库的名称Backup .Database = "Northwind";

/// 另外一个是存放备份文件的路径和文件名称Backup .Files = @"c:\databak.bak";

///


private void Button1_Click(object sender, System.EventArgs e)

{

SQLDMO.Backup Backup = new SQLDMO.BackupClass();

SQLDMO.SQLServer SQLServer = new SQLDMO.SQLServerClass();

try

{

SQLServer.LoginSecure = false;

SQLServer.Connect("IP", "USERNAME", "PWD");

Backup .Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMBackup _Database;

Backup .Database = "Northwind";//要备份的数据库的名称,例如Northwind

Backup .Files = @"c:\databak.bak";//存放路径,和备份文件的名称

Backup .BackupSetName = "Northwind";

Backup .BackupSetDescription = "数据库备份";

Backup .Initialize = true;

Backup .SQLBackup(SQLServer);

}

Catch(Exception ex)

{

Throw ex;

}

finally

{

SQLServer.DisConnect();

}

}

///

/// 数据库恢复

/// 参数信息要恢复的数据库的名称Restore .Database = "Northwind_Res";

/// 另外一个是存放数据库备份文件的路径和文件名称

/// Backup .Files = @"c:\databak.bak";用来恢复数据库

///


private void Button2_Click(object sender, System.EventArgs e)

{

SQLDMO.Restore Restore = new SQLDMO.RestoreClass();

SQLDMO.SQLServer SQLServer = new SQLDMO.SQLServerClass();

try

{

SQLServer.LoginSecure = false;

SQLServer.Connect("IP", "USERNAME", "PWD");

Restore .Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMRestore _Database;

Restore .Database = "Northwind_Res";

Restore .Files = @"C:\ databak.bak";

Restore .FileNumber = 1;

Restore .ReplaceDatabase = true;

Restore .SQLRestore(SQLServer);

}

catch(Exception ex)

{

Throw ex;

}

finally

{

SQLServer.DisConnect();

}

}

}

2011年8月22日 星期一

Microsoft iSCSI Software Target 3.3

Microsoft iSCSI Software Target 3.3
---
參考:
微軟釋出iSCSI Software Target 3.3 for Server 2008 R2

MSSQL資料庫建在NAS網路儲存設備上的效率分析

-----------
以上的數據,若要如此建構;要好好考慮了!

若是運用在資料流小的,且SQL的主機要強悍些;也許可考慮這樣的跑法!
但差了快29倍,是否主機配備夠;是否能拉出高效率呢?

---
2011/8/24 修正:
1.以上的29倍,乃是經過3層hub的結果
2.當實測在同一層HUB,速度無異
3.MS-SQL 使用 iscsi 掛入 nas 為硬碟;若關機前未將資料庫卸離,恐造成災難問題! (如同不正常關機情況)
4.nas 使用 iscsi 若被 2 PC (含以上) 將造成錯亂和一推問題出現!

以上種種,若要這樣的架設;得好好思量了...

--
2011/8/26 修正:
1.經再測 只用1pc iscsi nas 空間,開關機 ; MS-SQL 均可正常運作!
2.重點在:不可 2 台pc 同時 iscsi nas 的相同空間


資料庫 'tempdb' 的交易記錄已滿

因sql 2008 已無法使用:(只適用 SQL 2000,2005)
-----------------------------
BACKUP LOG tempdb WITH TRUNCATE_ONLY
DBCC SHRINKDATABASE (tempdb)
-----------------------------
會出現:'TRUNCATE_ONLY' 不是可辨識的 BACKUP 選項。


解決方式:
(1)restart sql
(2)試著對tempdb壓縮,取得一些空間

其實:
這問題該是:安裝的mssql 2008 ->tempdb 所在的磁碟槽 ; 若是hd 夠大的話,應不會有此問題出現!!
所以建議, c: 一定要保持一定的空間容量 ; 像我的剩 1.5 GB 結果都被tempdb咬去吃了..

2011年8月21日 星期日

Win 7 批次檔式開防火牆

參考
----
批次檔:
將以下內容存成*.bat檔並且執行

@echo ========= SQL Server Ports ===================
@echo Enabling SQLServer default instance port 1433
netsh firewall set portopening TCP 1433 "SQLServer"
@echo Enabling Dedicated Admin Connection port 1434
netsh firewall set portopening TCP 1434 "SQL Admin Connection"
@echo Enabling conventional SQL Server Service Broker port 4022
netsh firewall set portopening TCP 4022 "SQL Service Broker"
@echo Enabling Transact-SQL Debugger/RPC port 135
netsh firewall set portopening TCP 135 "SQL Debugger/RPC"
@echo ========= Analysis Services Ports ==============
@echo Enabling SSAS Default Instance port 2383
netsh firewall set portopening TCP 2383 "Analysis Services"
@echo Enabling SQL Server Browser Service port 2382
netsh firewall set portopening TCP 2382 "SQL Browser"
@echo ========= Misc Applications ==============
@echo Enabling HTTP port 80
netsh firewall set portopening TCP 80 "HTTP"
@echo Enabling SSL port 443
netsh firewall set portopening TCP 443 "SSL"
@echo Enabling port for SQL Server Browser Service's 'Browse' Button
netsh firewall set portopening UDP 1434 "SQL Browser"
@echo Allowing multicast broadcast response on UDP (Browser Service Enumerations OK)
netsh firewall set multicastbroadcastresponse ENABLE

windows XP 使用 iscsi 遠端無碟啟動 remote boot

真是驚嘆!!
-----------
1.windows XP 使用 iscsi 遠端無碟啟動 remote boot

2.無硬碟環境啟動Windows XP(使用ISCSI虛擬磁碟)

3.How To: Windows Server / XP / 2000 / 2003 ISCSI Initiator Configuration

4.FreeNAS 8.0 | Storage For Open Source
--------------
最近看到不少同業採用此方法建置網咖,但大都採用對岸的無碟軟體,例如"遙志CCDISK...",但這些原理與Linux中的免費軟體gPXE大同小異,雖然不是甚麼特別的技術,不過還是把DIY建置的方法寫下與大家分享/交流.
建置環境:
(1)FEDORA 9 作業系統, 已建置DHCP/ TFTP以及LVM磁碟系統
(2)使用 iSCSI Enterprise Target 作為iSCSI Server
不再贅述DHCP/Tftp及ISCSI安裝方法,請先行參考安裝文件

原理導論:
一般使用無碟啟動,都是利用主機板內建網卡的PXE ROM來向DHCP Server發出請求,Server會回應IP設定值,並利用TFTP傳回對應的檔案啟動執行,但多為軟碟的影像檔,或其他較小的檔案(約5mb以內),載入後以RAMDISK虛擬執行, 並不能直接虛擬光碟或硬碟,因為用TFTP協定不宜傳輸太大的檔案.
但一些例如Intel的高階網卡,卻可直接在網卡中設定iSCSI的主機來開機,是因為這些網卡有完整的程式碼可將遠端iSCSI磁碟連入後虛擬成單機的一個SCSI裝置,故可以輕易在上面執行XP.
但主機板上的PXE ROM通常都很簡漏,做不到這些高階功能,所有就有一些自由軟體的愛好者,提出了Etherboot/gPXE 方案解決了這個問題.
簡單的說gPXE一樣是用PXE ROM啟動,DHCP Server回應gPXE的原始檔,它會自動將主機板的PXE ROM取代,然後再向DHCP Server再要求一次IP設定,這時我們可以透過DHCP的設定腳本來分析這個要求是否是一般PXE ROM還是gPXE,如過是gPXE就回應給他要登入的iSCSI參數列指令,這樣gPXE的程式碼就會把成功連入的iSCSI磁碟虛擬成一個SCSI裝置,這樣就可以自由的載入Windows XP了.
1.建置iSCSI Target
我們假設你已安裝好 iSCSI Enterprise Target, 首先先建立一個LVM的分割區給XP的影像使用
lvcreate -L 20GB -n BOOTTEST /dev/VG
分割20GB給XP用,BOOTTEST是你命名的XP影像分割區, VG是邏輯磁區群組名稱
用ietadm手動建立target (當然你可以用/etc/ietd.conf來設定,但我喜歡用指令列的方法,比較簡單)
ietadm --op new  --tid=100 --params Name=BOOTTEST
ietadm --op new --tid=100 --lun=0 --params Path=/dev/VG/BOOTTEST,Type=fileio,IOMode=wb
中間tid的數值可自己設定1~999都可以.
這樣iSCSI Target就有一個設備的名稱叫BOOTTEST,這就是我們用來連入ISCSI磁碟的連結點
2.安裝Windows XP
先找一台有硬碟的電腦先安裝好 windows xp 並且更新到最新的 update ,當然這個磁碟分割不能超過我們剛才設定的20GB.
安裝一般正常的 iscsi initiator (微軟)
http://www.microsoft.com/downloads/en/details.aspx?familyid=12cb3c1a-15d6-4585-b385-befd1319f825&displaylang=en

裝好後請加裝  iscsi 的開機(BOOT)支援套件
請參考:http://www.etherboot.org/wiki/sanboot/winnt_iscsi
也就是下載這兩個檔案安裝:
然後再加裝 sanboot driver ,這樣就可用 iscsi 開機
http://www.etherboot.org/wiki/sanboot/winnt_sanbootconf
這是 etherboot 這個專案為了這個開發的設定工具。

這樣這個Windows XP就可以在iSCSI中被正常啟動, 先把它做成GHOST檔吧!
然後要把這個GHOST檔"灌入"這個iSCSI磁碟中
當然要在Windows XP的系統先用iscsi initiator 來連接剛才在iSCSI SERVER作好的BOOTTEST目標
連入後,你只能initiator看到connected訊息,你在"我的電腦"中不會看到有任何新磁碟出現的訊息,因為這時候這顆ISCSI磁碟是"空白的",要在"我的電腦"圖示上按右鍵,選"管理",然後 "本機->存放裝置->磁碟管理",這時你會看到你電腦中所有的磁碟裝置,其中會有一個20GB顯示"未啟始"的磁碟,這就是剛才連入的iSCSI磁碟,起始它並分割一個NTFS的主分割區給它,分配代號並格式化後回到我的電腦就可以看見這顆iSCSI磁碟.
再來我們要如何把剛做好的的ghost檔"灌入"呢?
要用ghost32.exe程式, 這是gosht 11中的檔案,它可以在Windows XP的環境中直接把"非現用系統碟"作GHOST,很好用,可把ghost影像檔直接灌到iscsi碟中;請不要問我要去哪裡找,這是版權軟體,自己上網找或買正版的.
灌入後,iSCSI Server的BOOTTEST目標,就有這台客端完整的XP程式了, 現在可以將客端硬碟接拔掉或關閉.
3.取得gPXE程式碼
http://kernel.org/pub/software/utils/boot/gpxe/gpxe-1.0.1.tar.gz
在linux中解壓後要用gcc編譯成原始碼
cd gpxe-1.0.1
make bin/undionly.kpxe
這樣在 gpxe-1.01/bin資料夾下就有一個undionly.kpxe程式,這就是gPXE原始檔,把它COPY到tftpboot中
cp undionly.kpxe /tftpboot/
4.設定DHCP的啟動腳本
編輯/etc/dhcpd.conf檔
allow booting;
allow bootp;
option broadcast-address 192.168.1.255;
option domain-name "dns.hinet.net";
option domain-name-servers 168.95.1.1;
ddns-update-style none;
           subnet 192.168.1.0 netmask 255.255.255.0 {
           range 192.168.1.10 192.168.1.100;
           option subnet-mask      255.255.255.0;
           option routers          你的主機IP;
           next-server                你的主機IP;
           filename                "pxelinux.0";
           }

           host BOOT01 {
           hardware    ethernet    xx:xx:xx:xx:xx:xx;  #你的網卡MAC位址
           fixed-address           客端IP;
           next-server             你的主機IP;
            if exists user-class and option user-class = "gPXE" {
               filename "";
               option root-path "iscsi:你的iSCSI主機IP::::BOOTTEST";
            } else {
               filename "undionly.kpxe";
            }
           }
這種設定方法就是把特定的MAC位址對應到指定的iSCSI Target連結, 如果不符的網卡,會依正常的PXE去使用syslinux程式來啟動.
改好後,把DHCP SERVER重新啟動, 可以用指令 service dhcpd restart 來達成.
5.現在將無硬碟的客端開機, 如果一切都沒有問題的話,應該可以順利啟動Windows XP.
後面還有一個問題就是,如何使用一個iSCSI母碟,多台客端連入, 事實上更簡單,聰明的人早已想到了...對的,LVM磁碟系統可以做snapshot(快照),你要用母碟作多少個客端都沒問題,每個客端都可以有自己不同的設定,甚至就算網卡/顯卡/主機板有差異也一樣可用! 自己試試看吧!

打造免費的全能型NAS

1.打造免費的全能型NAS - 安裝教學
2.打造免費的全能型NAS - iSCSI攻略

Windows XP 支援iSCSI

Microsoft iSCSI Software Initiator Version 2.08
---
相關討論:
DIY Iscsi server

2011年8月19日 星期五

移除 win7 sp1

wusa.exe /uninstall /kb:976932

或是到控制台[程式和功能]
找編號:976932 ,解除安裝

Windows 7 SP1 導致含有 ADO 的程式失效問題

真是....敗了!! 怎老是要去舊迎新勒..
----------------------------------------
須調整寫法:
原:
Dim Conn As New ADODB.Connection

改:
Dim Conn As Object
Set Conn = CreateObject("ADODB.Connection")
----------------------------------------
相關請參考:
1.參考1
2.參考2
3.參考3
4.參考4

MSFlexGrid 運用

Private Sub Form_Load()
MSFlexGrid1.TextMatrix(1, 1) = "Twinkle"
Timer1.Interval = 500
End Sub



Private Sub Timer1_Timer()
With MSFlexGrid1
.Row = 1
.Col = 1
.CellForeColor = IIf(.CellForeColor = vbBlack, vbRed, vbBlack)
.CellBackColor = IIf(.CellBackColor = vbWhite, vbGreen, vbWhite)
End With
End Sub


假設您的欄位名稱是 UpdateDate,則在 SQL 語法內可以以此格式將欄位的內容進行格式設定:
Format(UpdateDate, "yyyy/MM/dd")

2011年8月16日 星期二

SQL2008R2_SP1

哇,微軟又釋放新的SP了
---
發行日期:2011/7/12
真是一忙,又忘了關注此事!!

Microsoft® SQL Server® 2008 R2 Service Pack 1

------------------
要安裝 SP1 版,必須先安裝 MS-SQL 2008 R2 版
Microsoft SQL Server 2008 R2 RTM - Express

2011年8月13日 星期六

Crystal Report 子報表與主報表公用參數設置

參考來源
---
一: 設置子表報與主報表的公用參數,主報表的datasource 與子報表的datasource 分開,如果子報表需要新增其他輸入參數,則可以直接設置入參,也可以使用與主報表一樣的入參。 以下步驟 就是為了使子報表使用與主報表一樣的入參 而做的操作,這樣可以減少入參的數量,簡化程序

1.1. 先將主報表中的數據庫字段 以及參數 設置好,並且創建好子報表(菜單--》crystal report--》insert --》subreport 然後拖到主報表的指定位置)

1.2. 將子報表 添加到主報表的 報表頁腳中,不同子報表 可以添加到多個 報表頁腳中.

1.3. 設置 子報表 與主報表的公用參數 .如下圖

1.3.1 在主報表頁面,右鍵點擊 子報表, 然後點擊 "更改子報表鏈接"

1.3.2 在"子報表鏈接" 窗口, 按照每個子報表,分別選中 主報表中的字段或參數, 然後對應到該子報表的參數中,

這些子報表必須沒有鏈接到其他 主報表的字段或參數上, 必須是乾淨的,

---
---
二: 修改 報表參數.

如果主報表參數被子報表引用了,而你又需要修改這個參數,則可以 按照一下步驟

2.1 參照1.3步驟, 執行1.3.1 步驟,到 "子報表鏈接" 頁面,將 所有引用到 該修改字段或參數的 參數 全部移除

2.2 修改 主報表中的該字段或參數

2.3 重新執行 1.3 全過程, 給每個子報表重新綁定該字段或參數.(如果子報表仍然需要引用該字段或參數)

2011年8月11日 星期四

JWorld@TW Java論壇

JWorld@TW Java論壇
---
JWorld@TW Java論壇 , 是國內最穩定的java論壇 ; 要學java可在這兒尋得相關心得和方法

2011年8月9日 星期二

影音之星

官網
--

影音之星是一款純綠色的萬能影音播放器,界面簡潔易用,支持絕大部分網絡視訊格式,

不含任何流氓套件,也決不會給用戶帶來廣告的煩惱。

新版影音之星可以自動阻止影片中夾帶的惡意廣告彈窗,支持播放DVD,

支持5.1環繞聲,支持自動或手動載入影片字幕。新版還支持獨有的滾動字幕功能,

可以同時顯示多行字幕,從而方便調整字幕和聲音的同步。此外另增加了視頻格式轉換功能,

可以輕鬆的將您喜歡的視訊轉換成PSP的/ iPhone/ iPod的觸摸這些手持設備支持的格式。

----------

終於找到適合的撥放器了,且又能撥音樂唷 !! 這下總算可把"暴風影音"刪了(實在廣告一推還弄一些技巧會讓人按到廣告)



2011年8月8日 星期一

水晶報表~判斷數量,標示:已未銷完

引用來源
---

1.
報表內寫一個公式

if 未銷數=0 then
formula="已銷完"+{備註}
else
formula="未銷完"+{備註}
end if

再把這個公式取代備註

2.
Dim dr1 As DataRow
For Each row1 In Me.Ds.sale
if dr1("未結數量")=0 then
dr1("備註")="已銷完"
else
dr1("備註")="未銷完"
end if
Next

2011年8月7日 星期日

LPT指令打印条码——代码嵌套指令

參考來源
---
VS中存在Com口操作的控件,却未有现成的LPT端口控件,而相对COM口来说,LPT的速度要快,所以在打印的时候客户一般选择LPT通讯方式,经过网上的一些查阅,终于实现了LPT口的打印,打印机为Zebra,写出来与大家分享。其他品牌打印机原理类似,只是打印指令有所区别。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PrintDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
tbBarCode.Focus();
}
private void tbBarCode_KeyDown(object sender,
KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Enter:
PrintBarcode(tbBarCode.Text.Trim());
tbBarCode.Text = "";
tbBarCode.Focus();
break;
default:
break;
}
}
private void PrintBarcode(string Barcode)
{
Barcode = "^XA^FO48,12^BY4^BCN,152,N,N^FD>;" +
Barcode.Trim() + "^FS^FT62,220^CI0^ABN,44,28^FD" +
Barcode.Trim() + "^FS^PQ1,0,1,Y^XZ";
PrintDemo.POSPrinter prn = new
PrintDemo.POSPrinter("LPT1");
string strmsg = prn.PrintLine(Barcode);
if (strmsg != "")
{
MessageBox.Show(strmsg);
}
}
}
}

其中类POSPrinter定义如下
namespace PrintDemo
{
class POSPrinter
{
const int OPEN_EXISTING = 3;
string prnPort = "LPT1";
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(string lpFileName,
int dwDesiredAccess,
int dwShareMode,
int lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
int hTemplateFile);
public POSPrinter()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public POSPrinter(string prnPort)
{
this.prnPort = prnPort;//打印机端口
}
public string PrintLine(string str)
{
IntPtr iHandle = CreateFile(prnPort, 0x40000000,
0, 0, OPEN_EXISTING, 0, 0);
if (iHandle.ToInt32() == -1)
{
return "LPT1 Port Open Failed";
}
else
{
FileStream fs = new FileStream(iHandle,
FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs,
System.Text.Encoding.Default); //写数据
sw.WriteLine(str);
sw.Close();
fs.Close();
return "";
}
}
}
}

向LPT1送一条切纸指令给打印机

參考來源
--
1. 定义LPT打印类
public class PrintFactory
{
public const short FILE_ATTRIBUTE_NORMAL = 0x80;
public const short INVALID_HANDLE_VALUE = -1;
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);

public static void SendCMDToLPT1( String receiptText )
{
IntPtr ptr = CreateFile("LPT1", GENERIC_WRITE, 0,
IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

if (ptr.ToInt32() == -1)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
else
{
FileStream lpt = new FileStream(ptr, FileAccess.ReadWrite);
Byte[] buffer = System.Text.Encoding.Default.GetBytes(receiptText);
lpt.Write(buffer, 0, buffer.Length);
lpt.Close();
}
}
}

2. 调用
PrintFactory.SendCMDToLPT1("ECS指令");

LPT1 列印

參考來源
--

public class PrintFactory
{
public const short FILE_ATTRIBUTE_NORMAL = 0x80;
public const short INVALID_HANDLE_VALUE = -1;
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);

public static void sendTextToLPT1( String receiptText )
{
IntPtr ptr = CreateFile("LPT1", GENERIC_WRITE, 0,
IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

/* Is bad handle? INVALID_HANDLE_VALUE */
if (ptr.ToInt32() == -1)
{
/* ask the framework to marshall the win32 error code to an exception */
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
else
{
FileStream lpt = new FileStream(ptr, FileAccess.ReadWrite);
Byte[] buffer = new Byte[2048];
//Check to see if your printer support ASCII encoding or Unicode.
//If unicode is supported, use the following:
//buffer = System.Text.Encoding.Unicode.GetBytes(Temp);
buffer = System.Text.Encoding.ASCII.GetBytes(receiptText);
lpt.Write(buffer, 0, buffer.Length);
lpt.Close();
}
}
}

小紅傘 當誤判病毒時,如何設定例外


----
2011/8/9 : 好像沒什用,設好玩的;一樣出現是病毒還檔掉檔案 !! 和AVG差太多了...真是有待加強!

HOW TO:端口打印(比较粗糙)

參考來源
--------
Imports System.IO
Imports System.Runtime.InteropServices
Public Class DataInfo
Private mLPTPORT As String '打印机端口
Private mInitText As String '初始化参数
Private mTexts As String() '以数组形式输出
Private mText As String '打印文本
Public Property LPTPORT() As String
Get
Return mLPTPORT
End Get
Set(ByVal Value As String)
mLPTPORT = Value
End Set
End Property
Public Property ToPrintText() As String
Get
Return mText
End Get
Set(ByVal Value As String)
mText = Value
End Set
End Property
Public Property InitPrinterText() As String
Get
Return mInitText
End Get
Set(ByVal Value As String)
mInitText = Value
End Set
End Property
Public Property ToPrintTexts() As String()
Get
Return mTexts
End Get
Set(ByVal Value As String())
mTexts = Value
End Set
End Property
End Class
Public Class Printer
#Region "接口参数"
Private PARAS As DataInfo
Public WriteOnly Property InputInfo() As DataInfo
Set(ByVal Value As DataInfo)
PARAS = Value
End Set
End Property
Private mStatus As Integer
Public ReadOnly Property STATUS() As Integer
Get
Return mStatus
End Get
End Property
#End Region

#Region "本地变量"
Private LPTPORT As String '端口
Private hPortP As IntPtr '返回句柄
Private retval As Boolean '关闭打印时返回的句柄
Private outFile As FileStream '打印字符流
#End Region
Public Sub InitializePrinter()
If PARAS.InitPrinterText.Trim = "" Then Exit Sub
LPTPORT = PARAS.LPTPORT
hPortP = CreateFile(LPTPORT, GENERIC_READ Or GENERIC_WRITE, 0, IntPtr.Zero, _
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)
mStatus = hPortP.ToInt32
outFile = New FileStream(hPortP, FileAccess.Write, False)
Dim fileWriter As New StreamWriter(outFile, System.Text.Encoding.Default)
fileWriter.AutoFlush = False
'打印开始
fileWriter.Write(PARAS.InitPrinterText)
fileWriter.Flush()
fileWriter.Close()
outFile.Close()
retval = CloseHandle(hPortP)
End Sub
Public Sub PrintText()
If PARAS.ToPrintText.Trim = "" Then Exit Sub
LPTPORT = PARAS.LPTPORT
hPortP = CreateFile(LPTPORT, GENERIC_READ Or GENERIC_WRITE, 0, IntPtr.Zero, _
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)
mStatus = hPortP.ToInt32
outFile = New FileStream(hPortP, FileAccess.Write, False)
Dim fileWriter As New StreamWriter(outFile, System.Text.Encoding.Default)
fileWriter.AutoFlush = False
'打印单据开始
fileWriter.WriteLine(PARAS.ToPrintText)
fileWriter.Flush()
fileWriter.Close()
outFile.Close()
retval = CloseHandle(hPortP)
End Sub
Public Sub Print(ByVal Text As String)
If Text.Trim = "" Then Exit Sub
LPTPORT = PARAS.LPTPORT
hPortP = CreateFile(LPTPORT, GENERIC_READ Or GENERIC_WRITE, 0, IntPtr.Zero, _
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)
mStatus = hPortP.ToInt32
outFile = New FileStream(hPortP, FileAccess.Write, False)
Dim fileWriter As New StreamWriter(outFile, System.Text.Encoding.Default)
fileWriter.AutoFlush = False
'打印单据开始
fileWriter.WriteLine(Text)
fileWriter.Flush()
fileWriter.Close()
outFile.Close()
retval = CloseHandle(hPortP)
End Sub
Public Sub PrintTexts()
If PARAS.ToPrintTexts Is Nothing OrElse PARAS.ToPrintTexts.Length = 0 Then Exit Sub
LPTPORT = PARAS.LPTPORT
hPortP = CreateFile(LPTPORT, GENERIC_READ Or GENERIC_WRITE, 0, IntPtr.Zero, _
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)
mStatus = hPortP.ToInt32
outFile = New FileStream(hPortP, FileAccess.Write, False)
Dim fileWriter As New StreamWriter(outFile, System.Text.Encoding.Default)
fileWriter.AutoFlush = False
'打印单据开始
For Each s As String In PARAS.ToPrintTexts
fileWriter.WriteLine(s)
Next
fileWriter.Flush()
fileWriter.Close()
outFile.Close()
retval = CloseHandle(hPortP)
End Sub
Public Shared Function GetCodeString(ByVal Numbers As String) As String
If Numbers.Trim = "" Then Return ""
Dim tmp As String
For Each s As String In Numbers.Split(" "c)
tmp &= Chr(CType("&H" & s, Integer))
Next
Return tmp
End Function
#Region "API所需要的必要信息"
Public Structure DCB
Public DCBlength As Int32
Public BaudRate As Int32
Public fBitFields As Int32
Public wReserved As Int16
Public XonLim As Int16
Public XoffLim As Int16
Public ByteSize As Byte
Public Parity As Byte
Public StopBits As Byte
Public XonChar As Byte
Public XoffChar As Byte
Public ErrorChar As Byte
Public EofChar As Byte
Public EvtChar As Byte
Public wReserved1 As Int16 'Reserved; Do Not Use
End Structure

Public Structure COMMTIMEOUTS
Public ReadIntervalTimeout As Int32
Public ReadTotalTimeoutMultiplier As Int32
Public ReadTotalTimeoutConstant As Int32
Public WriteTotalTimeoutMultiplier As Int32
Public WriteTotalTimeoutConstant As Int32
End Structure

Public Const GENERIC_READ As Int32 = &H80000000
Public Const GENERIC_WRITE As Int32 = &H40000000
Public Const OPEN_EXISTING As Int32 = 3
Public Const FILE_ATTRIBUTE_NORMAL As Int32 = &H80
Public Const NOPARITY As Int32 = 0
Public Const ONESTOPBIT As Int32 = 0

Public Declare Auto Function CreateFile Lib "kernel32.dll" _
(ByVal lpFileName As String, ByVal dwDesiredAccess As Int32, _
ByVal dwShareMode As Int32, ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As Int32, ByVal dwFlagsAndAttributes As Int32, _
ByVal hTemplateFile As IntPtr) As IntPtr

Public Declare Auto Function GetCommState Lib "kernel32.dll" (ByVal nCid As IntPtr, _
ByRef lpDCB As DCB) As Boolean

Public Declare Auto Function SetCommState Lib "kernel32.dll" (ByVal nCid As IntPtr, _
ByRef lpDCB As DCB) As Boolean

Public Declare Auto Function GetCommTimeouts Lib "kernel32.dll" (ByVal hFile As IntPtr, _
ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean

Public Declare Auto Function SetCommTimeouts Lib "kernel32.dll" (ByVal hFile As IntPtr, _
ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean

Public Declare Auto Function WriteFile Lib "kernel32.dll" (ByVal hFile As IntPtr, _
ByVal lpBuffer As Byte(), ByVal nNumberOfBytesToWrite As Int32, _
ByRef lpNumberOfBytesWritten As Int32, ByVal lpOverlapped As IntPtr) As Boolean

Public Declare Auto Function ReadFile Lib "kernel32.dll" (ByVal hFile As IntPtr, _
ByVal lpBuffer As Byte(), ByVal nNumberOfBytesToRead As Int32, _
ByRef lpNumberOfBytesRead As Int32, ByVal lpOverlapped As IntPtr) As Boolean

Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal hObject As IntPtr) As Boolean
#End Region
End Class

Public Class CODE
Public Const C4 As String = Chr(&H34)
Public Const 联机 As String = Chr(&H11)
Public Const 解除联机 As String = Chr(&H13)
Public Shared Function 页长(ByVal i As Integer) As String
Return GetString("1B 43 " & i.ToString) '3英寸长
End Function
Public Shared Function 解除重打模式() As String
Return GetString("1B 6E")
End Function
Public Shared Function 双向打印() As String
Return GetString("1B 23 42")
End Function
Public Shared Function 行距(ByVal i As Integer) As String
Return GetString("1B 25 39 00 " & i.ToString) '18
End Function
Public Shared Function 高速打印() As String
Return GetString("1B 44")
End Function
Public Shared Function 垂直跳格(ByVal i As Integer) As String
Return GetString("1B 0B 00 " & i.ToString) '修改最后两位
End Function
Public Shared Function 间距换行(ByVal i As Integer) As String
Return GetString("1B 23 35 " & i.ToString) '修改最后一数
End Function
Public Shared Function 逆向换行(ByVal i As Integer) As String
Return GetString("1B 23 38 " & i.ToString) '修改最后一数
End Function
Public Shared Function 初始化() As String
Return GetString("1B 42")
End Function
Public Shared Function 下页() As String
Return GetString("0C")
End Function
Public Shared Function 换行() As String
Return GetString("0A")
End Function
Public Shared Function L行距(ByVal i As Integer) As String
Return GetString("1B 2B " & i.ToString)
End Function
Public Shared Function GetString(ByVal Numbers As String) As String
If Numbers.Trim = "" Then Return ""
Dim tmp As String
For Each s As String In Numbers.Split(" "c)
tmp &= Chr(CType("&H" & s, Integer))
Next
Return tmp
End Function
End Class
使用示意:

Imports LzmTW.PortPrint
Imports LzmTW.Common.SubAndFunction
Public Class OKIPrinter
Private Shared mPrinter As Printer
Private Shared mDataInfo As DataInfo
Private mPrinterInfo As PrinterInfo '读取打印机端口定义
Private mInitialzePrinterText As String = CODE.初始化 & CODE.页长(3) & CODE.双向打印 & CODE.高速打印 & CODE.行距(18)
Sub New()
If mPrinter Is Nothing Then
mPrinter = New Printer
mDataInfo = New DataInfo
mPrinterInfo = New PrinterInfo
mPrinter.InputInfo = mDataInfo
End If
End Sub
Public Property LocatePrinterInfo() As PrinterInfo
Get
Return mPrinterInfo
End Get
Set(ByVal Value As PrinterInfo)
mPrinterInfo = Value
End Set
End Property
Private Sub InitializePrinter()
mDataInfo.LPTPORT = mPrinterInfo.LPTPORT
End Sub
Public Sub 打印(ByVal Bill As 票据, ByVal BillName As String)
InitializePrinter()
If BillName.Equals("结算单") Then
mPrinter.Print(Bill.ToPrint结算单(mPrinterInfo.PrinterType))
End If
If BillName.Equals("发票") Then
mPrinter.Print(Bill.ToPrint发票(mPrinterInfo.PrinterType))
End If
End Sub
Public Sub 打印收费卡(ByVal Card As 收费卡)
InitializePrinter()
mPrinter.Print(Card.PrinterText)
End Sub
Public Class PrinterInfo
Public PrinterType As PrinterType
Public LPTPORT As String
End Class
End Class

Public Enum PrinterType
OKI
LQ
End Enum


Public Class 票据
Public 用户编码 As String
Public NO As String
Public 用户名称 As String
Public 所属月份 As String
'...

Public Function ToPrint发票(ByVal PrinterType As PrinterType) As String
If PrinterType = PrinterType.OKI Then
Return ToPrintOKI发票()
Else
Return ToPrintLQ发票()
End If
End Function
Private Function ToPrintOKI发票() As String
Dim Code As Code
Dim Leg As String = Space(10)
Dim tmp As String
tmp &= Code.页长(5) & Code.双向打印 & Code.高速打印 & Code.行距(21) & Code.下页()
tmp &= Code.换行() & Code.换行() & Code.间距换行(9)
tmp &= Leg & String.Format("{0,12}" & CHNFormat(1, 41, True, 收费类型) & "{2,4} {3,2} {4,2}", _
"", 收费类型, 年, 月, 日)
tmp &= Code.间距换行(2)
tmp &= Code.换行() & Leg & String.Format("{0,12}" & CHNFormat(1, 26, True, 用户名称) & "{2,12}{3,-24}", _
"", 用户名称, "", 用户编码)
'....
tmp &= Code.下页
Return tmp
End Function
Private Function ToPrintLQ发票() As String
Dim Code As Code
Dim Leg As String = Space(10)
Dim tmp As String
tmp = Code.GetString("1B 40 1B 43 0 03") & Code.L行距(62)
tmp &= Code.换行() & Code.换行()
tmp &= Leg & String.Format("{0,12}" & CHNFormat(1, 39, True, 收费类型) & "{2,4} {3,2} {4,2}", _
"", 收费类型, 年, 月, 日)
tmp &= Code.换行() & Leg & String.Format("{0,12}" & CHNFormat(1, 24, True, 用户名称) & "{2,12}{3,-24}", _
"", 用户名称, "", 用户编码)
'....
Return tmp
End Function
'....
End Class

vb.net 如何利用 热敏打印机(小票机)打印文本,图片

參考1
參考2
---------
My.Settings.DirectPrint_Port 是设置的打印机端口。
可以为 LPT1,LPT2,com1,com2
---------
Try
Dim iHandle As IntPtr
Try
If My.Settings.DirectPrint_Port.Length <> 0 Then
iHandle = CreateFile(My.Settings.DirectPrint_Port, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
'iHandle = CreateFile("\\.\USB002", GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0) '打开USB句柄

Else
iHandle = CreateFile("LPT1", GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
End If
Catch ex As Exception
iHandle = CreateFile("LPT1", GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
End Try
'If "GAINSCHA GP(Aopos)"
If (iHandle.ToInt32 = -1) Then
MsgBox("没有连接打印机或者打印机端口不是LPT1")
Exit Sub
Else
' MsgBox("打印机连接成功!")

Dim fs As New FileStream(iHandle, FileAccess.ReadWrite)
Dim sr As New StreamReader(fs) '读数据
Dim sw As New StreamWriter(fs, System.Text.Encoding.Default) '写数据
Dim ESC2 As String = Chr(27)
Dim GS As String = Chr(29)
Dim LF As String = Chr(10)
Dim SEND As String = ESC2 & "@"
Dim footSpace As String = ""
Try
Dim i As Integer
For i = 0 To My.Settings.NumericUpDownEndTicket
footSpace = footSpace & CRLF
Next
Catch ex As Exception

End Try
SEND = SEND & strOutputData & footSpace & CRLF & CRLF & GS & "V" & Chr(1) '& LF & LF & LF & LF & LF
sw.Write(SEND)
If My.Settings.LOG_LPT Then
Dim log_filename As String = AppPath & "\" & Now.Year & Now.Month & "OrderLogLPT.txt"
My.Computer.FileSystem.WriteAllText(log_filename, strOutputData & Chr(13) & Chr(10), True)
End If

'If cajon Then sw.Write((Chr(27)).ToString() + "p" + (Chr(0)).ToString() + ((Chr(60))).ToString() + ((Chr(255))).ToString()) '''''''开钱箱
sw.Close()
fs.Close()
End If
Catch ex As Exception
MsgBox("没有连接打印机!")
End Try

如何使用 Visual Basic.NET 存取序列及平行連接埠

微軟官網:如何使用 Visual Basic.NET 存取序列及平行連接埠
--------

MP3 To Audio CD Burner Free

MP3 燒到 CD 片 ; 真是簡單又好用穩定,且是免費的唷

官方網址 Free download audio editor,cd mp3 converter

2011年8月3日 星期三

2款利用Excel當資料集的報表

1.
快逸报表软件-免费、快速开发WEB报表的JAVA报表工具

2.
数新软件 - 快乐报表 - 创造数据新价值

ODBC 與 DSN 簡介

ODBC 與 DSN 簡介

Visual Basic & ADO Tutorial 使用 DSN 連線

Visual Basic & ADO Tutorial

這篇真是精緻

access 網路共用,連線字串

1.
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\xxx.xxx.xxx.xxx\db$\test.mdb;Persist Security Info=False

2.
cnn.open "Provider=Microsoft.Jet.OLEDB.4.0;data source=\\192.168.0.1\someshare\mydatabase.mdb;"

3.
DAO
Set db = DAO.OpenDatabase("\\192.168.0.1\SHARENAME\Database.MDB", False, False, ";pwd=LetMeIn")

ADO
cnn.open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\192.168.0.1\SHARENAME\Database.MDB;Jet OLEDB:Database Password= LetMeIn"

ADO Connection String Samples

ADO Connection String Samples

2011年8月2日 星期二

如何發佈.net的DLL到Assembly

在Dll目录新建文本文档,修改文件后缀名为bat。粘贴下面代码:
echo off
for %%c in (*.dll) do gacutil /u %%c
for %%c in (*.dll) do sn -Vr %%c
for %%c in (*.dll) do gacutil /if %%c
for %%c in (*.dll) do sn -Vu %%c
echo 已经注册到 WINDOWS\assembly
echo on
pause
需要复制X:\Program Files\Microsoft SDKs\Windows\v6.0A\bin目录下面的 sn.exe 和 gacutil.exe 到DLL目录。X为系统盘,v6.0A为.net版本号。