星期二, 九月 29, 2009

Jump List很棒,但有時候還是需要快顯功能表

Windows 7可以讓使用者在工作列建立程式的捷徑,但這種情況若對程式捷徑按下滑鼠右鈕,所顯現的是『Jump List』。但,捷徑原本的快顯功能表呢?

我會將常用的程式訂選到工作列,但之前讓我困擾的是,若對這類工作列的程式捷徑按下滑鼠右鈕,所顯現的是『Jump List』,而非原本的快顯功能表。

難道這類捷徑無法顯現快顯功能表嗎?

不是,只是必須拐個彎:要先按住Shift按鍵,再對程式捷徑按下滑鼠右鈕,才會顯現快顯功能表。


[全文]

星期一, 九月 28, 2009

Windows 7內建Open Command Windows Here

我很喜歡Microsoft PowerToys for Windows XP裡的Open Command Windows Here,原本打算找找怎麼讓Windows 7也具備這項功能,但其實Windows 7已經內建這項功能了。

只是微軟讓使用者必須拐個彎才能看到這項功能:先按住Shift按鍵,再以滑鼠右鈕按下檔案總管裡的磁碟或資料夾項目。這時所顯現的快顯功能表,會多出一些項目,其中的『在此處開啟命令視窗』,就如同Microsoft PowerToys for Windows XP的Open Command Windows Here。

Windows_Explorer_Right_Click_Shift

按住Shift按鍵的快顯功能表多出的項目還有『在新處理程序開啟』和『複製路徑』。


[全文]

星期四, 九月 24, 2009

Windows SDK練習曲--Windows版本相關資訊 [Native Code] (2)

取得Windows版本相關資訊--Native Code(1)》曾提及取自Windows SDK 7的Getting the System Version主控台程式,這個程式用了許多Windows API取得Windows版本資訊,以下則將簡述這些API。

GetVersionEx

從Windows 2000就存在的GetVersionEx,是取得Windows版本資訊的基本函式。如果呼叫失敗,GetVersionEx會傳回0;呼叫成功則傳回非0。

GetVersionEx必須使用OSVERSIONINFO或OSVERSIONINFOEX結構作為參數,GetVersionEx會將取得的資訊置入作為參數的結構,包括Windows的主序號、次序號等。以下列出幾個Windows的主序號及次序號。

Windows 主序號.次序號
Windows 2000 5.0(用戶端及伺服端皆然)
Windows XP 5.1
Windows Server 2003 5.2
Windows Server 2003 R2 5.2
Windows Vista 6.0
Windows Server 2008 6.0
Windows 7 6.1
Windows Server 2008 R2 6.1


這支程式會用到OSVERSIONINFOEX的以下成員:

  • dwPlatformId:平台代號,其值若為VER_PLATFORM_WIN32_NT,表示NT平台。
  • dwMajorVersion:主版本序號
  • dwMinorVersion:次版本序號
  • wProductType:Windows作業系統的產品類型,有VER_NT_WORKSTATION、VER_NT_SERVER、VER_NT_DOMAIN_CONTROLLER等3種常數值。用來判斷Windows是用戶端還是伺服器版本。
  • wSuiteMask:Windows作業系統的組合方式,可以利用位元運算(遮罩)查得作業系統的詳細資訊。可以用來檢查伺服器版是不是Home Server、Datacenter或Enterprise等版本、用戶端版是不是家用版、或是不是Embedded版本。

關於GetVersionEx及OSVERSIONINFOEX,還可參考舊作《如何檢測各種Windows平台的版本資訊》的《利用GetVersionEx檢查Windows系統版本》、《GetVersionEx使用範例》、《OSVERSIONINFOEX結構剖析》、《GetVersionEx與OSVERSIONINFOEX搭配應用》等節。

GetNativeSystemInfo / GetSystemInfo

這兩個函式在這支程式的目的是偵測Windows版本是不是x86、x64或IA64。32位元程式要呼叫GetNativeSystemInfo,64位元程式要呼叫GetSystemInfo。GetNativeSystemInfo或GetSystemInfo需使用SYSTEM_INFO結構,而這支程式會用到結構中的wProcessorArchitecture成員,這個成員可以是以下常數值:

常數值 說明
PROCESSOR_ARCHITECTURE_AMD64 x64
PROCESSOR_ARCHITECTURE_IA64 IA64(Intel Itanium)
PROCESSOR_ARCHITECTURE_INTEL x86
PROCESSOR_ARCHITECTURE_UNKNOWN 未知

GetSystemMetrics

這個API會根據參數而傳回系統特定的公制單位或系統設定值。這支程式以下列方式檢查是不是Windows Server 2003 R2:

if( GetSystemMetrics(SM_SERVERR2) )

GetProductInfo

這是Vista及Windows Server 2008開始支援的API,可以根據傳入的主、次版本序號及主、次Service Pack版本序號,取得SKU(例如旗艦版還是企業版)。此函式實際上可取得的 SKU 不止這支程式所列,完整資訊可參考SDK文件。

參考資料:MSDN Getting the System Version


[全文]

