Remote Desktop from Win to Mac via Chrome Remote Desktop

Google Chrome Remote Desktop Extension is really amazing!!!!!
I try to install the extension on both Chrome on my iMac and the one on my laptop with Win 7.
Then I try to connect the iMac from Win 7 via Chrome Remote Desktop!
The performance is really amazing!!!! It is less well than Windows RDP but much better than the famous but sucks VNC!!!!!
I totally have no idea how Google implemented this! But it do works super well in my environment!

Chrome Remote Desktop to Mac

You know, before Chrome Remote Desktop, there is only one real cross platform remote desktop solution: VNC, and the performance of which is unacceptable poor, and we have to install a lot of ugly software to make it happen.
But now, we can achieve it by simply install chrome and the chrome extension….
It is amazing!

I found the desktop fade in animation works smoothly via remote desktop! And I can even play movie from Mac!!!!!

Play Movie on Mac via Chrome Remote Desktop

While playing video, the peak of the network traffic might be reach 800kBps to 1MBps… but normally it should be 300 kBps…..

But since it is only the beta version, so there are some limitations in Chrome Remote Desktop:

  1. The Hotkey doesn’t work well, which means you cannot Press Cmd+Space to pop up quick-silver or spot-light…
  2. Mouse Wheel doesn’t work well, which means you cannot scroll the page with your mouse wheel, or magic mouse.
  3. Sound doesn’t bring to remote side, if you wanna play movie with Chrome Remote Desktop, then you might be have to read the subtitle rather than hear the speech.
  4. CPU consuming is high, I guess Chrome Remote Desktop spend a lot of CPU power on compressing the data to be transferred, so the CPU consuming is higher than other Remote Desktop solution……

And special Precondition required for Chinese Netizens:
If you are try to use Chrome Remote Desktop in China, this miracle land, you might need some other special technology tool to help you get rid of the famous GFW. To my experience, sometimes Remote Desktop OAuth might be blocked by GFW.

TDD vs Natural Selection : Part II

As discussed in previous part, both TDD and natural selection can produce suitable designs. But there are costs.
The design from natural selection is just perfect, but the cost is 99% unsuitable species die out. It is the cost of life.
Same to TDD, except TDD isn’t so cruel. If you try to write a piece of code in TDD and pure factoring way, which means all the designs are in order to eliminate smell. And you might find that to eliminate the smell sometime is not so easy that you can have it done in minutes. You might need several tries to find out the most proper approach, since you might find that you just introduced a new, and maybe more serious smell while you eliminating a smell. Sometimes you might find that the upcoming new smells just drive into a dead road, and you just want revert the changes and retry from a fresh start. In worst case, you might find you can hardly find the right way, and you just got lost in the code.
In some simple project, you might find the situation is just acceptable, but in some complex project, you can hardly do that or you might find at the end of the day you and your pair produced nothing with great effort.

So in my opinion, TDD doesn’t mean no design at all. When you practicing TDD, you must focus on the detailed code. At this time if you can easily got lost without the guide from a clear, more general, high level vision. It just works like the architecture design or general solution to specific type of problem.

Such design can save you tons of time wasted on times of retries.

FluentAssertion is not compatible with xUnit.Extensions

I met a weird problem that I found the Resharper Test Runner hangs when I introduced theory test case in my unit test.
After some spikes, I found the problem seems caused by the incompatibility between Fluent Assertion and xUnit.Extension.
It is wired, and there seems to be no quick fix.
So I replace the Fluent Assertion with Should and Should.Fluent, which is a port of ShouldIt.
After that, everything goes well except the syntax between Fluent Assertion and Should Fluent are not compatible with each other, although they’re really similar.
But Should.Fluent doesn’t support something.Should.Be(), it requires something.Should.Be.Equals(), which is really annoying to me.

According to the Fluent’s introduction, Fluent is a direct fork of xUnit. And I’m not sure what’s the impact caused by this.

TDD vs Natural Selection

