版本:InstallShield 2009,2010 - Premier or Professional
設為跟source相同位置後,就是要下載相關的檔案
1. 設定必要條件
在Project Assistant裡勾選完「必要條件」(Prerequirist)
2. 啟動Release Wizard
Premier及Professional都可以到「Installation Designer」界面
再點選底下的 「Meda/Releases」
右側會出現「Releases」的樹狀圖,再其右鍵「Release Wizard」
3.設定"必要條件"資料來源
勾選Extract from Setup.exe
這時便會要求要下載"必要條件"
4.勾選要下載的"必要條件"
一步步往下做,就會發現Wizard會詢問了
過程中選擇.net framework時,勾選符合語系的檔, 另外原文版的也要勾選
p.s. 原文的.net framework為「.Net Framework Version X.X Redistributable Package」
找 了好久...
選好後,下一步 便會自動下載啦
p.s 直接在Releases右鍵Release Wizard是會產生一個新的Build Installation程序
如果要 利用Project Assistant的Build Installation產生安裝檔
要在該樹狀結構選擇 「PROJECT_ASSISTANT」底下的檔右鍵Project Assistant
如果沒看到「PROJECT_ASSISTANT」,就先利用Project Assistant產生一次安裝檔後,就會出現了
p.s. Express版本沒試過
星期四, 2月 26, 2009
星期二, 2月 17, 2009
當系統程式掛時 給於使用者提示
就在系統掛時 還可以給個提示...
說是windows有問題....不是我寫的程式掛了 哈
1.先catch exception
系統會掛 通常發生在exception發生了,但沒有catch到
所以可以用ThreadException來抓到沒有handle到的excpetion
而Application.ThreadException只能handle到主執行緒上的Exception
當有thread或某些情況下,這event就不會被觸發
所以得另外用AppDomain.CurrentDomain.UnhandledException
細節查關鍵字就可以找到了
2.Report Error
*註
UnhandledExceptionEvent在執行編譯過release下的exe才會抓到
UnhandledExceptionEventdebug的抓不到,而ThreadExceptionEvent好像debug模式下可以
Reference
C# Tutorial - Dealing With Unhandled Exceptions
如何在程序中友好提示錯誤
說是windows有問題....不是我寫的程式掛了 哈
1.先catch exception
系統會掛 通常發生在exception發生了,但沒有catch到
所以可以用ThreadException來抓到沒有handle到的excpetion
Application.ThreadException += new ThreadExceptionEventHandler(HandleException);
而Application.ThreadException只能handle到主執行緒上的Exception
當有thread或某些情況下,這event就不會被觸發
所以得另外用AppDomain.CurrentDomain.UnhandledException
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(UnhandledException);
細節查關鍵字就可以找到了
2.Report Error
*註
UnhandledExceptionEvent在執行編譯過release下的exe才會抓到
UnhandledExceptionEventdebug的抓不到,而ThreadExceptionEvent好像debug模式下可以
Reference
C# Tutorial - Dealing With Unhandled Exceptions
如何在程序中友好提示錯誤
演講
事前準備
1.聽眾背景
決定topic及內容深淺
2.可用媒介
先探聽場合可用的媒介,以免準備了投影片,現在卻沒投影機可用
3.內容
不要讓聽眾讀,特別是投影片,遵守6*6原則
英文每行不超過6個字,每頁不超過6行
中文每行不超過6個詞, ...
投影片速度 1頁/1分 ,太多聽眾不會有印像
演講時
1.站姿:自然即可
2.視線接觸:與聽眾有眼神接觸,抓住他的注意
3.距離:看到想睡的人,可以走近他,讓他不敢睡
4.速度:
10~20人,120~150字/分
30人以上,90~120字/分
5.加深印像
可重覆的帶重要的topic,讓聽眾重覆複習加深印像
1.聽眾背景
決定topic及內容深淺
2.可用媒介
先探聽場合可用的媒介,以免準備了投影片,現在卻沒投影機可用
3.內容
不要讓聽眾讀,特別是投影片,遵守6*6原則
英文每行不超過6個字,每頁不超過6行
中文每行不超過6個詞, ...
投影片速度 1頁/1分 ,太多聽眾不會有印像
演講時
1.站姿:自然即可
2.視線接觸:與聽眾有眼神接觸,抓住他的注意
3.距離:看到想睡的人,可以走近他,讓他不敢睡
4.速度:
10~20人,120~150字/分
30人以上,90~120字/分
5.加深印像
可重覆的帶重要的topic,讓聽眾重覆複習加深印像
星期日, 2月 15, 2009
js顯示loading gif 動畫不會動
利用一個click事件
要顯示loading動畫的gif
可是圖片卻會卡住不會動
就像沒開thread一樣的卡住畫面
想了半天還是不知為了
後來看了程式碼
當初利用anchor tag來當做click事件的元件
其中javascript:void(0) 是當初為了取代# 而用
就在亂試之下,改回#字後 重新click居然可以了
真是感動...
先寫下了 免得以後又發生
要顯示loading動畫的gif
可是圖片卻會卡住不會動
就像沒開thread一樣的卡住畫面
想了半天還是不知為了
後來看了程式碼
< a href="javascript:void(0);"> < img src="xx">
當初利用anchor tag來當做click事件的元件
其中javascript:void(0) 是當初為了取代# 而用
就在亂試之下,改回#字後 重新click居然可以了
真是感動...
先寫下了 免得以後又發生
星期六, 2月 14, 2009
.Net Process相關應用
.net的Process
除了可以自己new起來外
還加參數
偵測Process結束事件
除了可以自己new起來外
還加參數
myProc.StartInfo.Arguments = "xx";
偵測Process結束事件
myProc.Exited += new EventHandler(myProcExit);
星期五, 2月 13, 2009
讓程式在Vista下 以「系統管理者」身份執行
在Vista下
當程式需要有系統管理者權限時
Vista是通過manifest來判斷所需的權限
也就是 YourProgram.exe 就會看同位置下的 YourProgram.exe.manifest (xml檔)
主要有2個步驟
1.先編這個xml檔
(1)複製「專案/Properties」下的app.manifest
(2)再把裡的name修改成YourProgram.exe
(3)把的level改成requuirAdministrator
*如果沒app.manifest這個檔案,右鍵「專案/屬性」下的分頁「安全性」,把啟用ClickOnce安全性設定取消就會出現了
2.編完後,利用mt.exe 來下
*編完得到失敗結果:
Code:9009 => 找不到mt.exe , 找出mt.exe 再加入
通常會在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 底下找到mt.exe
到環境變數裡Path設定吧
Code:31 => 還不是很確定,就多按幾下 或切個畫面就可以了
Reference中有詳細的圖文說明
就照著步驟做吧
「就感心」的是 筆者有教在「建置後事件命令列」中,放進步驟2
也就是當你的程式compile後,就會自動來執行這段指令。
不然多個步驟 忘了編就麻煩了
*將manifest檔放到bin/Release下
Reference
當程式需要有系統管理者權限時
Vista是通過manifest來判斷所需的權限
也就是 YourProgram.exe 就會看同位置下的 YourProgram.exe.manifest (xml檔)
主要有2個步驟
1.先編這個xml檔
(1)複製「專案/Properties」下的app.manifest
(2)再把
(3)把
*如果沒app.manifest這個檔案,右鍵「專案/屬性」下的分頁「安全性」,把啟用ClickOnce安全性設定取消就會出現了
2.編完後,利用mt.exe 來下
mt -manifest YourProgram.exe.manifest -outputresource:YourProgram.exe
*編完得到失敗結果:
Code:9009 => 找不到mt.exe , 找出mt.exe 再加入
通常會在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 底下找到mt.exe
到環境變數裡Path設定吧
C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin;
Code:31 => 還不是很確定,就多按幾下 或切個畫面就可以了
Reference中有詳細的圖文說明
就照著步驟做吧
「就感心」的是 筆者有教在「建置後事件命令列」中,放進步驟2
也就是當你的程式compile後,就會自動來執行這段指令。
不然多個步驟 忘了編就麻煩了
*將manifest檔放到bin/Release下
Reference
如何讓你的C#程式在Vista上以「系統管理者身分」執行
星期四, 2月 12, 2009
利用WM_DEVICECHANGE抓Port Name
除了用監聽Usb event外
還可利用WM_DEVICECHANGE來攔截相關訊息
由於網路上多是C/C++的實作
真不容易找到C#的 但又沒有完整的用C#查Port Name
在Reference[2]有相關的教學,但沒有查Port Name
就看了MSDN的說明,依樣畫葫蘆做出來了
在Reference[2]裡有做了 Win32的class
然後在DBT_DEVICEARRIVAL裡,再改成用剛寫的StructLayout DEV_BROADCAST_PORT
{
Marshal.PtrToStructure(m.LParam, typeof(Win32.DEV_BROADCAST_HDR));
int dbccSize = Marshal.ReadInt32(m.LParam, 0);
int devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == Win32.DBT_DEVTYP_PORT)
{
Win32.DEV_BROADCAST_PORT dip = (Win32.DEV_BROADCAST_PORT)
Marshal.PtrToStructure(m.LParam, typeof(Win32.DEV_BROADCAST_PORT));
string csTemp = "COM" + dip.dbcp_name[6].ToString(); //dbcp_name是一串字,在第6個是COM的Number
//MessageBox.Show(csTemp + " arrived/removed");
listBox1.Items.Add(csTemp + " arrived/removed");
}
}
Reference
1.MSDN WM_DEVICECHANGE Message MSDN的說明
2.Retrieving dbcc_name string from a DEV_BROADCAST_DEVICEINTERFACE structure 有VB及C#的實作
還可利用WM_DEVICECHANGE來攔截相關訊息
由於網路上多是C/C++的實作
真不容易找到C#的 但又沒有完整的用C#查Port Name
在Reference[2]有相關的教學,但沒有查Port Name
就看了MSDN的說明,依樣畫葫蘆做出來了
在Reference[2]裡有做了 Win32的class
[StructLayout(LayoutKind.Sequential)] public class DEV_BROADCAST_PORT {
public int dbcp_size;
public int dbcp_devicetype;
public int dbcp_reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public char[] dbcp_name;
}
然後在DBT_DEVICEARRIVAL裡,再改成用剛寫的StructLayout DEV_BROADCAST_PORT
if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL)
{
Marshal.PtrToStructure(m.LParam, typeof(Win32.DEV_BROADCAST_HDR));
int dbccSize = Marshal.ReadInt32(m.LParam, 0);
int devType = Marshal.ReadInt32(m.LParam, 4);
if (devType == Win32.DBT_DEVTYP_PORT)
{
Win32.DEV_BROADCAST_PORT dip = (Win32.DEV_BROADCAST_PORT)
Marshal.PtrToStructure(m.LParam, typeof(Win32.DEV_BROADCAST_PORT));
string csTemp = "COM" + dip.dbcp_name[6].ToString(); //dbcp_name是一串字,在第6個是COM的Number
//MessageBox.Show(csTemp + " arrived/removed");
listBox1.Items.Add(csTemp + " arrived/removed");
}
}
Reference
1.MSDN WM_DEVICECHANGE Message MSDN的說明
2.Retrieving dbcc_name string from a DEV_BROADCAST_DEVICEINTERFACE structure 有VB及C#的實作
星期二, 2月 10, 2009
開啟網芳超慢
不知為何每次要開啟網芳就很慢
但利用ip位置 直接開啟 倒是挺快
上網survey了一下
利用下面的方法 果然有變快
把 W2K、WinXP 登錄檔中
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RemoteComputer\NameSpace
下面的 {D6277990-4C6A-11CF-8D87-00AA0060F5BF} 刪除,
不需要重開機馬上就見效,Win2k 及 WinXP 均有效。
Reference
winxp 網路芳鄰開啟超慢
Windows XP 系統調校秘技
但利用ip位置 直接開啟 倒是挺快
上網survey了一下
利用下面的方法 果然有變快
把 W2K、WinXP 登錄檔中
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RemoteComputer\NameSpace
下面的 {D6277990-4C6A-11CF-8D87-00AA0060F5BF} 刪除,
不需要重開機馬上就見效,Win2k 及 WinXP 均有效。
Reference
winxp 網路芳鄰開啟超慢
Windows XP 系統調校秘技
星期五, 2月 06, 2009
USB轉Comport時 查DeviceID及佔用的Comport name
利用WQL查詢
位置:「root\\WMI」下的「MSSerial_PortName」
MSSerial_PortName下有三個屬性
1.Active
2.InstanceName //即DeviceID
3.PortName //佔用的Port name
找USB插入的佔用的Port name
p.s 在vista下 會因為UAC (User Account Control) 而會遇到Access Denied
解決方法
1.以 run as administrator 的方式執行就能動
2.到「控制台/使用者帳戶」 把UAC(使用者帳戶控制)關閉,就可以了
3.想要程式自動設好... 讓程式在Vista下 以「系統管理者」身份執行
Reference
1.A Useful WMI Tool & How To Find USB to Serial Adaptors
2.Vista 底下如何加入WMI provider dll?
位置:「root\\WMI」下的「MSSerial_PortName」
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSSerial_PortName");
MSSerial_PortName下有三個屬性
1.Active
2.InstanceName //即DeviceID
3.PortName //佔用的Port name
找USB插入的佔用的Port name
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSSerial_PortName Where InstanceName like '%VID_067B&PID_2303%'"); //這裡是利用Prolific做的驅動程式
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSSerial_PortName instance");
Console.WriteLine("Find Beacon at Port:{0}", queryObj["PortName"]);
Console.WriteLine("-----------------------------------");
}
p.s 在vista下 會因為UAC (User Account Control) 而會遇到Access Denied
解決方法
1.以 run as administrator 的方式執行就能動
2.到「控制台/使用者帳戶」 把UAC(使用者帳戶控制)關閉,就可以了
3.想要程式自動設好... 讓程式在Vista下 以「系統管理者」身份執行
Reference
1.A Useful WMI Tool & How To Find USB to Serial Adaptors
2.Vista 底下如何加入WMI provider dll?
星期三, 2月 04, 2009
C#查詢Windows已安裝的軟體
找某軟體是否已安裝
以下為完整範例
*Clickonce安裝位置
利用clickonce安裝的軟體不會在LocalMachine下的Software
而會是在CurrentUser的Microsoft\Windows\CurrentVersion\Uninstall下
- 先取得軟體安裝路徑
可利用regedit.exe,到LocalMachine下的Software查軟體安裝註冊表
比如說要查Prolific Technology INC 公司的 PL-2303 USB-to-Serial
得知路徑為
string path = "Prolific Technology INC\PL-2303 USB-to-Serial";
- 程式寫法
程式的話,就可以透過Microsoft.Win32.Registry 達成
比如說要查Prolific Technology INC 公司的 PL-2303 USB-to-Serial
在程式註冊表中會在SOFTWARE資料夾中Prolific Technology下找到PL-2303 USB-to-Serial
如果可以找到代表有安裝,所以程式可寫成
regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE", true).OpenSubKey(@"SOFTWARE下的路徑", true);
以下為完整範例
//先引用Microsoft.Win32 using Microsoft.Win32; public bool findSoftwareInstalled() { try { //找PL-2303 USB-to-Serial 是否安裝 string path = "Prolific Technology INC\PL-2303 USB-to-Serial"; RegistryKey regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE", true).OpenSubKey(@path , true); if (regkey == null) { //"註冊表內無儲存安裝訊息"; return false; } else { //已安裝,可利用regkey.GetValue("xxx").ToString(); 取得相關資訊 return true; } } catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); return false; } }
*Clickonce安裝位置
利用clickonce安裝的軟體不會在LocalMachine下的Software
而會是在CurrentUser的Microsoft\Windows\CurrentVersion\Uninstall下
利用WQL 找Windows裡相關資訊
先引用WQL所在的namespace
找Driver
References:
可直接下拉查詢相關的資訊
WMI Code Creator v1.0
using System.Management;
//要先在專案的參考加入System.Management找Driver
public bool getDrivers()
{
ManagementScope scope = new ManagementScope(@"root\CIMV2");
ObjectQuery query = new ObjectQuery("WQL", "SELECT * FROM Win32_SystemDriver");
ManagementObjectSearcher search = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection col = search.Get();
if (col.Count == 0)
{
return false;
}
Console.WriteLine("Win32_SystemDriver instance (Total Found:{0})", col.Count.ToString());
Console.WriteLine("-----------------------------------");
foreach (ManagementObject obj in col)
{
string driverlist = obj.ToString().ToUpper();
if (driverlist.Contains("SER2PL")) //此例是找SER2PL,更換你要的Driver Name
{
Console.WriteLine("找到Driver已安裝,Name: {0}", obj.ToString()); //name 是 Unique identifier for the service
return true;
}
/*
//印出所有屬性
foreach (PropertyData propertyData in obj.Properties)
{
ManagementBaseObject mbo = null;
if ((mbo = propertyData.Value as ManagementBaseObject) != null)
{
foreach (PropertyData prop in mbo.Properties)
Console.WriteLine("{0} - {1}", prop.Name, prop.Value);
}
}
* */
}
search.Dispose();
col.Dispose();
return false;
}
References:
可直接下拉查詢相關的資訊
WMI Code Creator v1.0
訂閱:
文章 (Atom)