開發 Android Apps: 第三篇,安裝 Sun Java

安裝 Eclipse 開發平台之前,我們要準備 Java 以及一些常用的插件,所以安裝步驟分為兩個:

1. 安裝 Sun Java

2. 安裝 Eclipse

這次先講 Sun Java,開發 Android Apps 會以 Java 為主,Ubuntu 預裝的是 OpenJava,你可以在 終端機 中輸入:

java -version

查看:

雖然 OpenJava 跟 Sun Java 大致上是相同的,不過也有少部份分別,為了避免日後開發時可能遇到的不知名問題,我們還是安裝 Sun Java 吧。
Continue reading “開發 Android Apps: 第三篇,安裝 Sun Java”

開發 Android Apps: 第二篇,Ubuntu 11.04 后安裝

上回講到新安裝了 Ubuntu 11.04,Ubuntu 啟動後還有一系列的手續要完成:

1. 更新 Ubuntu

當你第一次登入之後,什麼都不做,等 … 等大概 1-2 分鐘左右吧,你會發現螢光幕出現一個 popup window 但是又立即 minimize 咗,螢幕左下方有一個 更新管理員:

如果你唔想等,你可以啟動 command prompt,輸入這個指令:

sudo apt-get update && sudo apt-get upgrade

Continue reading “開發 Android Apps: 第二篇,Ubuntu 11.04 后安裝”

開發 Android Apps: 第一篇,安裝 Ubuntu 11.04 繁體版

為何選 Ubuntu?當然是由於它是免費的,而且 Ubuntu 相當穩定,要求的 resources 比較低,速度夠快,支持的開發平台(我指免費的)很多,足夠用作開發 Android Apps。

我自用的 notebook 是 64-bit Windows 7,Core 2 Duo,8GB,用 VMware Player 搞一個獨立的 virtual host,輕而易舉,步驟如下:

1. 去 Ubuntu 下載 Ubuntu Desktop 的 ISO

我選了 Ubuntu 11.04 64-bit。有網友說 32-bit 比較穩定,Ubuntu 自己也推薦 32-bit,不過我覺得 64-bit OS 運行速度比較快,所以就選了,反正是 virtual host,日後如果唔喜歡就推到重來吧。

2. 啟動 VMware Player

VMware Player 也是免費的,去 VMware 登記一下就可以下載。VMware Player 啟動後的畫面:


Continue reading “開發 Android Apps: 第一篇,安裝 Ubuntu 11.04 繁體版”

在 Firefox 中測試 RESTful WebServices

我用 WCF 寫了一個簡單的 WebServices,主要功能是利用 GET 和 POST 做一些基本的 data retrieval 和 updates。

WCF 提供了一個 WCF Test Client,可以直接在 Visual Studio 中做測試:

已經不錯,祇是未夠真實, 最理想當然是用 HTTP 發出 GET/ POST/ PUT/ DELETE 等指令做測試.

如果我部電腦已經安裝了 Java Runtime 就有很多選擇,不過我一直避免在我部 development notebook 安裝 Java Runtime,於是在網上找替代的辦法。

試了一下 Fiddler,不合適。最後找到了 Firefox 的 plugin,RESTClient

厲害!這裡顯示的是 Response Header 資料,另外的兩頁是 Response Body,有更多詳盡的資料。 Firefox 真是 web 開發者必備.

IIS7 + SSL + Multiple Sites

新建 web server (Win2008 Standard Server) 給 SSL websites 專用,SSL 採用自製 (Self-Signed Certificate)。

在建立第二個 websites 時出現問題, 說是同一個 port 不可以給兩個 websites 共用。

當然,沒有分別設定 HTTP HEADER。

可是 IIS 的 Management Console 沒法 edit 個別 website 的 HTTP HEADER 資料啊?

原來 IIS 7 的 Management Console 未有改善這個功能,說是 IIS7.5 就可以了,又係 Microsoft 的討厭手段。

要用 appcmd 了,啟動 cmd,轉移至 C:WindowsSystem32inetsrv,輸入以下的指令:


appcmd set site /site.name:"你的 website 名" /+bindings.[protocol='https',bindingInformation='*:443:你要用的 HTTP HEADER 名']

參考資料:

  1. 這是 Microsoft 的說明
  2. 這裡是網友的說明 (比較清楚)

@Html.ActionLink 太麻煩了