After practiced TDD for almost a month, I guess I began to understand why TDD can possibly generate the best suitable design, although there is no one actually did the design work. It is interesting that if something is not intended to be done but actually has been done finally. It means that the design is actually done gradually and silently during the TDD process.
I always wondering what actually happened leads to such a result. Then I guess I have found the answer from Darwin’s theory. Think about the various lives on the planet, there is no one who designed them, but they are just so reasonable and harmony with the environment.
Why? Natural selection!
Natural selection ensures a trend of the life evolution, which makes the life to be more and more suitable to the environment, by serious survival tests. Unsuitable life just died out, the remained are the suitable.
Comparing to natural selection, you can find the similar gene in TDD. They both got tests and the test result eliminates the unsuitable design, which actually drives the design more and more fit to the requirements in a most efficient way.

Push Data Flow Model in C# 4.0

In the pre 4.0 era, there are two interfaces reveal a new world to .net world. The two hero are IEnumerable<T> and IEnumerator<T>.
Based on these two interfaces, .net introduced a lot of amazing staffs that dramatically simplified the development related to data flow, these well known features are: foreach loop, yield keyword, and LINQ.
These 2 interfaces provide an common abstraction layer for the operation that pull data from the data source. And with this abstraction, you can apply foreach loop to almost every kind of data source in the .net world.
IEnumerable<T> and IEnumerator<T> are cool, but they are somehow not so convenient to use in some cases, such as in asynchronous context or in obvious latency environment.
And the pull data flow model also has a capable brother, the push data flow, which can fill up the gap that pull model left for us.

So in .net 4.0, Microsoft introduce another 2 great interfaces, called IObservable<T> and IObserver<T>. These two interfaces, just as IEnumerable<T> and IEnumerator<T>, also open a door to the new world for every .net developer. With these 2 interfaces, people can setup a lot of features that corresponding to IEnumerable<T> and IEnumerator<T>.

Now Microsoft has a great library that called Rx(which stands for “Reactive Extension”), which provided a lot of features that similar to LINQ and more based on IObserable<T> and IObserver<T>.

Sync Notify Pattern for WPF Cross Thread View Model

WPF has a powerful data binding mechanism, by which it is easy to implement MVVM and MVC pattern for UI application.
But thing gets not so beautiful once you introduced multi-thread into the app. Somehow, it means you have to manually call dispatcher method to synchronize the thread context, or else INotifyPropertyChanged contract causes cross thread violation, which is likely to drive UI component throw exception. But tons of calls to Dispatcher.Invoke or Dispatcher.BeginInvoke make you code ugly and hard to maintain. And it is boring to call dispatcher every time you try to write view model properties.

Is there any solution to this embarrassed situation?
The answer is Sync Notify pattern.

By analyzing the WPF data binding data flow, you can find the best point to behave the thread synchronization is at the boundary of your code and WPF implementation, which is the property changed event raiser. To sync the thread context here makes your code clean and effective.

Typically, you might implement the INotifyPropertyChanged in following way:

INofityPropertyChanged Implementation
1
2
3
4
5
6
7
8
9
10
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion

And you might implement the property of view model as following:

Notify Property Decalration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#region Notify Property ViewModelProperty
private string viewModelPropertyBackField;
public string ViewModelProperty
{
get { return viewModelPropertyBackField; }
set
{
if (viewModelPropertyBackField == value)
return;
viewModelPropertyBackField = value;
Notify("ViewModelProperty");
}
}
#endregion

This implementation works perfect in single thread context , but fails in multi-thread context. So we introduce a new event raiser implementation, which synchronize the thread context before raising the event:

SyncNotify
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#region Sync INotifyPropertyChanged Members
protected void SyncNotify(string propertyName, bool wait = false, Dispatcher dispatcher = null)
{
if (PropertyChanged == null)
return;
dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
if (dispatcher.Thread == Thread.CurrentThread)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
else
{
if (wait)
{
dispatcher.Invoke(PropertyChanged, this, new PropertyChangedEventArgs(propertyName));
}
else
{
dispatcher.BeginInvoke(PropertyChanged, this, new PropertyChangedEventArgs(propertyName));
}
}
}
#endregion

