2012-02-06

Windows 7 : add Command Prompt in right click context menu

Original: http://www.blogsdna.com/2226/windows-7-add-elevated-command-prompt-option-in-right-click-context-menu.htm

cmd2folder.reg, right click on file -> Merge


Windows Registry Editor Version 5.00


[HKEY_CLASSES_ROOT\Directory\shell\runas]
@="Command Line (Administrator)"


[HKEY_CLASSES_ROOT\Directory\shell\runas\command]
@="cmd.exe /s /k pushd \"%V\""

2011-11-01

Create self-signed certificate for localhost/DEV web server (enabled https/ssl)



Purposes

Để enabled SSL dùng trong flow xAuth, https://api.xxxyyy.vn/v1/oauth/access_token. Tạo môi trường test tại localhost hay server dev.

Download OpenSSL binary

1.       Download OpenSSL binary http://gnuwin32.sourceforge.net/packages/openssl.htm, bản mới nhất hiện tại là openssl-0.9.8h, extract phần bin (folder bin có chức các file exe như openssl.exe) vào folder giả sử D:\ openssl-0.9.8h.

2.       Tạo folder tương ứng certs, config, keys, p12, requests. Có thể chỉ dùng 1 folder cũng được

3.       Tạo file text database.txt, command tương ứng là

D:\openssl-0.9.8h>copy con database.txt
^Z

4.       Tạo file text serial.txt, nội dung có 1 dòng là 01

D:\openssl-0.9.8h>copy con serial.txt
01
^Z