星期三, 九月 23, 2009

Windows SDK練習曲--Windows版本相關資訊 [Native Code] (1)

程式可能需要取得Windows版本相關資訊,以下取自Windows SDK 7 Getting the System Version的主控台程式,或許可作為您的參考。

[2009/09/24更新]更新程式碼,會顯示版本的主序號和次序號。

這支程式一共用了GetVersionExGetSystemMetricsGetProductInfoGetNativeSystemInfo / GetSystemInfo等API(延伸閱讀:《取得Windows版本相關資訊--Native Code(2)》),能取得相當完整的版本資訊,包括序號、SKU、用戶端或伺服端、Service Pack'、Build Number等。

我是以Visual Studio 2008建立這支主控台程式(系統需先安裝Windows SDK)。以下分別是這支主控台程式在我的Windows 7及Windows XP的執行結果。

osInfo on Windows 7

osInfo-xp

這支程式取自Windows SDK 7的Getting the System Version,但以下的中文註解是我所加入。

   1:  // osInfo.cpp : 定義主控台應用程式的進入點。
   2:  //
   3:  
   4:  #include "stdafx.h"
   5:  #include <windows.h>
   6:  #include <tchar.h>
   7:  #include <stdio.h>
   8:  #include <strsafe.h>
   9:  
  10:  #pragma comment(lib, "User32.lib")
  11:  
  12:  #define BUFSIZE 256
  13:  
  14:  typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
  15:  typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
  16:  
  17:  BOOL GetOSDisplayString( LPTSTR pszOS)
  18:  {
  19:      // 宣告變數
  20:      OSVERSIONINFOEX osvi; // 呼叫GetVersionEx需要此結構,內存Windows版本相關資訊
  21:      SYSTEM_INFO si; // 呼叫GetNativeSystemInfo需要此結構,內存系統資訊
  22:      PGNSI pGNSI;
  23:      PGPI pGPI;
  24:      BOOL bOsVersionInfoEx;
  25:      DWORD dwType;
  26:      
  27:      ZeroMemory(&si, sizeof(SYSTEM_INFO));
  28:      ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  29:      
  30:      osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  31:  
  32:      // GetVersionEx 呼叫成功會傳回非0值
  33:      //
  34:      if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
  35:          // GetVersionEx 呼叫失敗,結束函式
  36:          return 1;
  37:  
  38:      // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise
  39:      // 呼叫 GetNativeSystemInfo 或 GetSystemInfo
  40:      pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
  41:      if(NULL != pGNSI)
  42:          pGNSI(&si);
  43:      else GetSystemInfo(&si); // 呼叫 GetNativeSystemInfo 失敗,改呼叫 GetSystemInfo
  44:  
  45:      // NT 平台且主版本序號大於 4 者,會符合以下條件式
  46:      // 這支程式僅支援 NT 平台且主版本序號大於 4 的 Windows
  47:      if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4 )
  48:      {
  49:          // 隨著以下的檢查,會一一將查到的資訊複製到 pszOS 字串
  50:          StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft "));
  51:  
  52:          // Test for the specific product.
  53:          // 先從主版本序號為 6 的產品開始檢
  54:          // 也就是 Vista / Windows Server 2008、Windows 7 / Windows Server 2008 R2
  55:          if ( osvi.dwMajorVersion == 6 )
  56:          {
  57:              // 如果次版本序號是 0,就是 Vista / Windows Server 2008
  58:              if( osvi.dwMinorVersion == 0 )
  59:              {
  60:                  // VER_NT_WORKSTATION 表示用戶端版
  61:                  if( osvi.wProductType == VER_NT_WORKSTATION )
  62:                      StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista (Ver 6.0) "));
  63:                  // 不然就是伺服器版
  64:                  else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 (Ver 6.0) " ));
  65:              }
  66:  
  67:              // 如果次版本序號是 1,就是 Windows 7 / Windows Server 2008 R2
  68:              if ( osvi.dwMinorVersion == 1 )
  69:              {
  70:                  if( osvi.wProductType == VER_NT_WORKSTATION )
  71:                      StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 (Ver 6.1) "));
  72:                  else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 (Ver 6.1) " ));
  73:              }
  74:              
  75:              // 呼叫 GetProductInfo,取得產品類型
  76:              pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
  77:              
  78:              pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
  79:              
  80:              // 根據 dwType 取得 SKU
  81:              // 實際上可取得的 SKU 不止以下所列,
  82:              // 完整資訊可參考 SDK 文件 GetProductInfo 的說明
  83:              switch( dwType )
  84:              {
  85:              case PRODUCT_ULTIMATE:
  86:                  StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" ));
  87:                  break;
  88:              case PRODUCT_HOME_PREMIUM:
  89:                  StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" ));
  90:                  break;
  91:              case PRODUCT_HOME_BASIC:
  92:                  StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" ));
  93:                  break;
  94:              case PRODUCT_ENTERPRISE:
  95:                  StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
  96:                  break;
  97:              case PRODUCT_BUSINESS:
  98:                  StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" ));
  99:                  break;
 100:              case PRODUCT_STARTER:
 101:                  StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" ));
 102:                  break;
 103:              case PRODUCT_CLUSTER_SERVER:
 104:                  StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" ));
 105:                  break;
 106:              case PRODUCT_DATACENTER_SERVER:
 107:                  StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" ));
 108:                  break;
 109:              case PRODUCT_DATACENTER_SERVER_CORE:
 110:                  StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" ));
 111:                  break;
 112:              case PRODUCT_ENTERPRISE_SERVER:
 113:                  StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
 114:                  break;
 115:              case PRODUCT_ENTERPRISE_SERVER_CORE:
 116:                  StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" ));
 117:                  break;
 118:              case PRODUCT_ENTERPRISE_SERVER_IA64:
 119:                  StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" ));
 120:                  break;
 121:              case PRODUCT_SMALLBUSINESS_SERVER:
 122:                  StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" ));
 123:                  break;
 124:              case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
 125:                  StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" ));
 126:                  break;
 127:              case PRODUCT_STANDARD_SERVER:
 128:                  StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" ));
 129:                  break;
 130:              case PRODUCT_STANDARD_SERVER_CORE:
 131:                  StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" ));
 132:                  break;
 133:              case PRODUCT_WEB_SERVER:
 134:                  StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" ));
 135:                  break;
 136:              }
 137:          }
 138:          
 139:          // 以下檢查主版本序號為 5 且次版本序號為 2 的產品
 140:          // 也就是 Windows Server 2003 或 Windows Server 2003 R2
 141:          if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
 142:          {
 143:              if( GetSystemMetrics(SM_SERVERR2) )
 144:                  StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2 (Ver 5.2), "));
 145:              else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER )
 146:                  StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003 (Ver 5.2) "));
 147:              else if ( osvi.wSuiteMask==VER_SUITE_WH_SERVER )
 148:                  StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Home Server (Ver 5.2) "));
 149:              else if( osvi.wProductType == VER_NT_WORKSTATION &&
 150:                  si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
 151:              {
 152:                  // Windows XP Professional x64 與 Windows Server 2003 是相同 codebase
 153:                  // 但 wProductType 是 VER_NT_WORKSTATION,
 154:                  // 且 wProcessorArchitecture 是 PROCESSOR_ARCHITECTURE_AMD64
 155:                  StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition (Ver 5.2) "));
 156:              }
 157:              // 以上皆非則為 Windows Server 2003
 158:              else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, "));
 159:                       
 160:              // Test for the server type.
 161:              // 檢查其他的伺服器版
 162:              if ( osvi.wProductType != VER_NT_WORKSTATION )
 163:              {
 164:                  if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
 165:                  {
 166:                      if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
 167:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" ));
 168:                      else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
 169:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" ));
 170:                  }
 171:  
 172:                  else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
 173:                  {
 174:                      if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
 175:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" ));
 176:                      else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
 177:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" ));
 178:                      else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" ));
 179:                  }
 180:                  else
 181:                  {
 182:                      if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
 183:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" ));
 184:                      else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
 185:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" ));
 186:                      else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
 187:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" ));
 188:                      else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
 189:                          StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" ));
 190:                      else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" ));
 191:                  }
 192:              }
 193:          }
 194:          
 195:          // 以下檢查主版本序號為 5 且次版本序號為 1 的產品
 196:          // 也就是 Windows XP
 197:          if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
 198:          {
 199:              StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP (Ver 5.1) "));
 200:              if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
 201:                  StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" ));
 202:              else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
 203:          }
 204:          
 205:          // 以下檢查主版本序號為 5 且次版本序號為 0 的產品
 206:          // 也就是 Windows 2000
 207:          if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
 208:          {
 209:              StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 (Ver 5.0) "));
 210:              
 211:              if ( osvi.wProductType == VER_NT_WORKSTATION )
 212:              {
 213:                  // 用戶端版本
 214:                  StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
 215:              }
 216:              else 
 217:              {
 218:                  // 伺服器版本
 219:                  if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
 220:                      StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" ));
 221:                  else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
 222:                      StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" ));
 223:                  else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" ));
 224:              }
 225:          }
 226:          
 227:          // Include service pack (if any) and build number.
 228:          // 取得 Service Pack 版本及組建編號
 229:          if( _tcslen(osvi.szCSDVersion) > 0 )
 230:          {
 231:              StringCchCat(pszOS, BUFSIZE, TEXT(" ") );
 232:              StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);
 233:          }
 234:          
 235:          TCHAR buf[80];
 236:          
 237:          StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);
 238:          StringCchCat(pszOS, BUFSIZE, buf);
 239:          
 240:          // 主版本序號 6 及 6 以上,再檢查是 x64 還是 x86
 241:          if ( osvi.dwMajorVersion >= 6 )
 242:          {
 243:              if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
 244:                  StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
 245:              else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
 246:                  StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));
 247:          }
 248:          
 249:          // 完成檢查,傳回 True
 250:          return TRUE; 
 251:     }
 252:     
 253:     else
 254:     {  
 255:         // 這支程式僅支援 NT 平台且主版本序號大於 4 的 Windows
 256:         printf( "This sample does not support this version of Windows.\n");
 257:         return FALSE;
 258:     }
 259:  }
 260:   
 261:  // 主控台程式的進入點
 262:  int __cdecl _tmain()
 263:  {
 264:      TCHAR szOS[BUFSIZE];
 265:      
 266:      // 呼叫 GetOSDisplayString
 267:      if( GetOSDisplayString( szOS ) )
 268:          // 呼叫成功即列出相關版本資訊
 269:          _tprintf( TEXT("\n%s\n"), szOS );
 270:  }