This method check the whether it is running on the same thread as dispatcher, it not it synchronize the thread. It works perfect in most common cases.
But this implementation requires you to add some new code to the view model, and requires the event works as a delegate. This restriction sometime hurt, such as when you try to derive your view model from ObservableCollection<T>.
ObservableCollection<T> declared PropertyChanged event, but implemented it explicitly, which means you won’t be able to raise the event by calling PropertyChanged directly. Instead, you need to call protected method OnPropertyChanged.

In such cases, you need the following implementation powered by extension method:

SyncNotifyExtension
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
public static class SyncNotifyExtension
{
public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<PropertyChangedEventArgs> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
{
Contract.Requires<ArgumentNullException>(host != null);
Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
Contract.Requires<ArgumentNullException>(eventRaiser != null);
dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
if (dispatcher.Thread == Thread.CurrentThread)
{
eventRaiser(new PropertyChangedEventArgs(propertyName));
}
else
{
if (wait)
{
dispatcher.Invoke(eventRaiser, new PropertyChangedEventArgs(propertyName));
}
else
{
dispatcher.BeginInvoke(eventRaiser, new PropertyChangedEventArgs(propertyName));
}
}
}
public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<string> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
{
Contract.Requires<ArgumentNullException>(host != null);
Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
Contract.Requires<ArgumentNullException>(eventRaiser != null);
dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
if (dispatcher.Thread == Thread.CurrentThread)
{
eventRaiser(propertyName);
}
else
{
if (wait)
{
dispatcher.Invoke(eventRaiser, propertyName);
}
else
{
dispatcher.BeginInvoke(eventRaiser, propertyName);
}
}
}
public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<object, PropertyChangedEventArgs> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
{
Contract.Requires<ArgumentNullException>(host != null);
Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
Contract.Requires<ArgumentNullException>(eventRaiser != null);
dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
if (dispatcher.Thread == Thread.CurrentThread)
{
eventRaiser(host, new PropertyChangedEventArgs(propertyName));
}
else
{
if (wait)
{
dispatcher.Invoke(eventRaiser, host, new PropertyChangedEventArgs(propertyName));
}
else
{
dispatcher.BeginInvoke(eventRaiser, host, new PropertyChangedEventArgs(propertyName));
}
}
}
public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<object, string> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
{
Contract.Requires<ArgumentNullException>(host != null);
Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
Contract.Requires<ArgumentNullException>(eventRaiser != null);
dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
if (dispatcher.Thread == Thread.CurrentThread)
{
eventRaiser(host, propertyName);
}
else
{
if (wait)
{
dispatcher.Invoke(eventRaiser, host, propertyName);
}
else
{
dispatcher.BeginInvoke(eventRaiser, host, propertyName);
}
}
}
}

These extension methods can be called inside the view model, and it ensures that the event is raised on the dispatcher thread.
Since these extension methods uses delegate to invoke the event raiser, so it is unnecessary to worry about the accessibility of the event raiser, event it is declared as protected or private. And 4 overloads can handle most common event raisers.

Self Registration Pattern for Singleton View Models in WPF

Where to store the Singleton View Model in WPF application, there are 2 common options:

Store in Resource Dictionary.

UI Designers prefers to store the WPF View Model into the Resource Dictionary because the objects in Resource Dictionary can be easily referenced in XAML.
But Developers must hate that way very much!
To fetch the object in Resource Dictionary from code behind must call the “FindResource” method of DependencyObject. And codes with tons of calls to “FindResource” method are ugly and very low efficient. The situation is worse since the accessibility to object in resource dictionary is also constrained by the Resource Scope, which means it is almost impossible to fetch the object from business logic.

Store in the Static Class.