5.       Download file config openssl.cnf, search trên Google là có liền (http://stuff.mit.edu/afs/athena/contrib/crypto/openssl.cnf hoặc copy từ thư mục Apache config của Wamp Server D:/Wamp/bin/apache/Apache2.2.17/conf) và copy vào folder config. Chỉnh lại các giá trị trong file config cho phù hợp: ví dụ dưới dùng dir = thư mục hiện tại (dấu .)

dir            = .
certs = $dir/certs
database = $dir/database.txt
new_certs_dir = $dir/certs
serial = $dir/serial.txt
...

6.       Bắt đầu dùng command line thực hiện các bước mô tả bên dưới, phần đường dẫn D:\ openssl-0.9.8h> trong các command bỏ qua.

Create CA key, self-signed CA cert

1.       Tạo CA key, command này sẽ yêu cầu một password

openssl genrsa -des3 -out keys\ca-key.pem 1024

2.       Tạo CA self-signed, output vào folder certs, valid 10 năm, dùng config file trong folder config đã chuẩn bị, phần Your Name ví dụ là company.com
openssl req -config config\openssl.cnf -new -x509 -days 3650 -key keys\ca-key.pem -out certs\ca-cert.cer

Backup/Remove passphrase from key

1.       Backup CA key

copy keys\ca-key.pem keys\ca-key-org.pem

2.       Tạo RSA private key

openssl rsa -in keys\ca-key-org.pem -out keys\ca-key.pem

Tới đây đã có CA cert và CA key

Create localhost (web server) private key (optional)

1.       Tương tự tạo private key cho web server (ở đây gọi là localhost hay xxxyyy) giả sử password là password localhost.key.

openssl genrsa -des3 -out keys\server-key.pem 1024

2.       Backup CA key

copy keys\server-key.pem  keys\server-key-org.pem

3.       Tạo RSA private key

openssl rsa -in keys\server-key-org.pem -out keys\server-key.pem

Bước này không cần thiết, vì trong bước sau sẽ thực hiện tạo Certificate Signing Request cùng với Private Key.

Create CSR + Private key

Tạo csr kết quả sẽ output trong folder requests, đồng thời tạo private key cho web server, phần Your Name nên để là localhost, tức địa chỉ localhost hay nếu dùng địa chỉ khác thì là www.company.com
openssl req -new -nodes  -days 3650 -config config\openssl.cnf -out requests\server-request.csr -keyout keys\server-key.pem

Sign request WITH CA key

Dùng command openssl ca để ký lên yêu cầu vừa mới tạo trong bước trước

openssl ca -policy policy_anything -config config\openssl.cnf -cert certs\ca-cert.cer -in requests\server-request.csr -keyfile keys\ca-key.pem -days 3650 -out certs\server-cert.cer

Create DER/p12

1.       Tạo DER format cer bằng command

openssl x509 -in certs\ca-cert.cer -outform DER -out certs\ca-cert.der

2.       Tạo p12 bằng command

openssl pkcs12 -export -in certs\ca-cert.cer -inkey keys\ca-key.pem -certfile certs\ca-cert.cer -out p12\ca.p12

Install CA as Trusted Root CA

Double click vào CA cert và install vào Trusted Root Certification Authorities store.

Install Cert with Wampserver

1.       Enable SSL trong file config của Apache, uncomment load module SSL và include HTTPS config

D:\Wamp\bin\apache\Apache2.2.17\conf\httpd.conf

LoadModule ssl_module modules/mod_ssl.so

Include conf/extra/httpd-ssl.conf

2.       Copy cert và private key của localhost vừa tạo vào folder config của WampServer Apache D:/Wamp/bin/apache/Apache2.2.17/conf
3.       Replace đường dẫn sai trong extra/httpd-ssl.conf dạng path-to-Apache-folder đang bị sai thường là c:/Apache2 thành D:/Wamp/bin/apache/Apache2.2.17 (tùy version và path đang dùng)
4.       Uncomment và chỉnh các giá trị SSLCertificateFile và SSLCertificateKeyFile

SSLCertificateFile "D:/Wamp/bin/apache/Apache2.2.17/conf/server-cert.cer"
SSLCertificateKeyFile "D:/Wamp/bin/apache/Apache2.2.17/conf/server-key.pem"

5.       Chỉnh lại đường đẫn enable SSL, có thể enable cả www của Wamp Server trong httpd-ssl.conf

DocumentRoot "D:/Wamp/www"
ServerName localhost:443

Testing

Nếu không start được wampapache. Có thể bị lỗi sau (xem trong event logs) có thể cần load thêm module mod_socache_shmcb 


The Apache service named  reported the following error:
>>> SSLSessionCache: 'shmcb' session cache not supported (known names: ). Maybe you need to load the appropriate socache module (mod_socache_shmcb?).     .


2011-09-16

Remove SQL Server 2005 Express Tools - Install SQL Server Management Studio Express 2008, stupid installer

Khi install SQL Server Management Studio Express (SSME) bị cái lỗi "The SQL Server 2005 Express Tools are installed. To continue, remove the SQL Server 2005 Express Tools.".


Sau khi search Google mới tìm được cách pass qua đồ khi đó.
http://social.msdn.microsoft.com/Forums/en-US/sqlsetupandupgrade/thread/5fc58507-9f40-4213-acbd-32a57c8822d7/
http://dotnetguts.blogspot.com/2010/06/remove-sql-server-2005-express-tools.html

Solution
1) Open Run Menu and type regedit.
2) It will open Registry Editor
3) Now go to following location.
HKEY_LOCAL_MACHINE > Software > Microsoft > Microsoft SQL Server > 90

4) Remove Registry Key 90.

Thêm nữa cái installer của SSME installer cực kỳ ngu. Phải chọn install new instance, tất nhiên dù có chọn new instance thì cũng chằng có instance mới nào được install cả (yên tâm). Chỉ cần install bình thường với cách chọn new instance và check Management Tools - Basic. Thế là xong.

2011-09-12

Node.js evented I/O for V8 Javascript.

What is Node.js

Hôm nay mình sẽ note lại mình đã play với Node.js như thế nào. Thực ra thì mình cũng biết sơ về cái món này. Biết thông qua website/blog của Felix http://debuggable.com/. Developer này tất nhiên là quá quen đối với những người xài CakePHP và anh ta hiện giờ chuyển wa chơi với Node.js là core contributor. Mới đầu thì cũng chẳng biết nó là gì, sau thấy viết code server-side bằng Javascript trông rất sáng sủa, mình cũng mê code Javascript, có một chút gì đó tự do :D. Sau một thời gian làm và OK đã biết chút chút thì note lại cho khỏi quên.