參考資料:MSDN Getting the System Version


[全文]

星期一, 九月 21, 2009

Windows SDK練習曲--簡介Windows SDK 7

每推出新的Windows版本,微軟大概也都會推出相對應的SDK—Vista之前稱為Platform SDK,從Vista開始改稱Windows SDK。

SDK也就是所謂的軟體開發套件(software development kit),是給開發者針對特定產品或平台編寫程式的工具。例如Java SDK或Windows SDK,內含編寫Java或Windows程式所需要的檔案。SDK所提供的檔案可能也會限定某種程式語言。

下載Windows SDK

微軟針對開發Windows所推出的Windows SDK,內容包含工具程式、文件、標頭檔、程式庫、範例程式。而從Vista開始改名的Windows SDK,除了名稱的改變,也開始將.NET Framework SDK併入Windows SDK(而且諸如Tablet PC SDK、Windows Media SDK也都併入)。此外,Windows SDK(或Platform SDK)通常也會維持回溯相容。

這次隨著Windows 7所推出的SDK(以下稱為Windows SDK 7),有x86、x64、IA-64(Itanium)等3種CPU平台的版本,而任一種CPU版本的Windows SDK 7,都能建置出這3種CPU平台的程式;也就是說,如果使用x86版本的Windows SDK 7,能建置出x86、x64、IA-64等3種平台的程式。

