2008年8月24日 星期日

Get a repeating path in CMS resources gallery

After installing CMS on XP platform, I got a image broken situation when enter any CMS default pages.

There is a repeating image path on HTML source, which like "/IntranetCmsApp/cms/WebAuthor/CMS/WebAuthor/…". To solve this problem, you need to change some application folder to pure virtual folder under your website through the IIS manager. Please read the original article below:

Topic: Template Gallery resources reference "/CMS/CMS/…"

When I select "create new page" in the Web Author console, I see the Template Gallery Window pop up but no images are being pulled down. The stylesheet is not being loaded and the Javascript files are not being pulled down. I viewed the source of this page and saw that there was an extra folder in the path to the resource files. The links looked like this: /CMS/CMS/WebAuthor/Client/WBC.css. I had the same type of problem when I went into the resource gallery. What could be wrong?

Answer

The solution to this problem is that the virtual directory "CMS" in the template application is an application and not a virtual directory. You can tell the difference between the two by their appearance in the MMC. A virtual directory has a little world on top of a folder while an application has a grey box with a page in it and a green arrow. To fix this:

  • Open the IIS_Admin MMC
  • Right click on the "CMS" Virtual Directory/Application item under the web root
  • Click properties on the virtual Directory tab and select "remove"
  • Click "OK"

Reference link, Similar situation

[re-post this article due to database crash.]

Get broken images in MCMS authoring mode

This situation happened in my development machine. I think the problem exited since I have set up the CMS on it.

First, I switched to edit mode and everything looks fine including the web author console area. Then, I clicked the add new posting to enter the edit page and it looks fine too. However, when I finished the editing process and clicked the "Save" command, a pop up window which contains broken images showed up.

According to my experience, it is a similar issue to my previous post, [Get a repeating path in CMS resources gallery on XP platform]. To solve the problem, simply follow the procedure below:

  1. Open the IIS manager.
  2. Find out the web instance to which your CMS app installed.
  3. Switch to your CMS application if you installed it as a sub app under your web instance.
  4. Find out a folder called "cms" and enter it.
  5. Find out a virtual folder called "Web Author". (BINGO! If "Web Author" is not a virtual folder then it is the problem. Simply right click on it then adjust the setting to virtual folder by removing the application pool.)
  6. Done.
[re-post this article due to database crash.]

Using MCMS Performance Counters

It seems MCMS has it’s own performance counters which could be installed on MCMS server itself and browsed by performance tool under control panel.

These MCMS performance counters should be installed when we installed the MCMS spa1. So, They already existed and you just don’t know.

However, there are some issues that you may not see these performance counters after the installation process. You can fallow the steps below to solve this issue:

  1. Open the command window and switch to the directory path below:
    [MCMS install path] \ Server \ bin
  2. Type the command below and press enter button:
    regsvr32 /i cmsperfcounters.dll
  3. reboot server.
  4. If you have installed Microsoft Visual Studio .NET 2003 before then you can execute the “Exctrlst.Exe” tool to verify if the MCMS performance counters have installed successfully.
    The Exctrlst.Exe tool locate at the [Visual Studio Install path] \ Common7 \ Tools \ Bin \ winnt .
    Just execute the program and verify if there has a “CMS Performance Counters” in the middle text box. if you can see that then it means the installation process is successful.
  5. Open [Control Panel] > [ Administrative Tools] > [Performance] and click the “Add” button on the window, then select “CMS Performace Counters“ at the “Performace Object” drop down menu. Now, you should see all the CMS related counters display in the list box. Enjoy!

About the meaning of every CMS Performance Counter, the MCMS help CHM file has detailed information. you can download it from Microsoft MSDN website.
Here is the link.

[re-post this article due to database crash.]

Switching Reports and ReportServer folders under the CMS Website

The description of how to install reporting services in the computer which has MCMS setup.

The Reporting Services virtual folders (Reports and ReportServer) are installed in Default Web Site in IIS.

If we have installed a CMS web site on the same machine, then we should stop it and start the oringinal default web site before we install the Reporting Services.

After that, right click on virtual folders and execute the "Save Configuration to a file" options from "All task" inside the POP Windows, then we can use these files to import virtual folders under the CMS web site.

[re-post this article due to database crash.]

Wozniak Time

[Original published date: 9/12/2007 1:55:27 AM]

It was a great occasion that Trendmicro could invite Steve Wozniak, the founder of Apple Inc, to come to our office and give us a speech.

Although his speech was almost about the content of his new book, iWoz, he still gave us a impressive image of legendary engineer. Woznaik is not like another founder of Apple Inc, Steve Jobs. He is a typical engineer who loves to invent new stuff and hesitate to show up in public. Many great products produced by Apple in the 80s actually came from Wozniak's hand and they are inlcuding Apple I and II. He always treat himself as an engineer even he gained a lot of money from his founder position and the growing well of Apple, more than that, he actually shared his divident with basic employees. His value is so noble that some people call him the only good man in silicon valley.