不吐不快!

Microsoft 攪的東西有些時候真是無聊!

這個 MVC Razor 中用的 @Html.ActionLink 其實就是 HTML 中的 a tag. 以下是我不滿的例子:

@Html.ActionLink("Home", "Index", "Home", new { id = "", sid = "" }, new {data_role="button", data_icon="arrow-u", data_iconpos="notext"})

<a href="@Url.Content("~/")Home/Index" data-role="button" data-icon="arrow-u" data-iconpos="notext">Home</a>

第一行是 Html.ActionLink 的用法. 為了要增加幾個 jQueryMobile 要用到的 attributes 就變成一句奇怪的 syntax. 中間的 id 和 sid 東西原本是 parameters, 在這裡雖然沒有用到, 因為要加上最後的 attributes, 就算沒有用, 也要寫上, 否則就是 syntax error 了. 那幾個 attributes 也有問題的, 因為 MVC 不接受 “-“, Microsoft 就取巧, 叫你用 “_” 他幫你生成 “-“, 攪成三不像!

第二行是沒有 Html.ActionLink, 衹採用了 Url.Content 來取得 root 的路徑. 清楚易明.
這個 Url.Content 也是找了一會才找到的, 以前是用 ResolveUrl, 在 Razor 中居然又要改了!

Synchronize 兩台 IIS7

使用了兩種不同的方法去 synchronize 兩台 IIS7,記錄下來供日後參考。

  1. 用 WebDeploy + Robocopy
  2. 用 Appcmd + Robocopy (這個辦法比較好)

WebDeploy + Robocopy

首先在 source 啟動 WebDepSv:


net start webdepsv

然後在 destination 使用以下的 command 續一把 website 從 source sync 至 destination:
Continue reading “Synchronize 兩台 IIS7”

利用 PowerShell 自動 Restore 數據庫

也是三部曲,首先是準備 PowerShell 的 restore script,接著是利用一個 batch file (.BAT) 啟動這個 script 檔案,最後就是在 Task Scheduler 創建一個 task 按時執行這個 batch file 就完成了。
PowerShell script file 稱為 SqlRestore.ps1,內容如下:

#============================================================
# Restore a Database using PowerShell and SQL Server SMO
# Restore to the same database, overwrite existing db
# Donabel Santos
# 2010.10.16 paulus: modified
#============================================================

#clear screen
cls

#load assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

#get backup file
#you can also use PowerShell to query the last backup file based on the timestamp
#I'll save that enhancement for later
$backupFile = "C:MSSQLBackup" + $args[0] + ".bak"

#we will query the db name from the backup file later

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File")
$smoRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")

#settings for restore
$smoRestore.NoRecovery = $false;
$smoRestore.Partial = $false
$smoRestore.ReplaceDatabase = $true;
$smoRestore.Action = "Database"

#show every 10% progress
$smoRestore.PercentCompleteNotification = 10;

$smoRestore.Devices.Add($backupDevice)

#read db name from the backup file's backup header
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server)

#display database name
"Database Name from Backup Header : " + $smoRestoreDetails.Rows[0]["DatabaseName"]

$smoRestore.Database = $smoRestoreDetails.Rows[0]["DatabaseName"]

#restore
$smoRestore.SqlRestore($server)

#2010.10.16 paulus: set owner to sa
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $server.Databases.Item($smoRestoreDetails.Rows[0]["DatabaseName"])
$db.SetOwner("sa", $TRUE)

"Done"

 

batch file 稱為 RestoreDb.bat,內容如下:

powershell -command "& {C:MSSQLSqlRestore.ps1 Club.Secretary}"

powershell -command "& {C:MSSQLSqlRestore.ps1 Club.Secretary.RTIA}"

batch file 比較簡單,再來就是設立 Task Scheduler。如果 Task Scheduler 啟動的時間比 Backup 的時間早,就可以做成有兩天的備份了。

配合之前講的 Backup script 便建立了一個 SQL Server 的 mirrror server, 用作 disaster backup, 雖然不是 synchronized,難得是免費的,效果也算不壞吧?

利用 PowerShell 做 SQL 數據庫備份

分成三個部份,首先是準備 PowerShell 的 backup script,接著是利用一個 batch file (.BAT) 啟動這個 script 檔案,最後就是在 Task Scheduler 創建一個 task 按時執行這個 batch file 就完成了。