由於Windows SDK相當龐大--大約 1.5 GB,因此微軟除了提供完整的ISO檔下載,也提供Web Setup的方式:先下載、執行僅23 KB的winsdk_web.exe,您可透過這支小程式選擇欲安裝的SDK項目,而且可以只下載選取的項目。不過我還是習慣下載ISO檔,以下是3種CPU平台ISO檔的直接連結:

MSDN訂閱者也可以透過Subscriber Downloads下載到Windows SDK 7。但可能會讓人困惑的是,顯示在Download Center和Subscriber Downloads的名稱不同,所下載的檔名也不同:

  • Download Center:Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1
  • Subscriber Downloads:Windows Software Development Kit for Windows 7 and Windows Server 2008 R2

不過我比對了這兩處檔案的CRC和SHA1,發現完全相同,因此這兩個地方所下載的應該是相同的檔案。

支援的Windows與Visual Studio

Windows SDK 7支援Windows XP、Windows Server 2003(含R2)、Vista、Windows Server 2008、Windows 7、Windows Server 2008 R2等Windows,而且也支援.NET Framework 3.5 Service Pack 1。此外,Windows SDK 7與Visual Studio 2005 Service Pack 1、Visual Studio 2008 Service Pack 1(及其Express版本)相容。

安裝Windows SDK 7之前,最好先到Microsoft Update檢查、下載、安裝最新的更新檔,而且必須完全移除任何預覽版本的.NET Framework SDK、Platform SDK、Windows SDK,及其附屬。這些預覽版本的元件可能會與Windows SDK 7衝突,而造成安裝或某些功能失敗。

此外,如果欲以Windows SDK 7開發managed code,系統需安裝.NET Framework 3.5 SP1;如果要搭配Visual Studio,也應在安裝Windows SDK 7之前裝好Visual Studio,及相關的Service Pack。但請注意,若欲使用Visual Studio 2005,必須先安裝Windows SDK 7,再安裝Visual Studio 2005 SP1Visual Studio 2005 Extensions for .NET Framework 3.0

安裝Windows SDK 7

由於是ISO檔,因此必須先以虛擬光碟軟體掛載Windows 7 SDK的ISO檔,或者將ISO檔燒成DVD光碟。我的習慣是掛載ISO檔,並且使用MagicDisc 2.7 Build 106,它支援Windows 7,而且免費。

執行Windows SDK 7光碟根目錄裡的Setup.exe,即可開始安裝。安裝的過程必須同意軟體授權協議、可以選擇文件及工具的安裝資料夾,並且也可以選擇安裝選項(下圖為預設的安裝選項,也就是不安裝Redistributable Components)。

安裝之後會在『開始』功能表建置『Debugging Tools for Windows (x86)』和『Microsoft Windows SDK v7.0』資料夾,後者底下還有『Tools』和『Visual Studio Registration』等資料夾。

Windows SDK Configuration Tool

為了讓Visual Studio搭配Windows SDK,Windows SDK在安裝之後、使用之前,必須先執行Windows SDK提供的Windows SDK Configuration Tool;它在『開始/所有程式/Microsoft Windows SDK v7.0/Visual Studio Registration』資料夾(若是Vista及之後的Windows,系統裡的每位使用者皆須執行)。