At the Q & A period, our CCO, Jenny asked Woz that how do you think about the computer viruses and the hackers who made them? Wozniak's response is very mischievous, he said: All of my servers use Macintosh system and I have two hourses to store these machine. But as I know, not any hacker even me has the firewall and I think it is because no one want to write a vurus on Macintosh system. Two times in those days, my friends bring in some linux machines and setup their own router and firewall but they ware intruded because somebody took control the computers. As a hacker, I never try to write virus or do something bad. However, too many hackers cross that line and I do not appreciate it totally. Basically, the Macintosh platform has lower marketship so very few people try to write virus on Macintosh. Anyway, the virus issue became more and more important especially we all step into the Internet right now, and one of companies which I am in board is focus on software security.

Then, One of our engineer ask him how do you negotiate and sell your innovation idea to your boss? He said: Engineers usually are focus on the functionality and do not know the real requirement from the customers. The valuable improvement to the software maybe not always the same to the engineer and customer. In order to getting closer to the customer, engineer must work closely with marketing to reach customer's thinking. Besides it, some bosses will listen to you but some don't, there is nothing I can do about that!

I also raised my question: Do you know Kai Fu Lee? He was the employee of Apple before and how do you feel that he join the Microsoft at last? Wozniak showed his humor again, he said: does his scandal really over? (all people laughed out loud at the time) The Q&A period took about 15 mins and I can not type each question and Woz's answer here because it is so many. Just want to share the experience with you and hope everyone who listend his speech does have inspired no mater by his value or profession. To those people who are interesting in his new book, iWoz, in Traditional Chinese edition, the website produced by Yuan-Liou publisher is a good start: http://www.ylib.com/hotsale/iWoz/index.htm.

[re-post this article due to database crash.]

Configure Web.config to permit the uploading of big file

The description of how to setting the ASP.NET file upload limit in web.config file.

Please add or modify the following section in your web.config file to control the maximum upload size and time:

<httpRuntime executionTimeout=”3600″
maxRequestLength=”1024000″
useFullyQualifiedRedirectUrl=”false”
minFreeThreads=”8″
minLocalRequestFreeThreads=”4″
appRequestQueueLimit=”100″/>

In this example, the values are set to 3600 seconds=1 hour and 1024000 KB=1GB.

Original Article: http://download.microsoft.com/download/4/2/5/4250f79a-c3a1-4003-9272-2404e92bb76a/MCMS+2002+-+(complete)+FAQ.htm#21529F34-A8D4-47B5-8B63-6FBE6A1BC91E

[re-post this article due to database crash.]

.Net LDAP ADsPath Programming

[Original published date: 6/7/2007 8:31:17 PM]

在 DotNet 平台撰寫 AD 相關應用程式,最常使用到的莫過於 DirectoryEntry 物件。透過該類別的建構子,傳入欲取得之 LDAP 節點的 LDAP 路徑、具有 Query 權限的帳號名稱和密碼,便可以輕易取得該節點,進而檢視其細部屬性:

DirectoryEntry de = new DirectoryEntry( [LDAP Path], [具有AD瀏覽權限的帳號名稱], [具有AD瀏覽權限的帳號密碼]);

其中的第一個 LDAP Path,我們可以使用 ADsPath 格式以達到 Query AD 伺服器的目的,有關 ADsPath 的格式如次:

LDAP://HostName[:PortNumber][/DistinguishedName]

以下則是一些 ADsPath 的範例:

Bind to the root of the LDAP namespace
LDAP:

Bind to a specific server
LDAP://server01/

Bind to a specific server using the specified port number
LDAP://server01:390/

Bind to a specific object
LDAP://CN=Jeff/ Smith,CN=users,DC=fabrikam,DC=com

Bind to a specific object through a specific server
LDAP://server01/CN=Jeff Smith,CN=users,DC=fabrikam,DC=com

比較需要注意的地方是,ADsPath 是以 '/' 作為 hostnameDistinguishedName 的分界點,因此,程式開發是必須注意在後方的 DistinguishedName 當中是否有任意 LDAP 節點名稱包含了 '/' 字元(通常情況下,LDAP節點名稱是不可以包含任何特殊符號的,不過不遵守此一通則的情況比比皆是)。舉例來說,在下面這個 ADsPath, 因為後方的 DistinguishedName 路徑出現了 '/' 字元,故程式會將 [server01/CN=Jeff Smith,CN=users,DC=fabrikam] 這段路徑都當作 hostname 處理:

LDAP://server01/CN=Jeff Smith,CN=users,DC=fabrikam/taiwan,DC=com

因此,程式開發時必須特別留意 DistinguishedName 是否出現了不合法的字元,以上面的例子來說,我們必須將 '/' 加上脫逸符號成為 '\/',因此正確的 ADsPath 應該為:

LDAP://server01/CN=Jeff Smith,CN=users,DC=fabrikam\/taiwan,DC=com

參考資料:
http://msdn2.microsoft.com/en-us/library/aa706070.aspx
http://msdn2.microsoft.com/en-us/library/aa746384.aspx
http://msdn2.microsoft.com/en-us/library/aa772257.aspx
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzahy/rzahyunderdn.htm