Đến version này thì đã có bản build node.exe cho Windows, trước kia thì phải install Cygwin. OK nói đến đây thôi chỉ để biết nó là server-side Javascript. Và nên biết thêm V8 Javascript Engine là gì. Giờ thì play 1 chút.

Installation
Download node.exe dành cho Windows về, chạy lên chỉ ra màn hình có dấu nhắc lệnh > như command prompt. Với Linux hay Mac thì install cũng không mấy khó khăn. Nếu có thể install git hay download source tar và make là xong. Mình lấy Windows làm dev enviroment.


Giờ tạo một function đơn giản thực hiện phép cộng, nhấn Enter nó sẽ tự động indent bằng ... cho mình như trong hình. Cách viết như các ngôn ngữ script khác gọi là REPL read-eval-print loop. Mình không đi sâu nó là gì, chỉ cần biết dùng thử ntn đã.


Felix có một trang gọi là study guide rất đáng để tham khảo.

Demo
Vậy tiếp theo làm gì, tất nhiên không viết code trên cái màn hình như cmd đó được. OK copy cái ví dụ trên trang chủ http://www.nodejs.org/  thành một file gọi là server.js saved cùng thư mục với node.exe. Server này mở port 1337, trả về 200 OK result là Hello World với tất cả request, một simple dummy web server.
  
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

Chúng ta sẽ chạy script này, để thuận tiện từ đây chúng ta dùng PowerShell dùng command line cũng OK. Với Windows 7 thì PowerShell được shift sẵn, bình thường mình găm nó vào taskbar luôn (taskbar của mình theo thứ tự là Windows Media Player, Unikey, PowerShell). Nếu chạy bình thường thì gọi Windows + R -> gõ powershell. Nếu đã găm vào taskbar thì đơn giản Windows + số thứ tự trên taskbar như mình là Windows + 3. OK launch PowerShell change dir (cd) tới file server.js và node.exe. Chạy command
  
.\node.exe .\server.js


Như vậy ta đã có server, port 1337. Giờ test server bằng Firefox chẳng hạn, localhost:1337 sẽ được hello string. Stop server đơn giản như terminate command, Ctrl + C. Tới đây dể thấy tạo server đơn giản như thế nào.

 

Các vấn đề khác thuộc về cách sử dụng hay syntax hay style; ví dụ như closure, sử dụng module, callback; thì có lẽ tự tìm hiểu sẽ tốt hơn là nói ở đây.

What next?
Nhưng giờ có con dao này rồi sẽ làm gì, viết web thì với những gì có thể làm được với PHP -> say no vì ko thể cầm con dao nhỏ mà giết chết con khủng long. Nếu tham khảo bài viết của Felix bạn sẽ biết một vài trường hợp mà Felix kêu là bad use cases.

Vậy nó làm gì, hiện tại thì chưa có gì nhiều nhưng nếu dùng build một light-weight service thì rất phù hợp. Ví dụ một REST API service hay chat server. Nếu để ý thì rất nhiều chat server đã triển khai dùng Node.js. Có thể kể là Ajax IM hay Faye và vô số những ví dụ trên GitHub chỉ cần search 1 chút là ra. Faye giới thiệu là implement Bayeux protocol. Mình không đi sâu mô tả protocol này nhưng mình không lựa chọn Faye cũng như chỉ tham khảo Ajax IM. Có lẽ bạn nên chọn Node.js + Socket.IO và thử viết cái gì đó, rồi từ từ cải tiến theo cách bạn muốn, có thể là tổ chức lại hay implement theo Bayeux.

Authentication with Node.js and Socket.IO
Vấn đề tiếp theo mình đề cập lại việc chứng thực giữa Node.js và Socket.IO. Socket.IO có mục config gọi là handshake function như sau:

// create io
var io = sio.listen(PORT);

io.configure(function() {
    io.set('authorization', function (data, callback) {
        authorizePhpSession(data, callback);
    });
});