Windows SDK Configuration Tool

如果是先安裝Windows 7 SDK,再安裝Visual Studio,需要執行Windows SDK Configuration Tool,將Windows 7 SDK指定給Visual Studio。如果像我在安裝Windows 7 SDK之前,系統裡已有舊版的Windows SDK 6.0A(這是隨Visual Studio 2008所安裝),也必須執行Windows SDK Configuration Tool,同樣也是將Windows SDK 7指定給Visual Studio。

參考資料


[全文]

星期五, 九月 18, 2009

Windows Virtual PC與Windows XP Mode的關係

Windows XP Mode是微軟針對Windows 7的個人使用者及中小企業用戶所提供的Windows XP相容性問題解決方案;如果需要升級到Windows 7,但又有非Windows XP不可的應用程式得執行,Windows XP Mode是個值得評估的選項。

Windows Virtual PC

Windows Virtual PC(以下簡稱WVPC)是Virtual PC 2007後繼新版本(主要的競爭對手是VMWare Workstation),能在主系統(host OS)產生出虛擬機器,使用者可將其他作業系統裝入虛擬機器,而成為客系統(guest OS)。

WVPC有兩項特殊的系統需求:一是安裝的硬體需支援虛擬技術(註:這已非強制條件,詳情請參閱Windows Virtual PC和Windows XP Mode不再需要HAV處理器),而且必須開啟開啟這項功能;另一項是主系統僅支援Windows 7,也就是WVPC只能安裝在Windows 7。

請留意,WVPC能裝在Windows 7的Home Basic、Home Premium、企業版、專業版、旗艦版,但Windows XP Mode只能用在Windows 7的企業版、專業版、旗艦版。

Windows XP Mode

Windows XP Mode(以下簡稱XPM)實際上是微軟事先設置完成的Windows XP虛擬映像。

以往,微軟只提供虛擬機器軟體(例如WVPC、Virtual PC或Virtual Server),及試用或評估性質的虛擬機器映像檔,如果要在虛擬機器安裝OS,使用者必須自行取得OS的授權(購買是取得的方式之一),然後以類似在實體電腦安裝OS的作法,將OS裝入虛擬機器。

XPM的作法與以往不同。XPM是微軟事先設置好的Windows XP虛擬映像,這意味著只要透過簡易的安裝,而不需以類似在實體電腦安裝OS的方式,就能裝好WVPC的客系統。

不過並非所有的Windows 7版本都能使用XPM,只有專業版、企業版、旗艦版才能使用XPM,這是軟體授權的限制。

下載Windows Virtual PC及Windows XP Mode

WVPC和XPM分屬兩個檔案,到微軟Windows Virtual PC網站下載時,必須視情況加以選擇(以下圖例及說明為RC版本):

  1. Windows 7 system type:針對安裝WVPC所在的Windows 7版本,選擇32位元或64位元。
  2. Windows XP Mode language:選擇XPM虛擬映像的語系,如果選擇繁體中文,屆時所執行的Windows XP即為繁體中文環境。


接著分別點選『Download Windows Virtuaal PC RC』和『Download Windows XP Mode RC』,就可下載這兩個檔案:

  • Windows Virtual PC:Windows6.1-KB958559-x86.msu
  • Windows XP Mode:WindowsXPMode_zh-tw.exe(此為繁體中文)

請先雙按執行Windows6.1-KB958559-x86.msu,(也就是先安裝WVPC),這個檔案很小,將近6 MB。接著再雙按執行WindowsXPMode_zh-tw.exe,這其實是個自解壓縮檔,而且檔案很大,約略550 MB。

Windows Virtual PC的虛擬機器也可以安裝其他客系統

WVPC不是只能搭配XPM,只要有軟體授權,也可以安裝Vista、Windows 7或其他OS,當然也可以安裝Windows XP。舉例來說,雖然XPM只能用在Windows 7的專業版、企業版、旗艦版,但如果使用者自己有Windows XP授權,還是可以將Windows XP裝入WVPC的虛擬機器。

延伸閱讀


[全文]

星期三, 九月 16, 2009

如何部署 Azure 雲端服務套件

如何部署 Azure 雲端服務套件》是我在MSDN網站寫的另一篇Windows Azure文章。


[全文]

星期一, 九月 14, 2009

Firefox 3收藏庫是不是該減肥了

結束我的Firefox需耗時近20秒,原來是因為收藏庫太過臃腫。

Firefox 3改以SQLite資料庫存放書籤、下載記錄、搜尋列與表單輸入的內容、網站表單Cookie和瀏覽歷程,並以『收藏庫』作為使用者存取書籤或歷程的GUI。這種作法的好處不少,但如果資料庫檔案太大,就會影響效率。

這個資料庫檔案名稱是places.sqlite,如果是Windows XP或Windows 2000,它的位置在(其他作業系統的位置請參考這裡):

%APPDATA%\Mozilla\Firefox\Profiles\<隨機數.default>

如果是Windows 7或Vista,預設位置是在