[re-post this article due to database crash.]

2008年8月23日 星期六

Microsoft Office Communications Server 2007

[Original published date: 7/15/2007 7:08:52 PM]

I went to the Microsoft Technology Center of Taiwan BU last week to see the new Microsoft Office Communication Server 2007's capability and limitation due to my work.

The giant leap to MOCS 2007 is to integrate all the office product with instant message service, mobile service, email service, phone service and video conference service. Basically, it combine all the possible communication ways in the real modern world right now with MS Office. But first, I need to remind you that most new features of MOCS 2007 must co-operate with Office 2007. It means you should upgrade your old MS Office version to 2007 before using MOCS 2007. It is another example to Microsoft for gaining a lot of money from client, so don't be surprised.

During the DEMO, the people from Microsoft showed us some user cases by using MOCS 2007, and it looks fantastic! By integrating with Office 2007, any one in the organization could easily communicate with others. Just simply click the communication target in the menu and choice which end device you want to use, then the back-end MOCS 2007 will make a connection for you. The user does not need to remember communication target's instant message account, email account, modile phone number, desktop phone number or vedio conference IP because MOCS 2007 handles all of them. All the client users who want to have these benifits should install office 2007 and MOCS client agent on their computer.

Another impressive demo is the integration of MOCS 2007 and Office 2007. Imagine that you received a word document file from one of your colleagues and you want to make a contact with him because of some issue in file. At old time, you need to look up his phone number or email account then make a phone call or send an email. But for now, you only need to press a button in Office Word menu then the MOCS client will handle the rest of process, communicating target user for you right away. All the Office software could work like this including Excel, Powerpoint and Outlook. Besides, MOCS 2007 also could co-operate with Microsoft Exchanger Server 2007, SharePoint Server 2007 and many other Microsoft Server systems to enrich the communication behavior.

However, consider the current status of most enterprises, the real practical feature is instant message service in MOCS 2007. The vedio conference will impact the network bandwidth and the phone service must leverage with some telephone switch devices, so they won't be the major motive for a company to user MOCS 2007. For more information about MOCS 2007, please check here. According to the information from Microsoft Technology Center this time, the formal version of MOCS 2007 will come out before end of Q3 this year. From now to the launch day, Microsoft will hold a series activities such as workshop, fresh meeting and tech conference to the public, let's wait and see!



[re-post this article due to database crash.]

部門溝通與合作

[Original published date: 7/12/2007 9:07:15 PM]

最近在公司甫完成一專案,因為上線的成果不錯,故整個 team 安排了一次出差,與在美國的各個合作部門進行感謝性質的會議,雖說如此,其中也安插了許多技術、資訊的分享內容,讓此次的出差不像在工作,反倒是參加教育訓練營般,過足了學習之癮,實在不虛此行。

最近在公司甫完成一專案,因為上線的成果不錯,故整個 team 安排了一次出差,與在美國的各個合作部門進行感謝性質的會議,雖說如此,其中也安插了許多技術、資訊的分享內容,讓此次的出差不像在工作,反倒是參加教育訓練營般,過足了學習之癮,實在不虛此行。

此一剛完成的專案為一個跨部門合作的專案,為了達成組織內部的某一需求,整個 team 需負責開發一內部系統,然開發本身非常單純,一言以蔽之,系統分析及程式設計而已,可是要讓整個系統可以順利的上線、測試,進而獲得使用者的回饋,人機介面的微調及改善,均非簡單之事,且牽涉到諸多部門間的溝通、協調與合作。

其中,此次更對溝通的時機和深入程度有了重新的認識。舉例來說,某 A 部門因掌管硬體基礎建設,本身具有許多優異的硬體解決方案來支援、輔助,甚至以直接代勞的方式來完成許多應用系統層級的功能,如果在專案開始時便能與 A 部門召開諮詢會議,也許在系統開發上會有不一樣的結果,讓整體開發時程進而縮短。這告訴了我們,組織內部的資源往往不夠透明,以致於不同部門不曉得彼此之間的資源有哪些,自然無法善加、重複利用,也間接的造成人力資源的浪費。

因此我們可以假設,在專案初始之時若能即刻與相關牽涉之部門聯合召開 kick off meeting,應當可以減少上述情況之發生。然而現實情況是複雜多變的,礙於組織層級的窒礙,部門間彼此的溝通層級往往決定了溝通的效率,若會議的出席者均為有實質決策權的管理人員,則相對的整合效果自然遠超過僅能做技術交換的技術人員,因此,跨部門的溝通是否應當為平行、交叉並行呢?也就是給予充分的機會,讓合作的兩個部門能跨越組織的階級型態,做充分的溝通,就像此次我所參加的會議一般,若能在專案開始之初便進行相類似的溝通,想必專案的執行成果勢必更佳亮眼。