I preferred to store the View Model in static class which is available globally. Developer can fetch the object by calling the static method, and designer also can fetch the object by using {x:Static} psudo-tag.
But it is still inconvenient somehow for designer, and it is somehow hard to provide design-time mockup data in this way.

For the previous 2 solutions, the pros and cons are obvious. But is it possible to combine these 2 approaches together to gains all the advantages but all the disadvantages.
The answer is Self-Registration Pattern.

The basic idea for Self-Registration Pattern is simple. It is obvious that we prefers to store the view models in Resource Dictionary, but we also want to access that object from Code Behind by calling static method.

So I designed the ViewModel class as following:

Self-Register View-Model
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ViewModel
{
#region Self Registration
public static ViewModel Default { get; private set; }
public ViewModel()
{
Default = this;
}
#endregion
}
View-Model Declaration
1
<vm:ViewModel x:Key="ViewModel"/>

You can see, the ViewModel has a globally visible static property named Default, and the class set the Default property to itself in its constructor.
Which means once the View Model is initialized in Resource Dictionary, it also set the instance reference to Default,
So designer can reference the view model easily with StaticResource Tag

Reference View-Model from XAML
1
<Control Property="{StaticResource ViewModel}"/>

And Developer also can access the view model by calling Static Property

Reference View-Model from C#
1
ViewModel.Default

一个关于 Inheritance 和 Delegate 的故事

Cocoa Programming for Mac OS X 里看到这么一段话~挺有意思的~~~

Once upon a time, there was a company called Taligent, which was created by IBM and Apple to develop a set of tools and libraries like Cocoa. About the time Taligent reached the peak of its mindshare, I met one of its engineers at a trade show. I asked him to create a simple application for me: A window would appear with a button, and when the button was clicked, the words “Hello, World!” would appear in a text field. The engineer created a project and started subclassing madly: subclassing the window and the button and the event handler. Then he started generating code: dozens of lines to get the button and the text field onto the window. After 45 minutes, I had to leave. The app still did not work. That day, I knew that the company was doomed. A couple of years later, Taligent quietly closed its doors forever.

可以想象,这个故事一定发生在 OO 刚刚起步的年代~那个年代几乎把 inheritance 当作所有问题的 Killer Pill~随着技术的演化,在无数的 Developer 对着一堆堆让人眼花缭乱的继承树(特别是像 C++ 这样具有多继承能力的预言的继承树)浪费的无数的 Working Hour,杀死了无数自己的脑细胞后,人们终于开始意识到或许应该有一种比 Inheritance 更好的方式去处理某些问题~ 于是有了 Composition 有了 Delegate~~~甚至把继承深度作为了代码可维护性的一个重要指标!

看新的预言中~C# 和 Java 拿掉了多继承~ 在产生变种对象的时候,Java 是采用 Handler 的新类,其实就是 Delegate 的方式~ C# 对于比较重量级的对象(比如 Form,Window,Page)依然采用 Inheritance ,但是对于轻量级的对象(Button,TextBox,MIenutem)时则采用更为灵活的方法级别的 Delegate~
C# 的方式和 Cocoa 比较类似。
Cocoa 中,由于界面采用溜达 MVC 模式~需要大量定制的对象,比如 Window,View,会采用继承重载的方式。需要改变行为时一般会 Controller,而要改变 Visual 时,通常会重载 Visual Element 对象本身~ 而轻量级的定制,或者仅仅是响应某些交互的话,则会采用 Delegate 的方式~比如 Application 的 Delegate~~

Vision 只有一个,但是 Implementation 会有很多~而对比不同语言对同一个问题的处理方式是一件非常有意思的事情~在这种对比中~才能发现不同的设计模式和实现模式的优劣~~~和在现实中的实用效果~~~~

Plants vs Zombie Cheat Engine +3 Trainer

  • Collect Sunshine Cheat: Give 0x8FF sunshine when player pick any sun shine, overflow protection is enabled
  • Consume Sunshine Cheat: Set Sunhine to 0xFFF when any sunshine is consumed
  • Cool Down Cheat: No Cool Down time for plants