C:\Users\<user>\AppData\Roaming\Mozilla\Firefox\Profiles\<隨機數.default>

非常驚人的是,我的places.sqlit竟然有230 MB。容量這麼大的檔案,常會有效率低落的結果,也讓我聯想到,這與結束我的Firefox需耗時近20秒(表面上程式已關閉,但從『工作管理員』仍可看到程式),或許也有關係。

如果只是儲存書籤,places.sqlit的容量不至於暴漲,暴漲的原因往往是歷史記錄,尤其Firefox預設會儲存90天的歷史記錄。

減掉贅肉

利用收藏庫可以刪除個別的瀏覽記錄或書籤,Firefox本身的『清除最近歷史記錄』(工具/選項/個人隱私),也可依照時間範圍來刪除特定的項目(例如『瀏覽與下載記錄』)。

 清除最近的歷史記錄

以上都是不錯的選擇,不過Irvin在《Firefox 3 日漸肥大的收藏庫減肥法:最新版!》提供了更好的方法。他利用Firefox的『錯誤主控台』來執行6行內含SQL  statement的JavaScript  statement,可以只刪除瀏覽次數不超過2次的記錄、刪除Google Toolbar『新分頁網頁』的縮圖(),最後再壓縮檔案空間,讓places.sqlit變小。他們甚至已經將手動輸入statement的程序寫成Firefox附加元件《PlacesCleaner  收藏庫清潔工》。

藉由Irvin提供的方法,我230  MB的places.sqlit瘦身成12  MB(另一個只用了1個月的places.sqlit,也從42  MB變成5.3  MB),而且結束Firefox也不需再耗時20秒了。

還有一種清除歷史記錄的終極作法,刪掉places.sqlit,開啟Firefox之後,Firefox找不到places.sqlit,就會自行重建。

不要復胖

除了定時清理、壓縮places.sqlit檔案(或安裝PlacesCleaner附件元件),另一個方式是不要儲存沒有必要的資料。尤其Firefox 3預設會儲存所有的歷史記錄,但也允許使用者自訂歷史記錄的儲存選項;甚至可以在Firefox結束時,就清除歷史記錄。

自訂歷史記錄的儲存選項


:Firefox  3的附加元件也能將資料存入places.sqlit,因此若使用不當,附加元件也可能是讓places.sqlit暴肥的原因。之前Google Toolbar 5某個版本的『新分頁網頁』縮圖,會塞爆places.sqlit。目前的Google Toolbar  5就算不塞爆,依然是將縮圖存到places.sqlit,因此Irvin的作法依然有效。如果沒有用到這項功能,可取消Google Toolbar選項交談窗的『搜尋/啟用Google新分頁網頁』。

選項交談窗


[全文]

星期日, 九月 13, 2009

雲端運算的特徵、角色與服務

雲端運算有幾項重要特徵,但或許像雲一樣看得到卻摸不到,才是雲端運算最重要的特徵。

雲端運算的重要特徵如下:

  • 透過網路提供服務
  • 具有高度的擴充能力
  • 採用虛擬技術
  • 用了什麼付什麼;用了多少付多少

雲端運算的角色

  • 供應商(vendor):提供電腦軟硬體給提供者。例如伺服器廠商、網通廠商、儲存設備廠商,及作業系統廠商、虛擬技術廠商、開發工具廠商等。
  • 提供者(provider):提供雲端運算解決方案給用戶,例如Amazon、Google、微軟、Force.com等。
  • 用戶(customer):開發雲端服務或雲端程式給其他用戶或使用者。
  • 使用者(user):使用雲端服務或雲端程式的程式或人。

因此一般的ISV可居於用戶的角色,利用提供者的解決方案,開發雲端服務或雲端程式;例如利用微軟的Azure Services Platform開發一套「啾啾叫」Web程式,讓網友照三餐互相問候(甚至再開放啾啾叫的API)。

有些廠商甚至能橫跨多種角色,例如:

雲端運算透過網路提供服務,實際上提供視為服務的資源;以此分類的常見方式有:

  • 將架構視為服務(infrastructure as a service,IaaS)
  • 將平台視為服務(platform as a service,PaaS)
  • 將軟體視為服務(software as a service,SaaS)

原本稱為Hardware as a service(HaaS)的IaaS,是將基礎架構當作服務提供給用戶,對用戶來說,這種方式最彈性,但相對之下,用戶也必須負擔較多的系統管理資源或人力。IaaS也被認為是網站主機代管及虛擬主機的進化。

Amazon Elastic Compute Cloud(Amazon EC2)是經常用來作為IaaS的討論範例。EC2提供了虛擬的主機執行環境,這些執行環境是利用Xen虛擬技術所產生,而且提供不同等級的運算環境,還可讓用戶選擇Red Hat Enterprise Linux、OpenSolaris、Oracle Enterprise Linux、Windows Server 2003等作業系統,及Web伺服器、資料庫軟體、開發環境。