然而,要進行如此廣泛、深入的溝通,牽扯到大量人力的時間安排問題,將上至經理等管理階層,下至工程師等全部拉在一起開會,固然能提升專案執行成效,可是為了執行此事所浪費的時間,是否又會造成組織其他地方更大的損害呢?經理等管理階層投入其中的經濟效益又是否足夠呢?如果我們以組織整體的角度來思考,似乎答案又不那麼肯定了!同樣的,相同的問題如果放在不同的組織型態上,所獲得的答案可能也會不同:在扁平組織中,執行上述的跨部門溝通所耗費的時間成本自然比金字塔型的組織來的少,因此也較不會產生上述的問題。總而言之,充分、廣泛的溝通,掌握溝通時機(越早越好,最好是在專案初始期便建立全面的溝通平台。),以及邁向扁平化組織,似乎是成功的部門溝通與合作不可或缺的背景環境!

[re-post this article due to database crash.]

Developer 的試煉

[Original published date: 7/12/2007 9:08:17 PM]

Developer 的工作,將不再只是開發出使用者所需功能而已!

我曾在出版的書籍『Visual C# 2005 資訊安全程式設計』提到程式 Developer 所應具備的基本觀念,也就是 Developer 的工作,將不再只是開發出使用者所需功能而已,還必須具備資訊安全的知識,從系統分析階段開始,直到軟體系統釋出為止,在每個環節都必須顧及到資訊安全的細節,包含程式碼本身的強固性、可靠性等。上述的觀念,乃是因為網際網路興起,系統安全逐漸受到重視,故我認為 Developer 必須具備充足的資訊安全知識,如此方能產出應用在現今複雜、攻擊行為不斷的網際網路執行環境上之系統程式。

該書提到的觀念是完全從技術的角度出發,然而,在整個軟體開發流程中,Developer 除了技術本質學能外,還有哪些觀念必須要建立呢?在目前公司工作了一陣子,出差到美國參加 workshop 後,在我腦中有了個概念,我將他稱之為『匠心』!程式開發在本質上屬於邏輯思維的創作,它跟製造業呆板的製程不同,因此,將程式、軟體比喻成藝術創作,遠比將他形容成產品還來得恰當許多,因此,軟體 Developer 在相當程度上與工匠相當類似。然而,工匠何其多,但被尊為大師的卻非常稀少,有何不同?有無『匠心』而已。

稱職的工匠,打造出的作品能切合使用者的需求,但是大師級的作品,除了切合需求之外,還進一步抓到了使用者的心,那也許是多一點的體貼設計,也許是前所未有的創新,讓人驚豔!更重要的是,對於其每一份作品,他都視為本身的延伸,作品即代表了工匠者本人,故任何符合完成標準的作品,創作者本身皆感到無比的驕傲!這就是匠心。套用在 Developer 上,就是自我激勵、自我要求,對程式碼本身的品質、可靠性及創意不斷精進,進而感到驕傲!這就是 Developer 的匠心!如此一來,Debug 將不再是痛苦的工作,它成為一種邁向完美的試煉!在軟體開發組織當中,如此一來,程式品質自然能提升,遞交到 QA 手上時,自然已有相當程度的水準!

匠心的另一種展現,就是對於使用者的真正體察!一個稱職的 Developer,不僅要釐清功能需求,還需要問為何有此些功能需求!在很多情況下,使用者所提出的需求並不能解決他的真正問題,因為使用者自己並非解決問題的專家,因此,主動的提出質疑,釐清使用者需求背後的真正動機,在修正過後,與使用者一同重新擬定需求列表,方為 Developer 另一種匠心的展現!Developer 若能以提升匠心自我要求,則其作品:程式碼、軟體不僅符合了使用者實用的需求,同時也滿足了使用者的心。達此境界,Developer 的大師風範便於焉行成了!

[re-post this article due to database crash.]

Web 2.0 in Enterprise 的衝擊,正要開始展開!

[Original published date: 7/12/2007 9:10:42 PM]

在 2006 年底時,我參加了數位時代雙週刊所舉辦的『Web 2.0 創業種子大募集講座』,該活動藉由分享台灣地區成功的 Web 2.0 案例(HemiDemi巴哈姆特PC HOME Skype)以及邀請私人創投家和 Web 趨勢觀察家 Mr.6 發表論述為主,整個活動儼然成為 Web 2.0 的定義說明會,不管是從知識分享的角度、技術的角度以及商業行為模式等,讓與會者瞭解到狹義及廣義的 Web 2.0 概念及定義。然而,該活動是以鼓勵學生及網路造夢者為目的,希望台灣能多一點像 YouTube 創辦人陳士駿般的傳奇產生!在我看來,其本意是好的,但是完全漠視了台灣的經濟核心:中小企業群。該活動並沒有針對中小企業提供任何的資訊、案例及方案來促使公司行號學習利用 Web 2.0 這個新概念。