PowerShell script file 稱為 SqlBackup.ps1,內容如下:

#============================================================
# Backup a Database using PowerShell and SQL Server SMO
# Script below creates a full backup
# Donabel Santos
# 2010.10.16 paulus:modified
#============================================================

#specify database to backup
#ideally this will be an argument you pass in when you run
#this script, but let's simplify for now
$dbToBackup = $args[0]

#clear screen
cls

#load assemblies
#note need to load SqlServer.SmoExtended to use SMO backup in SQL Server 2008
#otherwise may get this error
#Cannot find type [Microsoft.SqlServer.Management.Smo.Backup]: make sure
#the assembly containing this type is loaded.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for smo.backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

#create a new server object
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDirectory = $server.Settings.BackupDirectory

#2010.10.16 paulus: display default backup directory
"Default Backup Directory: " + $backupDirectory

#display current backup database
"Current database: " + $dbToBackup

$db = $server.Databases[$dbToBackup]
$dbName = $db.Name

$timestamp = Get-Date -format yyyyMMddHHmmss
$smoBackup = New-Object ("Microsoft.SqlServer.Management.Smo.Backup")

#BackupActionType specifies the type of backup.
#Options are Database, Files, Log
#This belongs in Microsoft.SqlServer.SmoExtended assembly

$smoBackup.Action = "Database"
$smoBackup.BackupSetDescription = "Full Backup of " + $dbName
$smoBackup.BackupSetName = $dbName + " Backup"
$smoBackup.Database = $dbName
$smoBackup.MediaDescription = "Disk"
#2010.10.16 paulus: overwrite
$smoBackup.Initialize = $TRUE
#2010.10.16 paulus: no need for timestamp
#$smoBackup.Devices.AddDevice($backupDirectory + "" + $dbName + "_" + $timestamp + ".bak", "File")
$smoBackup.Devices.AddDevice($backupDirectory + "" + $dbName + ".bak", "File")
$smoBackup.SqlBackup($server)

#let's confirm, let's list list all backup files
$directory = Get-ChildItem $backupDirectory

#list only files that end in .bak, assuming this is your convention for all backup files
$backupFilesList = $directory | where {$_.extension -eq ".bak"}
$backupFilesList | Format-Table Name, LastWriteTime

batch file 稱為 BackupDb.bat,內容如下:

del C:MSSQLBackup*.* /F /Q
powershell -command "& {C:MSSQLSqlBackup.ps1 Club.Secretary}"
powershell -command "& {C:MSSQLSqlBackup.ps1 Club.Secretary.RTIA}"
robocopy C:MSSQLBackup \151-SQL2K8C$MSSQLBackup /Z /W:5 /MIR

第一行,把檔案夾內的舊 backup files 刪除。
第二行,啟動 Powershell script 備份數據庫 Club.Secretary。
第三行,再用 PowerShell script 備份數據庫 Club.Secretary.RTIA。
如此安排是容許選擇性地 backup SQL Server 內的 databases.
第四行,用 RoboCopy 把剛才備份的檔案抄至指定的 computer 151-SQL2K8 去,RoboCopy 用了一個 /MIR 意思是 Mirror, 確保 151-SQL2K8 收到的檔案跟本機完全相同,不多也不少。

最後的設定 Task Scheduler 就不用講了吧?

PowerShell 的 Set-ExecutionPolicy

最初的原意是利用 PowerShell 做一個 SQL 數據庫備份,然後利用 Task Scheduler 變成按時每天自動 backup 數據庫 一次。一開始就碰上了這個 Set-ExecutionPolicy 的麻煩,找到解決辦法後順便把它記錄下來。

PowerShell 的 SecurityPolicy default 是 Restricted,Restricted 是最嚴格的,不過就會影響到一些指令會由於 Security Level 不足而執行不了,例如我今次要做的 SQL backup 有需要用到一些 SMO (SQL Server Management Objects),這樣 Restricted 就行不通了。

如果在 PowerShell 的 console 中可以執行 Set-ExecutionPolicy 去改變目前的 Security Level,例如:

PS> Set-SecutrityPolicy RemoteSigned

不過在 Task Scheduler 就不可以這樣,唯一可行的方法是把本機的 policy 更改。
Continue reading “PowerShell 的 Set-ExecutionPolicy”