IaaS將硬體基礎當作服務,PaaS則進一步的將較為抽象的「平台」視為提供給用戶的服務,將整合了設計、開發、測試、部署、代管等功能的平台提供給用戶。例如微軟的Azure Services Platform或Google App Engine,都是PaaS的例子。

這3種類型當中,抽象程度最高,也最接近使用者的是SaaS,例子也不勝枚舉。甚至,一般ISV也能利用IaaS和PaaS所提供服務,而成為SaaS廠商。


[全文]

星期五, 九月 11, 2009

Windows 7的媒體櫃(4)--前傳之Known Folders篇

Vista引進了Known Folders,並以KNOWNFOLDERID取代了CSIDL(但為了回溯相容,新系統還是支援CSIDL)。

Known Folders的好處在於:

  • 可擴充,例如我可以自訂『賴榮樞』資料夾,再給予ID、向系統登錄,這個『賴榮樞』資料夾就成為Known Folders的一份子。CSIDL不能擴充。
  • 擴充的Known Folders可加入自訂的屬性。
  • 能以GetFolderIds列舉出系統所有的Known Folders。CSIDL沒有類似的功能。
  • Known Folders可重導到新的位置,CSIDL只有『我的文件』資料夾能重導。
  • Known Folders能有自訂的處理常式,可在建立或刪除時使用。

Kenny Kerr寫了一支可以列出所有Known Folders及相關資訊的程式,名為Known Folders Browser的程式各有x86和x64版本,而且不需安裝即可執行。這支程式只能在支援Known Folders的系統執行,例如Vista和Windows 7。

Known Folders Browser 1.0.2

延伸閱讀


[全文]

星期四, 九月 10, 2009

Windows 7的媒體櫃(3)--前傳之CSIDL篇

從Windows發展的角度來看,媒體櫃的濫觴應該是跟著Windows 95出現的『我的文件』資料夾。此後,不止『我的文件』,還有『我的音樂』、『我的視訊』,甚至其他應用程式還會自建例如『我的電子書』、『我的專案』。

目前的Windows 7都繼續支援這些特定的資料夾,畢竟媒體櫃只是使用者和檔案存取之間的介面,最終存取檔案的媒體,仍是這些實體的資料夾(或說檔案系統)。

但若論及Windows特定資料夾,其實還不止上述『我的xx』資料夾,更多的是用在系統儲存特定檔案的資料夾,例如安裝Windows的資料夾、安裝應用程式的資料夾、安裝x86應用程式的資料夾等等。

這些特定資料夾通常有預設值,但不論約定成俗或官方指定,硬是規定C:\Windows是安裝Windows的資料夾(舉例來說),不僅欠靈活、也容易出錯。因此系統需要維護一份對映特定資料夾和實體位置的清單,也就是能對映Windows資料夾和C:\Windows之間的關係(舉例來說),讓程式實際存取檔案前查詢。

目前依然支援的環境變數就具有這樣的功能,例如%windir%就是安裝Windows的資料夾。不過環境變數的層級不夠高。從Windows 95/Windows NT 4開始,Windows Shell利用CSIDL(constant special item ID list)的常數與常數值來維護這份清單。例如CSIDL_WINDOWS就是代表安裝Windows資料夾的常數,藉此常數向系統查詢所得的常數值,即為安裝Windows的資料夾位置。

利用SHGetFolderLocationSHGetFolderPathSHGetSpecialFolderLocationSHGetSpecialFolderPath等Windows Shell函式,可以取得特定資料夾的路徑或指向item identifier list的指標,也就是PIDL。

CSIDL是Vista之前的產物(為了回溯相容,新系統依然支援CSIDL),從Vista開始引進了Known Folders,並以一組稱為KNOWNFOLDERID的新的GUID取代CSIDL。

延伸閱讀


[全文]

星期六, 九月 05, 2009

下一版Windows Embedded Standard是以Windows 7為基礎

一點都不讓人意外的消息;如果以Vista為基礎,才讓人吃驚。

微軟9月初釋出下一版Windows Embedded Standard的CTP,有意試用者可至Microsoft Connect登入、選取後,下載文件、32及64位元Runtime、開發工具。預計2010下半年推出的Windows Embedded Standard 2011,專案代號為Quebec(魁北克),詳細的規格、功能可參考這裡

Windows Embedded是Windows家族的嵌入式系統分支,此分支是以「特定功能為導向」,例如用在POS銷售系統、Set-Top Box、ATM等。與一般Windows最大的不同,是Windows Embedded的銷售對像是OEM廠商,並且由廠商依其應用而客製化。

Windows Embedded目前有6大成員


處理器 基礎的系統 備註
Windows Embedded CE
  • ARM
  • MIPS
  • SH4
  • x86
  • Windows Embedded CE 6.0
手機或PDA應用另有Windows phone品牌
Windows Embedded Standard
  • x86
  • Windows XP Professional

Windows Embedded POSReady
  • x86
  • Windows XP Professional
適用於銷售系統
Windows Embedded Enterprise
  • XP: x86
  • Vista: x86 / x64
  • Windows XP Professional
  • Windows Vista Business
  • Windows Vista Ultimate

Windows Embedded NavReady
  • ARM
  • Windows CE 5.0