企業應用 Web 2.0 概念有其價值嗎?當然!光是利用社群網站集結客戶群,妥善利用設群討論力量,讓客戶轉而協助客戶本身,就不知道可為公司降低多少的客戶服務成本,這還只是最微不足道的應用面而已。我想,光靠政府及學界,在短時間內是別指望他們有何高瞻遠矚的規劃,產業界在這塊領域還是自食其力比較實際。另我感到訝異的是,在趨勢的 HIE 部門,已經有人在研究、分析及規劃如何在既有的公司內部資訊環境及系統上,藉由導入、開發新的 Web 技術來營造公司內、外部 Web 2.0 的環境!在 Workshop 分享中,我看到了真正以 Enterprise 為標的物的 Web 2.0 數據分析,不禁感動萬分、痛哭流涕!雖說整個公司要完全執行此份規劃,勢必勞師動眾且耗費大量時間於內部流程改造及系統開發、升級上,可是這是 Enterprise 必定要走的路,就算路很長,但好歹本公司已經在起跑點準備好了!

組織龐大的企業個體,其導入 Web 2.0 概念的動作一定是緩慢的,甚至許多資訊產業中的企業仍未耳聞此一概念。然而,當一個組織有了策略性動作,決定邁向 Web 2.0 時,在背後必定有其依據及考量!這股力量,據 HIE 部門的分析結果,便是長尾效應(長尾理論)。當企業的主要營收、業績來自於小眾市場,而非巨大的企業客戶或大眾化的單調產品時,企業勢必得尋覓一套新的營運模式及技術,來應付數量龐大、彼此區隔的小眾產品,而 Web 2.0 的優勢正好趁勢彌補了此塊商業模式的需求!

接下來,我們將焦點侷限在 Internet 軟體產業上,在這個產業領域,我認為反而是 Web 2.0 本身的技術層面驅動了整個導入動作。自 Internet 普及以來,WWW 的技術不斷的提升和躍進,從最初的純文字模式,到現今富含多媒體元素的瀏覽環境,其背後的技術決定了一切,且逐漸朝邁向細部分工來走,這也告訴我們軟體的應用開發的複雜度不斷的提高,已到了需要進行更細膩的內部分工和切割。單就 Web 技術來看,從最初程式碼和輸出呈現混雜在一起的 CGI 時代,到程式邏輯的獨立、設計 layout 的獨立、內容(資訊)的獨立,都顯示了此塊領域的細部分工結果,若我們再把眼光從 Web 領域拉大到整個軟體產業,我們更可以看到軟體型態從單機系統、Client-Server 主從式架構系統,演變為今日強調的服務系統(應用 Web Service 技術),從 programmer 的角度,也就是從單一執行檔、DLL、COM、assembly 組件到 Internet 端 Service 的開發改變!

綜觀各個層級,上至商業模式、下至開發技術的改變,都脫離不開一個概念:share(分享)!應用 Web 2.0 的分享精神,來應付長尾效應,應用 Web 2.0 的相關技術,來將原本軟體開發的組件概念,進一步延伸到跨 Internet 的共享 service 上。Web 2.0 in Enterprise 的衝擊,正要開始展開!

[re-post this article due to database crash.]

溝通的客製化

這年頭,什麼東西都可以客製化,產品可以針對特定族群做細部切割,軟體系統可以針對顧客資訊環境做特別設定,而客製化的目的,無非是藉由更契合對方的需求來提昇產品價值。如果我們將這種觀念轉而應用在組織中的溝通上,亦可行得通!

在之前美國的 workshop 當中,透過精心設計的帽子遊戲,我們可以瞭解到每個人的屬性是截然不同的,同時,自我認知的屬性也跟其他人的觀察結果有所差距。每個人都有主觀意識,強勢的主觀意識,往往狹隘的自己的視野,導致審視事物的角度有所偏頗、無法綜觀全貌,同時,也無法認清自己的本質!前者將造成與別人溝通的鴻溝和障礙,後者則阻礙了自我提升的潛力。在活動當中,我們針對每位小組成員做一次自我檢視,要求每位組員說出自己認為的屬性為何,再請組員之間交叉評比,認為別人的屬性為何,在此一階段,大家方能對組員的主觀意識及屬性有了概略瞭解。

再來,便是思考為何別人眼中的自己,與自我的認知有所差距,且造成此段差距的原因為何?以及如何著手改善?很多時候,這個差距並不一定是負面的,有時候反而會是正面的,那即代表自己在其他人眼中有好的評價,可是自己卻因為自信心不足或缺乏溝通而不自知。在這個階段,自我省思是最重要的工作,很多人都知道自我省思的重要,可是卻只有很少人能真正落實於生活當中。理解此點之後,再來便是學習如何與不同屬性的人來溝通,以我的角度來看,這便是一種溝通的客製化!

你絕對無法將同一套溝通模式,應用在每一種人身上而得到相同的結果,這就跟軟體應用系統,或多或少都必須針對目標客戶進行某種程度的客製化一樣,溝通必須要視溝通的對象來調整,將自己調整成與對方相同的頻率上,如此一來勢必有助於增進溝通的成效!舉例來說,針對樂觀的人,該如何傳達專案的隱憂呢?如果在溝通一開始便開門見山的述說可能遭遇的困難及阻礙,從樂觀者的角度來看,反而會認為是一種負面說法,進而拒絕仔細聆聽或理解。針對上述的情況,若能在一開始先建立對該專案的肯定共識,然後再慢慢點出可能的缺陷之處,相信對方也會欣然接受,並跟著一起思考可能的解決方案,這樣,就是一種客製化溝通。

