星期四, 2月 26, 2009

InstallShield 將'必要條件' 來源設為與source相同位置

版本: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月 17, 2009

當系統程式掛時 給於使用者提示

就在系統掛時 還可以給個提示...
說是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,讓聽眾重覆複習加深印像

星期日, 2月 15, 2009

js顯示loading gif 動畫不會動

利用一個click事件
要顯示loading動畫的gif
可是圖片卻會卡住不會動
就像沒開thread一樣的卡住畫面

想了半天還是不知為了
後來看了程式碼
&lt a href="javascript:void(0);"&gt &lt img src="xx"&gt
當初利用anchor tag來當做click事件的元件
其中javascript:void(0) 是當初為了取代# 而用
就在亂試之下,改回#字後 重新click居然可以了
真是感動...
先寫下了 免得以後又發生

星期六, 2月 14, 2009

.Net Process相關應用

.net的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 來下
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
[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 系統調校秘技

星期五, 2月 06, 2009

USB轉Comport時 查DeviceID及佔用的Comport name

利用WQL查詢
位置:「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已安裝的軟體

找某軟體是否已安裝

  1. 先取得軟體安裝路徑
    可利用regedit.exe,到LocalMachine下的Software查軟體安裝註冊表
    比如說要查Prolific Technology INC 公司的 PL-2303 USB-to-Serial
    得知路徑為
    string path = "Prolific Technology INC\PL-2303 USB-to-Serial";
  2. 程式寫法
    程式的話,就可以透過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
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