Xem thêm tài liệu của Socket.IO tại đây https://github.com/LearnBoost/socket.io/wiki/Authorizing

Bạn có thể tham khảo từ bài viết sau http://anthonyw.net/2011/07/authentication-with-node-js-and-zend-framework/. Tuy nhiên mình sẽ nói rõ hơn chút xíu.

Client khi connect sẽ gửi thông tin lên server bao gồm cả cookie và các thông tin khác. Như vậy hình dung ta có scenario như sau: user login vào site theo cách thông thường, web server sẽ lưu lại thông tin của user trong session: có thể là file session hay memcache. Giả sử trong PHP dùng file session thì thông tin sẽ trong một file mà server sinh ra trong thư mục chỉ định dạng sess_{session-id}. Khi user đã login và chuyển qua page chat, Socket.IO client (Javascript) sẽ kết nối với chat server (Node.js server), Node.js phải thực hiện authorization, quyết định cho phép client connect hay không thông qua thông tin của client cung cấp. Ta chú ý đến thông tin Session ID sẽ được client send thông qua cookie. Nếu OK sẽ gọi callback với tham số true, ngược lại là false và error. Giả sử web server chạy PHP và không dùng memcache. Khi đó session file sẽ có dạng

var sessionFile = SESSION_PATH + "/sess_" + sessionId;

Thực hiện authorize bằng session như sau:

function authorizePhpSession(data, callback) {
    Controller.log("Get handshake data from client: " + sys.inspect(data));

    var sessionId = getPhpSessionId(data.headers.cookie);
    Controller.log("Receive session ID: " + sessionId);

    // extend handshake data with PHP Session ID
    data.phpSessionId = sessionId;

    try {
        if(!USE_MEMCACHE) {
            getFileSessionData(data, sessionId, callback);
        } else {
            getMemcacheSessionData(data, sessionId, callback);
        }
    } catch(e) {
        callback(null, false);
    }
}

Lấy PHP SESSION ID trong cookies gửi lên. Lưu ý domain của web site và Node.js server phải giống nhau thì client mới send thông tin cookies.

function getPhpSessionId(cookies) {
    var result = "";
    cookies.split(";").forEach(function(a) {
        var b = a.split("=");
        if(b[0].trim() == PHP_SESSION) {
            result = b[1].trim();
        }
    });

    return result;
}

Example đọc thông tin session trong file

function getFileSessionData(data, sessionId, callback) {
    Controller.log("Get session data from session file with Session ID: " + sessionId);

    var sessionFile = SESSION_PATH + "/sess_" + sessionId;      
    try {
        fs.readFile(sessionFile, "utf8", function(err, fileData) {
            if(err) {   // not exists session
                Controller.log("Can not read session data from file path { session: '" +
            sessionFile + "', error: '" + sys.inspect(err) + "' }");
                callback(null, false);
            } else {
        if(fileData.indexOf(SESSION_AUTH + "|") == -1) {    // not logged in yet
            // not things here, not authorize for this connection
            callback(null, false);
        } else {
            fileData = fileData.substr((SESSION_AUTH + "|").length);

    // extend handshake data with user session data
            var sobj = utils.unserialize(fileData);

    if(sobj.storage) {
                data.user = sobj.storage;
                callback(null, true);
            } else {
        Controller.log("Not valid authentication session data for { session: '" +
            sessionId + "', result: '" + fileData + "' }");
                callback(null, false);
            }
                }
            }
        });
    } catch(e) {
        Controller.log("Error when get authentication information { session: '" + sessionId +
            "', error: '" + sys.inspect(e) + "' }");
        callback(null, false);
    }
}

Có thể dùng RegEx để tìm thông tin authentication thay vì unserialize string trong trường hợp thông tin session quá dài và quá khó để unserialize.