客製化的溝通並非一蹴可及,這種 Social 的技巧必須在溝溝過程中不斷反覆練習、推敲才行。故公司的 Workshop 在最後一個階段,便安排了角色扮演的遊戲,組員們藉由扮演不同屬性的人來進行不同情境的溝通演練,在此一過程中,大家都深切感受到其困難,畢竟一般人老早將自己單一的溝通模式視為理所當然,故當大家真正要對不同的溝通目標來調整溝通方式時,多半覺得彆扭,甚至在溝通中途又不自覺的退回自己習慣的那一套溝通屬性。不過,當大家建立了此一觀念,並落實於人與人的溝通上時,相信經過長時間的學習及調整,必定能對個人的溝通技巧和人際關係有正面的影響。屆時,溝通的客製化將變得自然許多了!

[re-post this article due to database crash.]

2008年8月22日 星期五

Software outsourcing

專注於核心項目,將非核心工作交付外包,等於間接提升企業的競爭能力,也節省了資源及時間。但是軟體外包因牽扯到眾多面向,導致實際的執行狀況非理論所能解釋,甚至對軟體外包所能帶來的效益產生質疑。為了能重新審視軟體外包的實務面,從中淬取出可供往後參考的寶貴經驗,茲將近期於工作中經歷的軟體外包案例重新審視,並針對幾項關鍵提出檢討。
  • 外包動機
    外包動機對於軟體外包來說是非常重要的一環,不管企業本身的規模大小與否,以及所能接受的外包成本多寡,都必須先審慎思考一件十分基礎的問題:是否真的該外包?所外包的內容也許是軟體系統,也許是軟體原件,只要外包所耗用之成本及時間效益不如企業自行開發來得便宜或快速,就不應該外包。然而實際的情況是,有太多的人為干擾因素存在於企業當中,導致軟體外包真正的意義被忽略,取而代之的是個人或部門績效。一個完善的組織應當避免此等狀況發生,否則即使拉高了個人或部門的績效,但是對公司整體而言卻是傷害。
  • 需求定義
    軟體外包案的品質優劣與否,跟需求定義的完善程度有絕對的正向關係。粗糙的需求定義即代表粗糙的成品,發包的企業往往會有角色錯置的問題,也就是以為外包廠商會以盡善盡美的態度來開發,這是一相情願的想法。首先,企業的文化絕對無法影響外包廠商,畢竟兩者是互為獨立的公司,再者,外包廠商總是以盡快完成交付案件並收取報酬為優先考量,跟處處斟酌細節、反覆推敲的公司內部開發流程截然不同,故軟體外包的需求定義必須力求精確、涵蓋完整,否則差強人意、甚至不堪使用的外包成品是必然結果。
  • 溝通與確認
    在執行外包的過程中,與外包廠商溝通的聯絡人或專案經理必須密集、精確的反覆確認外包案的需求定義,一方面避免外包案在最後驗收過程才來檢驗,一方面也對外包廠商傳達了督促的訊息,尤其是後者非常重要,否則外包廠商一定會刻意規避潛在的開發細節和問題。除了對外的溝通之外,對內與技術人員的反覆確認也非常重要,除了忠實的將外包廠商的回饋傳達給內部技術人員外,也必須適度的建立內部技術人員與外包廠商技術人員的直接溝通管道,以擴大溝通層面和深度,如此也能提升外包成品的品質。
  • 驗收
    針對軟體外包,驗收過程除了基本的測試外,也必須強調驗收的時效性。若驗收時程過長,除了會打擊雙方廠商的士氣、拖延開發進度外,更會提高外包破局的機率,導致原本的外包案件變成半外包、半自行開發的狀態(變成倚賴內部技術人員直接檢查外包成品以進行修改),已致完全違反了初衷。唯有快速的反應驗收結果,要求外包廠商期限內提出修正版本才是上策。

上述關鍵因素只要有一項出現瑕疵,即會給軟體外包結果帶來重大傷害,小則打擊員工士氣、重則拖慢開發時程,影響企業獲利,不可不慎。希望此篇短文能為執行軟體外包的企業、公司帶來些許的參考價值,進而避免犯下錯誤。

DateTime.ToString Issue in .NET

When we are programming in .NET platform, one of common task is using DateTime.ToString method to output a time string in certain pattern.

We all think that the output string will follows the pattern which we asign to the parameter in ToString method. However, sometime you will get a strange result. You may consider the code and result below:

DateTime.Now.ToString("yyyyMMdd"); -> 20070607
DateTime.Now.ToString("yyyy-MM-dd"); -> 2007-06-07
DateTime.Now.ToString("yyyy/MM/dd"); -> 2007-06-07
DateTime.Now.ToString("yyyy年MM月dd日"); -> 2007年06月07日
DateTime.Now.ToString("yyyy~MM~dd"); -> 2007~06~07


