使用VS自帶的打包工具,制作winform安裝項目
開發環境:VS2008 Access
操作系統:Windows XP
開發語言:C#
項目名稱:**管理系統
步驟:
1、打開開發環境VS2010,新建項目,選擇其他項目類型,再選擇“安裝項目”。
注:如果安裝項目在你的項目中,建議使用項目輸出的形式。這樣項目變更時,安裝程序也會相應的變更。如下圖,主輸出一定要選擇你要打包的項目。
3、添加項目所需文件。這里有兩個文件夾需要注意(DataBase和Report),因為DataBase是存儲項目數據庫,而Report是存儲項目所需報表文件.rpt,因此在應用程序文件夾中也需要建同名的文件夾,並添加所需文件。
4、為了在開始程序菜單中和桌面應用程序中看到安裝程序,這里我們需要項目創建快捷方式。右鍵選擇可執行文件(PersonFinance.exe),創建快捷方式,進行重命名“**管理系統” ,將該快捷方式拖放到“用戶的程序菜單”中。重復該步驟將新建的快捷方式添加到“用戶桌面”文件夾中,最好在用戶菜單中建立一個文件夾存放安裝程序。
5、設置系統必備。右鍵選擇安裝項目,進入屬性頁中,單擊“系統必備”按鈕,進入系統必備對話框;勾選“創建用於安裝系統必備組件的安裝程序”,在安裝系統必備組件列表中,選擇(1)Windows Installer 3.1(必選) (2).NET Framework 3.5(可選)(3)Crystal Report Basic for Visual Studio 2008 (可選)項目中用到了水晶報表就需要勾選此項。
6、卸載程序。安裝包做好后不能只有安裝程序,還需要有卸載程序。
(1)在“C:\Windows\system32”路徑下,找到msiexec.exe添加到應用程序文件夾中,創建快捷方式,並命名為“卸載管理系統”或“Uninstall” 。
(2)選擇安裝項目的ProductCode
右鍵選擇卸載程序的快捷方式,進入屬性,在Arguments選項中,輸入/x {ProductCode};例如:/x {6931BD71-5C5E-4DA1-A861-14C7D1A78B97},將卸載程序同時存放到用戶的開始菜單文件夾中。
7、更改安裝程序屬性。右鍵選擇安裝項目屬性,可以設置項目作者及名稱,其他屬性信息可以根據實際情況進行設置。
8、生成安裝項目。
說明及小結:
(1).NET Framework框架是可選的,不一定說你采用的是VS2008開發就必須使用.NET Framework3.5,只要你在程序中沒有使用到.NET Framework3.5的特性,那么你選擇框架時是可以選擇2.0的。更改方式:在安裝項目下面有個檢測到的依賴項文件,雙擊里面的Microsoft .NET Framework,進入了啟動條件選擇卡,右鍵選擇.NET Framework在Version中選擇你需要的.NET Framework框架。
C# winform打包數據庫
實現效果:安裝項目時直接附加數據庫。
1、在安裝項目所在解決方案中新建一個類庫項目【InstallDB】,刪除Class1.cs,新建一個安裝程序類【InstallDB.cs】,在類中編寫附加數據庫代碼。
編寫代碼:
/// 附加數據庫方法
/// </summary>
/// <param name="strSql"> 連接數據庫字符串,連接master系統數據庫 </param>
/// <param name="DataName"> 數據庫名字 </param>
/// <param name="strMdf"> 數據庫文件MDF的路徑 </param>
/// <param name="strLdf"> 數據庫文件LDF的路徑 </param>
/// <param name="path"> 安裝目錄 </param>
private void CreateDataBase( string strSql, string DataName, string strMdf, string strLdf, string path)
{
SqlConnection myConn = new SqlConnection(strSql);
String str = null ;
try
{
str = " EXEC sp_attach_db @dbname=' " + DataName + " ',@filename1=' " + strMdf + " ',@filename2=' " + strLdf + " ' " ;
SqlCommand myCommand = new SqlCommand(str, myConn);
myConn.Open();
myCommand.ExecuteNonQuery();
MessageBox.Show( " 數據庫安裝成功!點擊確定繼續 " ); // 需Using System.Windows.Forms
}
catch (Exception e)
{
MessageBox.Show( " 數據庫安裝失敗! " + e.Message + " \n\n " + " 您可以手動附加數據 " );
System.Diagnostics.Process.Start(path); // 打開安裝目錄
}
finally
{
myConn.Close();
}
}
public override void Install(System.Collections.IDictionary stateSaver)
{
string dbname = this .Context.Parameters[ " dbname " ]; // 數據庫名稱
string server = this .Context.Parameters[ " server " ]; // 服務器名稱
string uid = this .Context.Parameters[ " user " ]; // SQlServer用戶名
string pwd = this .Context.Parameters[ " pwd " ]; // 密碼
string path = this .Context.Parameters[ " targetdir " ]; // 安裝目錄
string strSql = " Server= " + server + " ;User Id= " + uid + " ;Password= " + pwd + " ;Database=master; " ; // 連接數據庫字符串
if (uid.Length == 0 && pwd.Length == 0 )
{
strSql = " Server= " + server + " ;Database=master;Trusted_Connection=True; " ; // Windows身份驗證
}
string DataName = " SCDB8 " ; // 數據庫名
if (dbname != null )
{
DataName = dbname;
}
string strMdf = path + DataName + " .mdf " ; // MDF文件路徑,這里需注意文件名要與剛添加的數據庫文件名一樣!
string strLdf = path + DataName + " .ldf " ; // LDF文件路徑
SetFullControl(strMdf);
SetFullControl(strLdf);
base .Install(stateSaver);
this .CreateDataBase(strSql, DataName, strMdf, strLdf, path); // 開始創建數據庫
}
private static void SetFullControl( string path)
{
FileInfo info = new FileInfo(path);
FileSecurity fs = info.GetAccessControl();
fs.AddAccessRule( new FileSystemAccessRule( " Everyone " , FileSystemRights.FullControl, AccessControlType.Allow));
info.SetAccessControl(fs);
}
2、在安裝項目上右鍵,【視圖】->【用戶界面】:
在用戶界面中,右鍵【啟動】->【添加對話框】->選擇【文本框(A) 】->確定。
3、右鍵文本框(A),將其上移到歡迎使用下面:
右鍵選擇【屬性】,填寫信息:
4、在安裝項目上右鍵,【視圖】->【自定義操作】,右鍵【自定義操作界面】的【安裝】節點,【添加自定義操作】,在彈出的對話框中選擇應用程序文件夾,再點擊右側的【添加輸出】,選擇安裝項目,默認還是主輸出,【確定】。
5、右鍵【主輸出來自InstallDB】,進入屬性界面,在【CustomActionData】屬性里輸入下面的內容:
/dbname=[DBNAME] /server=[SERVER] /user=[USER] /pwd=[PWD] /targetdir="[TARGETDIR]\"
說明:其中前四個方括號中的大寫字母為上面輸入的四個EditProPerty屬性。最后一個targetdir代表安裝文件的目錄路徑。
6、在安裝項目中右鍵,【添加】->【文件】,選擇你的MDF和LDF文件,就是需要附加的數據庫文件。
自己實現數據庫配置
上面程序中通過【添加自定義操作】實現數據庫輸入的。如果我們想在安裝時可以讓用戶有測試數據庫連接功能,並且是通過SQL語句創建數據庫,那可以在自定義操作的類庫中添加一個Form界面,通過它來完成。如下界面:
在自定義類庫中編寫代碼。
此代碼的主要功能是:
(1)創建數據庫
(2)創建數據庫表、存儲過程等內容
(3)修改安裝程序配置文件
#region 參數
public static string _serverName { get; set; }
public static string _dbName { get; set; }
public static string _userName { get; set; }
public static string _password { get; set; }
private string _setupType { get; set; }
private string _targetDir { get; set; }
/// <summary>
/// 資源中創建表結構及數據的文件名
/// </summary>
private const string _StructureAndDataFileName = "CreateStructureData";
#endregion
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
//數據庫配置 界面
frmDb dbFrom = new frmDb();
DialogResult DialogResult = dbFrom.ShowDialog();
if (DialogResult != DialogResult.OK)
{
throw new InstallException("用戶取消安裝!");
}
SqlConnection connection = null;
connection = TestConnection(_serverName, "master", _userName, _password);
//創建數據庫
int result = this.CreateDataBase(connection);
if (result > 0)
{
CloseConnection(connection);
//使用創建的數據庫
connection = TestConnection(_serverName, _dbName, _userName, _password);
CreateStructureAndData(connection);
}
//創建表及增加數據
CreateStructureAndData(connection);
//為空是表示有錯誤
if (connection != null)
{
ModifyConfig();
}
//關閉數據庫
CloseConnection(connection);
}
/// <summary>
/// 關閉數據庫
/// </summary>
/// <param name="connection"></param>
private void CloseConnection(SqlConnection connection)
{
if (connection != null)
{
//關閉數據庫
if (connection.State != System.Data.ConnectionState.Closed)
{
connection.Close();
connection.Dispose();
}
}
}
/// <summary>
/// 測試連接
/// </summary>
/// <param name="serverName"></param>
/// <param name="dbName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
private SqlConnection TestConnection(string serverName, string dbName, string userName, string password)
{
string connectionString = GetConnectionString(serverName, dbName, userName, password);
SqlConnection connection = new SqlConnection(connectionString);
try
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
return connection;
}
catch
{
CloseConnection(connection);
throw new InstallException("安裝失敗!\n數據庫配置有誤,請正確配置信息!");
}
}
/// <summary>
/// 得到連接字符串
/// </summary>
/// <param name="serverName"></param>
/// <param name="dbName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
private string GetConnectionString(string serverName, string dbName, string userName, string password)
{
string connectionString = "Data Source={0};Initial Catalog={1};User ID={2};Password={3}";
connectionString = string.Format(connectionString, serverName, dbName, userName, password);
return connectionString;
}
/// <summary>
/// 創建數據庫
/// </summary>
/// <param name="serverName"></param>
/// <param name="dbName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="connection"></param>
/// <param name="stateSaver"></param>
public int CreateDataBase(SqlConnection connection)
{
int result = -1;
connection.ChangeDatabase("master");
string createDBSql = @" if Exists(select 1 from sysdatabases where [name]=N'{0}')
begin
drop database {0}
end
GO
CREATE DATABASE {0} ";
createDBSql = string.Format(createDBSql, _dbName);
//因為有Go在SQLCommand中不認識,所以以Go為分隔符取sql語句
char[] split = new char[] { 'G', 'O' };
string[] sqlList = createDBSql.Split(split);
SqlCommand command = null;
try
{
command = connection.CreateCommand();
command.CommandType = System.Data.CommandType.Text;
foreach (string sqlItem in sqlList)
{
if (sqlItem.Length > 2)
{
command.CommandText = sqlItem;
result = command.ExecuteNonQuery();
}
}
return result;
}
catch
{
CloseConnection(connection);
command.Dispose();
throw new InstallException("安裝失敗!\n數據庫配置不正確!");
}
}
/// <summary>
/// 分隔SQL語句
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
private string[] splitSql(string sql)
{
Regex regex = new Regex("^GO", RegexOptions.IgnoreCase | RegexOptions.Multiline);
string[] sqlList = regex.Split(sql.ToUpper());
return sqlList;
}
/// <summary>
/// 創建表結構及數據
/// </summary>
/// <param name="connection"></param>
public void CreateStructureAndData(SqlConnection connection)
{
StringBuilder builder = new StringBuilder();
SqlCommand command = null;
//錯誤標志
bool isHaveError = false;
try
{
ResourceManager manager = new ResourceManager(typeof(YXSchoolSetupService.Properties.Resources));
if (manager != null)
{
connection.ChangeDatabase(_dbName);
command = connection.CreateCommand();
command.CommandType = CommandType.Text;
builder.Append(manager.GetString(_StructureAndDataFileName));
string[] sqlList = splitSql(builder.ToString());
foreach (string sqlItem in sqlList)
{
if (sqlItem.Length > 2)
{
command.CommandText = sqlItem;
command.ExecuteNonQuery();
}
}
}
else
{
isHaveError = true;
}
if (true == isHaveError)
{
CloseConnection(connection);
command.Dispose();
throw new InstallException("數據庫配置失敗!\n請與開發人員聯系!");
}
}
catch
{
CloseConnection(connection);
command.Dispose();
throw new InstallException("數據庫配置失敗!\n請與開發人員聯系!");
}
}
#region 修改web.config的連接數據庫的字符串
public void ModifyConfig()
{
System.IO.FileInfo FileInfo = new System.IO.FileInfo(_targetDir + "YXData.yixian");
if (!FileInfo.Exists) //不存在web.config文件
{
throw new InstallException("沒有找到文統配置文件!");
}
System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load(FileInfo.FullName);
try
{
XmlElement element = xmlDocument.DocumentElement;
if (element != null)
{
foreach (XmlNode node in element)
{
switch (node.Name)
{
case "dbserver":
node.InnerText = _serverName;
break;
case "dbname":
node.InnerText = _dbName;
break;
case "dbpassword":
node.InnerText = _password;
break;
case "dbuser":
node.InnerText = _userName;
break;
default:
break;
}
}
}
xmlDocument.Save(FileInfo.FullName);
}
catch
{
throw new InstallException("修改web.config配置文件失敗!");
}
}
#endregion
數據庫測試界面中的代碼:
/// 連接測試是否成功
/// </summary>
public bool isConnect { get ; set ; }
private void frmDb_Load( object sender, EventArgs e)
{
btnNext.Enabled = false ;
this .CenterToParent();
}
private void btnTest_Click( object sender, EventArgs e)
{ // 將得到配置值傳給主安裝程序類
string serverName = txbServer.Text.Trim();
DBInstaller._serverName = serverName;
string dbName = txbDbName.Text.Trim();
DBInstaller._dbName = dbName;
string userName = txbUserName.Text.Trim();
DBInstaller._userName = userName;
string password = txbPwd.Text.Trim();
DBInstaller._password = password;
isConnect = InstallCommon.TestConnection(serverName, dbName, userName, password); // 測試連接,此處調用其它類中的代碼。
if (isConnect == true )
{
lblInfo.Text = " 數據庫連接測試成功! " ;
btnNext.Enabled = true ;
}
else
{
btnNext.Enabled = false ;
lblInfo.Text = " 數據庫連接測試失敗! " ;
}
}
// 取消按鈕
private void btnCancel_Click( object sender, EventArgs e)
{
this .DialogResult = DialogResult.No;
this .Close();
}
// 下一步按鈕
private void btnNext_Click( object sender, EventArgs e)
{
if (isConnect)
{
this .DialogResult = DialogResult.OK;
}
this .Close();
}
原文地址: http://www.cnblogs.com/scottckt/archive/2011/05/14/2046313.html (有改動和完善)