Cheat-Engine cheat sheet definition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//Cheat Code
//==============================================
//Collect Sunshine Cheat
//==============================================
[ENABLE]
alloc(collectMoneyCheat,512)
label(collectMoneyReturn)
label(collectMoneyOriginal)
label(collectMoneyExit)
0041E6E0:
jmp collectMoneyCheat
nop
collectMoneyReturn:
collectMoneyCheat:
cmp [eax+00005578],FFFF // Overflow protection
jge collectMoneyExit
mov ecx, 8FF
collectMoneyOriginal:
add [eax+00005578],ecx
collectMoneyExit:
jmp collectMoneyReturn
[DISABLE]
dealloc(collectMoneyCheat)
0041E6E0:
add [eax+00005578],ecx
//==============================================
//==============================================
//Consume Sunshine Cheat
//==============================================
[ENABLE]
alloc(consumeMoneyCheat,512)
label(consumeMoneyReturn)
label(consumeMoneyOriginal)
label(consumeMoneyExit)
0041E844:
jmp consumeMoneyCheat
nop
nop
nop
consumeMoneyReturn:
consumeMoneyCheat:
mov esi, FFFF //Show me the money ;)
mov [edi+00005578],esi
consumeMoneyOriginal:
/*
sub esi,ebx
mov [edi+00005578],esi
*/
consumeMoneyExit:
jmp consumeMoneyReturn
[DISABLE]
dealloc(consumeMoneyCheat)
0041E844:
sub esi,ebx
mov [edi+00005578],esi
//==============================================
//==============================================
//Cool Down Cheat
//==============================================
[ENABLE]
alloc(coolDown,512)
label(coolDownReturn)
label(coolDownOriginal)
label(coolDownExit)
00491E4C:
jmp coolDown
nop
coolDownReturn:
coolDown:
//place your code here
mov eax, [edi+28]
mov [edi+24], eax
coolDownOriginal:
inc [edi+24]
mov eax,[edi+24]
coolDownExit:
jmp coolDownReturn
[DISABLE]
dealloc(coolDown)
00491E4C:
inc [edi+24]
mov eax,[edi+24]
//==============================================

Tested on Win XP SP3 EN+Pvz GOTY EN

Windows 7 下脚本启用或者关闭网卡的方法

方法一:NetSH 大法~
采用下列 Netsh 脚本

Netshell Script
1
2
interface
set interface name="Local Area Connection" admin=ENABLED/DISABLED

方法二:Powershell+WMI 大法

Powershell
1
2
$adapter = get-wmiobject Win32_NetworkAdapter -filter "NetConnectionID='Local Area Connection'"
$adapter.Disable()

同理可以 VBS+WMI 大法~
这个就不说了~没啥意义了~

其中有一个非常重要的问题就是权限控制问题!
Windows 7 的 UAC 很严格,不能像 WinXP 里那样随意修改系统设置而不通知用户。
如果不赋予脚本执行环境以 Administrative 权限的话,脚本会执行失败,WMI 返回码为 05,Netsh 报错:“An interface with this name is not registered with the router.”
因此在启动 Netsh 或者 Powershell 时需要指定 Administrative 权限,可通过右键菜单 Run as Administrator 实现。
然后会出现 UAC,Allow 即可~
由于 UAC 权限具有继承性,即一个具有 Administrative 权限的 Process 启动的 Process 默认是具有 Administrative 权限的(除非显式的禁止继承)~
因此可以通过启动一个有 Administrative 的 Cmd 或者 Powershell 的 Shell 来让脚本具有 Administrative 权限~

该方法仅在 Win7 下测试通过~WinXP 下不通过~
似乎原因是由于 WinXP 的 WMI Class 不支持 Enable 和 Disable 方法造成的~具体解决方案未知。