watch out the third line and you may think that should not be happened. But I really met this kind of problem in Windows Server 2000 today.

Why it happened? Because it is caused by the setting of short time format in your OS. In Windows Server 2000, You could go to the "regional options" in control pannel then switch to "Date" tab. In the dialog window, there is a "Date separator" option. You need to modify it from any other to "/". (Check the image below.)



If you want to make sure that your program will get the right string format in any setting condition to any windows computer, then The only way is using an overwrite versoin of DateTime.ToString method and pass the "System.Globalization.DateTimeFormatInfo.InvariantInfo" as second parameter. So the ultimate solution which don't need to configure your OS setting to the third line above is:
DateTime.NowToString( "yyyy/M/d", System.Globalization.DateTimeFormatInfo.InvariantInfo );

then the result will be exactly 2007/06/07.

Very funny, right? Hope Microsoft will fix this problem in the future.
[re-post this article due to database crash.]

MCMS 系統 Save 及 Publish Posting 程式開發指引

在 MCMS 系統中,如果要以程式的方式來建立或修改 Posting,必須透過一定的流程。然而,因為相關的資訊及文件十分缺乏,導致我自行摸索了許久,以下便將心得與大家分享。

在程式進行 MCMS 的 Posting 更新時,首先必須切換至 MCMS 的編輯模式,此時便需要進行身份驗證的動作。在開發 ASP.NET 程式時,我們通常會以目前 access 頁面的使用者帳戶直接進行驗證,以確定該名使用者具有足夠的權限進行後續操作,要達到上述的目的,請參考以下的程式碼片段:

WindowsIdetity wi = HttpContext.Current.User.Identity as WindowsIdentity;
CmsApplicationContext cac = new CmsApplicationContext();
cac.AuthenticateUsingUserHandle( wi.Token, PublishingMode.Update );


進行身份驗證並切換至編輯模式後,接下來,便是取得欲更新的 Posting 標的,在 MCMS 系統當中,針對每一 Posting 均會維護數種版本,包括歷次發佈的歷史版本等。因為我們是要針對某篇 Posting 做更新動作,所以應當取出該篇 Posting 的最新版本來更新,若先前切換成編輯模式成功,則取出某篇 Posting 的最新版本便輕而易舉,直接呼叫 CmsApplicationContext 物件的 Searches 類別方法即可:

Posting p = cac.Searches.GetByPath( "Posting Path" ) as Posting;

有些時候,你可能會想在同一個操作頁面秀出目前的發佈版本及目前編輯的最新版本,以作為交互比對之用,此時便需要取出上一次發佈的 Posting 版本,該怎麼做呢?請參考以下程式碼:

Posting p = cac.Searches.GetByPath( "Posting Path" ) as Posting;
PostingCollection pc = p.Revisions( true );
p = pc[pc.Count - 1];


一開始,同樣是呼叫 CmsApplicationContext 物件的 Searches 類別方法取出 Posting 物件,就跟取出最新版本的例子一樣,但是接下來,則呼叫 Posting 的 Revisoins 方法取出 PostingCollection 陣列物件。我們在此是傳入 true 當參數,用以取得該 Posting 以前所有發佈過的版本。最後,從回傳的 Posting 陣列中取出最後一個 Posting 物件,即是最近一次的發佈版本了!

再來,便是設定更新值的處理。在 MCMS 的 Posting 中,真正儲存資料的地方是 Placeholder(一篇 Posting 通常會包含數個 Placeholder 以存放資料,端看產生此篇 Posting 的 Template 如何設計而定),以下便以 XmlPlaceholder 為例,示範如何撰寫更新動作的程式碼:

XmlPlaceholder xp = p.Placeholder["Placeholder name"] as XmlPlaceholder;
xp.XmlAsString = "Your new xml content";


在更新動作完成後,有兩種選擇,一是將更新儲存但保持未發佈狀態,二是直接將更新後的 Posting 發佈。前者只會建立一新版本的 Posting 並保存更新狀態,真正供一般使用者瀏覽的 Posting 版本仍是上次發佈的版本。先示範儲存的寫法:

cac.CommitAll();

非常簡單,僅需呼叫 CmsApplicationContext 物件的 CommitAll 方法。再來示範直接發佈的寫法:

if( p.CanSubmit ) { p.Submit(); }
if( p.CanApprove ) { p.Approve(); }
cac.CommitAll();


欲直接發佈 Posting 時,要先呼叫該 Posting 物件的 Submit 方法,再呼叫 Approve 方法,最後跟儲存時的寫法一樣,呼叫 CmsApplicationContext 物件的 CommitAll 方法作為結束。上述的程式碼片段,使用了 CanSubmit 和 CanApprove 兩個 Posting 屬性做確認動作,可防止因登入使用者權限不足而導致的例外錯誤擲出。

以上,便是在撰寫 MCMS Posting 更新程式時的主要關鍵步驟,供大家參考。

[re-post this article due to database crash.]

Use .NET program to renew GSA crawling header