function getMemcacheSessionData(data, sessionId, callback) {
    Controller.log("Get session data from Memcache Server with Session ID: " + sessionId);

    try {
        memcache.get(sessionId, function(err, result) {
            if(err) {
               Controller.log("Can not read session data from Memcache Server { session: '" +
                    sessionId + "', error: '" + sys.inspect(err) + "' }");
               callback(null, false);
          } else {
              var match = result.match(SESSION_REGEX); // using regex to extract authentication information
              if (match != null) {
                  data.user = {
                     id: match[1],
                     username: match[2],
                     email: match[3],
                     first_name: (match[4] == null || typeof match[4] == "undefined") ? "" : match[4],
                     last_name: (match[5] == null || typeof match[5] == "undefined") ? "" : match[5],
                  }

                  Controller.log("Authentication information { session: '" +
                     sessionId + "', user: '" + sys.inspect(data.user) + "' }");
                  callback(null, true);
              } else {
                  Controller.log("Not valid authentication session data for { session: '" +
                     sessionId + "', result: '" + result + "' }");
                  callback(null, false);
              }
          }
        });
    } catch(e) {
        Controller.log("Error when get authentication information { session: '" + sessionId +
                    "', error: '" + sys.inspect(e) + "' }");
        callback(null, false);
    }
}

Còn một phần nữa nói về cách giao tiếp giữa Node.js server và Java server khác như game server (vì thường game server implement bằng Java. Giải pháp của mình là dùng message queue như RabbitMQ, tuy nhiên có lẽ đề một dịp khác sẽ giới thiệu.

2011-08-02

Using Link Shell Extension to create NTFS Junction

Trước giờ mọi người nghe nhiều về NTFS, sử dụng Windows không biết bao nhiêu năm và cũng không ai xa lạ gì với create shortcut. Nhưng chắc chắn rất ít người biết rõ về link của NTFS: thế nào là symbolic link hay junction. Những ai tiếp xúc với Linux thì sẽ quen với khái niệm link còn người dùng Wins thì phần lớn chỉ biết shortcut.

Tuy nhiên shortcut không phải khi nào cũng dùng được, nó có nhiều hạn chế hơn những dạng khác mà những dạng này ít người biết mà Wins cũng không hỗ trợ trực tiếp. Mình sẽ không nói gì về lý thuyết cả, chỉ giới thiệu một cách dùng Junction của NTFS trong thực tế như thế nào. Sẵn tiện cài xong game mình viết một vài dòng luôn. Vì sao lại dùng Junction thì có thể tham khảo link http://comptb.cects.com/2268-overview-to-understanding-hard-links-junction-points-and-symbolic-links-in-windows
Mình trích 1 đoạn như sau:


Junction Point (Directory Hard Link):
  • A file that acts like a representation of a target directorypartition or volume on the same system
  • Has the same size as the target without duplicating it (doesn’t use any space)
  • Interpreted at the operating system level – transparent to SW programs and users
  • Deleting the Junction Point does not remove the target*
  • If the target is moved, renamed or deleted, the Junction Point still exists, but points to a non-existing directory
  • Changing the contents through the Junction Point changes the target contents
  • Can reside on partitions or volumes separate from the target on the same system
  • Compatible with Win2k and above in Windows
*A Junction Point should never be removed in Win2k, Win2003 and WinXP with Explorer, the del or del /s commands, or with any utility that recursively walks directories since these will delete the target directory and all its subdirectories. Instead, use the rmdir command, the linkd utility, or fsutil (if using WinXP or above) or a third party tool to remove the junction point without affecting the target. In Vista/Win7, it’s safe to delete Junction Points with Explorer or with the rdir and del commands.
Symbolic Link (Soft Link):
  • A file containing text interpreted by the operating system as a path to a file or directory
  • Has a file size of zero
  • Interpreted at the operating system level – transparent to SW programs and users
  • Deleting the Symbolic Link does not remove the target
  • If the target is moved, renamed or deleted, the link still exists, but points to a non-existing file or directory
  • Points to, rather than represents, the target using relative paths
  • Can reside on partitions or volumes separate from the target or on remote SMB network paths
  • Compatible with UNIX and UNIX-like systems and with Vista and above in Windows
Shortcut:
  • A file interpreted by the Windows shell or other apps that understand them as paths to a file or directory
  • File size corresponds to the binary information it contains
  • Treated as ordinary files by the operating system and by SW programs that don’t understand them
  • Deleting the shortcut does not remove the target
  • Maintains references to target even if the target is moved or renamed, but is useless if the target is deleted
  • Points to, rather than represents, the target
  • Can reside on partitions or volumes separate from the target on the same System
  • Compatible with all Windows versions


Ví dụ 1: chơi The Sims, download objects phải để trong My Document/EA Games/The Sims 2/Downloads, nhưng việc này dẫn đến 2 vấn đề rắc rối: thứ nhất dung lượng ổ C chẳng hạn có giới hạn, thứ 2 muốn giữ lại download mỗi khi cài lại máy hay muốn để một nơi nào đó (một ổ đĩa khác ổ Data là D:).

Ví dụ 2: một trường hợp nữa là khi không muốn cài hết tất cả trong C: vì lỡ chia partition quá nhỏ mà không resize được, nhưng một số app rất khó chịu, đã chọn installation location là ổ đĩa khác vẫn install vào C: (điển hình là Visual Studio).

Lúc này mình sẽ dùng Junction như sau:

Bước 1: download  hardlink shell, một tiện ích miễn phí cho phép tạo các dạng NTFS link khác nhau, ở đây mình sẽ xài Junction
http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html
Trong trang download cũng có chỉ cách dùng, tuy nhiên để rõ ràng mình sẽ mô tả cách dùng Junction.

Bước 2: cài đặt link shell extension. Sau khi cài đặt xong, nhấp chuột phải vào một folder nào đó sẽ có một shell extension là 'Pick Link Source'. Tới đây là đã cài Link Shell Extension thành công.

Bước 3: cách dùng
Giả sử với ví dụ 1 ở trên. Chúng ta muốn link The Sims 2/Downloads sang ổ data D: chẳng hạn (có nghĩa là chúng ta cần kết quả cuối cùng trong The Sims 2 có folder Downloads nhưng thực chất nó là một folder ở D:).
- Tạo trong D:\My Games\The Sims 2\Downloads. Phần trước Downloads là gì cũng được tùy bạn quản lý nhưng phần sau chắc chắn là Downloads. Đây là folder thật 100%.
- Chọn chuột phải, hiện ra 'Pick Link Source', thực hiện Pick Link Source bằng cách click vào đó ;-). Sau bước này chúng ta đã chọn link source.
- Vào My Document/EA Games/ tức tại đây chúng ta thấy folder The Sims 2 nghĩa là folder cha của Downloads mà chúng ta sẽ tạo, nhấn chuột phải, lúc này sẽ thấy xuất hiện Cancel Link Creation tức hủy việc tạo link (nếu tạo nhầm chẳng hạn), và Drop As ..., ta chọn Drop As ... -> Chọn Junction, như vậy là đã tạo link xong. 