適用於手持式導航設備
Windows Embedded Server
  • x86
  • x64
  • Windows Server 2008
  • Windows Server 2003 R2
  • Windows Server 2003

Windows Embedded就是以修改過的Windows當作嵌入式裝置的作業系統,因為嵌入式應用需要使用即時系統,而且硬體條件不比PC。但對Windows開發者來說,Windows Embedded也是另一個類似的平台,尤其是x86版本,或許只需要做些調整,就可以將原本的Win32程式移植到嵌入式系統。而且諸多版本都已經支援到.NET Framework 2.0或3.5,有些甚至已經支援到Silverlight 3.0,這些都是程式移植到Windows Embedded的利多。

其實最讓我好奇的Windows嵌入式系統,是Xbox/Xbox 360遊戲機的作業系統。雖然微軟未承認它是Windows,雖然Xbox 360的處理器已經換成3核的PowerPC,但它的作業系統的確與Windows關係密切:

  • 許多API與Win32 API相同
  • 能執行DirectX
  • 具備 "微型" 的.NET Framework

而且:

  • Windows NT 3.51和4.0都有PowerPC(以及x86、Alpha MIPS)版本
  • Windows NT 4.0是第1個有嵌入式版本的Windows

雖然許多人討論、猜測Xbox的作業系統可能源自Windows 2000,或者認為是個特殊版本的Windows,但微軟並未承認,而是表示Xbox/Xbox 360用的是全新開發的作業系統。


[全文]

星期四, 九月 03, 2009

不同Windows的IIS 7.5功能差異

Windows 7和Windows Server 2008 R2的IIS都 "進化" 到IIS 7.5,然而這些Windows裡雖然都是IIS 7.5,功能的完整性卻不盡相同。

內建IIS 7.5的作業系統有:

  • Windows Server 2008 R2
  • Windows 7 Ultimate / Professional / Enterprise
  • Windows 7 Home Premium
  • Windows 7 Home Basic / Starter

TechNet Library的Available Web Server (IIS) Role Services in IIS 7.5列出了上述版本所包含的功能(角色服務),這些功能可能是預設安裝、具備、或不具備:

  • Default:安裝IIS 7.5預設就會安裝(但也能取消)
  • Available:具備,但需要使用者自行勾選才會安裝
  • Unavailable:不具備,當然也就無從安裝

基本上,越高階的Windows,其IIS的功能就越豐富。從這份文件,上述4種Windows的IIS 7.5功能,最完整的是1、2;Windows Server 2008 R2有的,Windows 7 Ultimate / Professional / Enterprise都具備。

PS.TechNet Library原本就有一份Available Role Services in IIS 7.0,列出不同Windows的IIS 7.0功能差異。


[全文]

星期三, 九月 02, 2009

Windows 7的媒體櫃(2)

看起來、用起來都像資料夾的媒體櫃,實際上只是XML設定檔;媒體櫃的內容,是系統根據XML裡的設定,從各個資料夾一一羅列而得。

媒體櫃雖然不是實體資料夾,但若非永久刪除,還是能以『資源回收筒』還原(還原之後,可保留原本的資料夾設定)。且因媒體櫃裡的檔案實際處於其他資料夾,所以不會因媒體櫃的刪除,而導致檔案遭到刪除。

若刪除系統預建的媒體櫃,可以滑鼠右鈕按下瀏覽窗格裡的『媒體櫃』,在選取『還原預設媒體櫃』,即可還原刪掉的媒體櫃。

若刪除媒體櫃裡的檔案或資料夾,會刪除原始位置的檔案或資料夾(反之亦然)。如果只是不想讓某些檔案或資料夾出現在媒體櫃,應該是要移除包含該檔案或資料夾的資料夾(也就是媒體櫃『加入資料夾』的反向操作)。

本機硬碟(包含外接式)及大部分隨身碟裡的資料夾,可以加入媒體櫃(但這些外接式裝置若未連線,當然就無法存取其中內容)。然光碟裡的資料夾不能加入媒體櫃。家用群組的資料夾可以加入媒體櫃,已編置索引或設為可離線瀏覽的網路位置,也可加入媒體櫃。

媒體櫃實際上只是副檔名為.library-ms的XML檔案,其內容是該媒體櫃的設定細節。這些XML檔案預設的位置是在%APPDATA%\Microsoft\Windows\Libraries資料夾,請先開啟『命令提示字元』,然後切換資料夾,再執行dir,就可以看到Documents.library-ms、Music.library-ms、Pictures.library-ms、Videos.library-ms等4個預建媒體櫃的XML檔案。您可以文字編輯器來瀏覽這些XML檔案內容,但請勿更改。此外,『檔案總管』看不到這些媒體櫃XML檔案,看到的還是媒體櫃資料夾。

例如以上部分的XML內容取自Documents.library-ms,設定內容是加到文件媒體櫃的資料夾,從<url>得知是使用者個人的『我的文件』,而且已設定成預設的儲存位置。<serialized>已省略的內容,是Base64編碼的位置。

延伸閱讀


[全文]