Now, I gonna guide you how to submitting form datas to GSA by using HTTP header as example.

In my previous article [Using .NET HttpWebRequest to pass through GSA login form], I talked about how to use .NET HttpWebRequest object to pass through GSA(Google Search Appliance) authentication framework. Now, I gonna guide you how to submitting form datas to GSA. (I will use HTTP header setting page under GSA admin console as example.)

Imagine that you have a system which only allows authenticated user and you want to configure GSA to crawl into it. That system does not integrate with Microsoft Active Directory server and has its own authentication framework, so we plan to get a cookie for GSA from that system. However, it is a ASP.NET web application running .NET 2.0 run time and does not provide indefinite duration cookie, so any cookie that we assign to GSA will be expired after a period of time. Although we could manually renew GSA cookie but it is much preferable that we could develop a program doing it for us. So here is the solution.

First, you need to follow the procedure that I introduced in [Using .NET HttpWebRequest to pass through GSA login form] to login GSA admin console page. Then, because we will submitting our data to HTTP Header setting page through HTTP POST, so we need to build the data string first. There has two input columns on HTTP Header page of Google Admin Console, one is "user agent name" and the other is "HTTP header". Please reference the full string from below:

string strContent = "actionType=httpHeaders&userAgent=[user agent name]&addHTTPHdrs=" + Server.UrlEncode("[HTTP header content]") + "&httpHeadersSave=+%E6%9B%B4%E6%96%B0%E6%A8%99%E9%A1%8C%E8%A8%AD%E5%AE%9A";

Please pay attention on a special key value of "HttpHeadersSave". You need to add it into full string or form submit won't be successful. Also, the HTTP header may contain special character so we use UrlEncode method of Server object to encode it. Once we have the full data string, we need to tranfer it to byte array:

ASCIIEncoding asciienc = new ASCIIEncoding();
byte[] byteContent = asciienc.GetBytes( strContent );


Finally, we will use HttpWebRequest object again to send out the request. The objects "req", "cc" and "s" below are HttpWebRequest, CookieContainer and Stream classes we created when logon GSA admin console. (Please reference the article [Using .NET HttpWebRequest to pass through GSA login form] for the details.)

req = HttpWebRequest.Create("http://[GSA URL]/EnterpriseController") as HttpWebRequest;
req.CookieContainer = cc;
req.Referer = "http://[GSA URL]/EnterpriseController?actionType=httpHeaders";
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
req.ContentLength = byteContent.Length;

s = req.GetRequestStream();
s.Write(byteContent, 0, byteContent.Length);
s.Flush();
s.Close();


That's all! You could based on the codes above to develop programs submitting data to all kind of GSA admin console pages.

[re-post this article due to database crash.]

Use .NET HttpWebRequest class to pass through GSA login form

Now let me show you how to use HttpWebRequest to pass through GSA login form. After that, you can extract the web page content by yourself.

The GSA (Google Search Appliance) login form has a special authentication framework to pervent the hacking. It is based on assigning several cookies to client browser during HTTP connecting session. Now let me show you how to use HttpWebRequest to pass through GSA login form. After that, you can extract the web page content by yourself.

First, you need to maintain a CookieContainer object during the whole process:
CookieContainer cc = new CookieContainer();

Then, we need to create a byte array to store the login data, please replace [User Name] and [password] in string loginData below to your case in GSA:
string loginData = "actionType=authenticateUser&login=Login&userName=[User Name]&password=[Password]";
ASCIIEncoding asciiEnc = new ASCIIEncoding();
byte[] byteArray = asciiEnc.GetBytes(loginData);

process 3 times http request to pass through GSA login form, please replace [GSA URL] to your case:
// first time
HttpWebRequest req = HttpWebRequest.Create("http://[GSA URL]/") as HttpWebRequest;
req.CookieContainer = cc;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
HttpWebResponse res = req.GetResponse() as HttpWebResponse;

// second time
req = HttpWebRequest.Create("http://[GSA URL]/EnterpriseController") as HttpWebRequest;
req.CookieContainer = cc;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
res = req.GetResponse() as HttpWebResponse;

// third time
req = HttpWebRequest.Create("http://[GSA URL]/EnterpriseController") as HttpWebRequest;
req.CookieContainer = cc;
req.Referer = http://[GSA URL]/EnterpriseController;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
req.ContentLength = byteArray.Length;
Stream s = req.GetRequestStream();
s.Write(byteArray, 0, byteArray.Length);
s.Close();
res = req.GetResponse() as HttpWebResponse;

OK, now we can pass parameters to get any web page content, please replace [Parameters] from code snippet below to your customized one:
req = HttpWebRequest.Create(http://[GSA URL]/EnterpriseController/?actionType=[Parameters]") as HttpWebRequest;
req.CookieContainer = cc;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
res = req.GetResponse() as HttpWebResponse;
s = res.GetResponseStream();
StreamReader sr = new StreamReader(s);
string result = sr.ReadToEnd();
sr.Close();
s.Close();

The result string is the final web page content.

[re-post this article due to database crash.]