Folder link sẽ có biểu tượng link nhỏ bên góc biểu tượng folder, nếu nhấn chuột phải thì trong menu context sẽ có mục Delete Junction.


- Giờ test thử, new một text document (New Text Document.txt) ngoài desktop chẳng hạn, paste vào My Document/EA Games/The Sims 2/Downloads hay vào trực tiếp tạo text file trong Downloads link folder mới tạo, rồi chuyển sang D:\My Games\The Sims 2\Downloads, trong đó có file text vừa tạo. Bây giờ 2 folder ở 2 vị trí nhưng bản chất là một.


Với ví dụ 2: chúng ta làm tương tự, giả sử cài Visual Studio 2010, tạo trong D: thư mục là D:\Microsoft Visual Studio 10.0 (là default installation folder name). Chọn Pick Link Source, xong vào C:, chọn chuột phải lên folder Program Files, và chọn Drop As ... > Junction. Sau khi thực hiện xong chúng ta cài Visual 2010 bình thường, chọn thư mục cài đặt là C:\Program Files\Microsoft Visual Studio 10.0, thực chất sẽ cài lên ổ D:. Có thể mình cài trước, rồi move cái folder cài đó sang D:, xong tạo link ngược lại cũng OK.

Vậy là có thể bạn đã biết thêm 1 các dùng link trong Windows. Rất cảm ơn developer tạo ra cái shell extension này, rất tiện lợi.
Nice day,

2011-07-09

Install The Sims 2 with Windows 7 compatibility issues (all EPs and SPs)

Hôm nay ngồi cài The Sims 2 cho vợ, lần trước cũng kêu sẽ cài nhưng rồi bị lỗi không cài được vài EP nên thôi không cài nữa. Lần này mới cài lại máy, nghĩ cũng tức không cài được EP thì chơi cái gì nữa. Mình cũng có sở thích 'giết người' và 'xây nhà tập thể' (có nghĩa là sưu tập bia mộ hoặc xây sao ở nhiều người mà bọn nó ko xung đột) trong The Sims 2.

OK vấn đề là sau khi install 4 đĩa gốc từ Disk 1 đến Disk 4, có thể chơi nếu chỉnh
Compatiblity mode Windows XP SP2 + Disable visual themes, Disable desktop composition, Privilege Level Admin (optional). Tới đây thì có thể chơi game rồi nếu không patch hoặc cài thêm EP. Tất nhiên ta không dừng lại ở đây.

The game will now run but you will not be able to install the patch or add a new EP. This is because each EP checks for an update which Windows 7 co-operate with. In my experience I still wasn’t able to install the patch even run TSBin/TS2UPD.exe in compatibility mode.

Bản patch có thể download tại website của EA nhưng không cần download nếu tiếp tục cài thêm EP.

The patch can be downloaded at http://thesims2.ea.com/update/ but it's unnecessary if we continue install EPs. The updater will automatic launch the patch after EP installation completed.

+ Patch, EPs installation

Nhưng tới đây vẫn chưa thể cài EP, nói chính xác là bản EP1 University. Nó sẽ ra thông báo 'Please insert The Sims 2 CD 4 to continue' và không thể hoàn tất cài đặt.

Can't complete patch after install EP1, even both Physical DVD and Virtual DVD Drive have The Sims 4 CD). If we cancel, the installer will rollback, OMG.

Tới đây thì đuối rồi, search hoài không ra cách nào để qua bước này. Cuối cùng thì mình cũng đã làm được. Tới đây đừng đụng đậy gì đến nó, shutdown máy và vào chế độ Safe Mode, F8. Nhớ là khi vào chế độ Safe Mode ta dùng Physical CD/DVD Drive vì Virtual CD/DVD Drive không hoạt động. Chạy EP1 Install Folder/TSBin/TS2UPD.exe với compatiblity mode. OK thành công.

After installation completed and the installer launch the patch, ignore the dialog 'Please insert The Sims 2 CD 4 to continue' and shutdown the PC. Restart PC in Safe Mode (F8), alter the patch/updater to compatibility mode and complete patch with The Sims 2 CD 4 in Physical CD/DVD Drive.

Kết luận:

1. Cài đặt 4 đĩa The Sims 2, sẽ chơi được với compatiblity mode. 
Completed install 4 CDs, alter the compatibility of the game. The game is runable in compatiblity mode (it's not all we needs).

2. Cài EP và để thông báo lỗi đó, thực hiện tắt máy.
Complete EP installation, leave the updater message alone, turn off PC.

3. Khởi động với Safe Mode
Start PC in Safe Mode

4. Chạy patch với compatibility mode
Alter the compatibility of the patch (EP Install Folder/TSBin/TS2UPD.exe)

5. Cài patch thành công
Install patch

6. Restart và tiếp tục cài trong Safe Mode với các EP còn lại nếu không patch được
Repeat install in Safe Mode with the next EPs. Restart and run game

2011-06-09

AS3 Array size hole



Nhiều khi code ra cái lỗi không thể nghĩ đến, may mà search ra (smartfoxserver2 forum)

The length property does not really return the size of the array, but return the highest index available.

var a:Array = []
a[1000] = "Hello"
trace(a.length)

It will return a lenght of 1001, which is clearly not the size of the Array.