刀切链球 CiviBalls

civiballs

用刀切断锁链,然后让球进入罐子里。注意,每个球只能进入与之颜色相同的罐子。灰色球不能进。

更多 >

矢量塔防 Vector TD

snapshot

我蛮喜欢塔防类游戏的,但就是玩不好-_-

这个矢量塔防,顾名思义就是用矢量画出来的。没有对空对地之分,但是有颜色相克,炮塔类型也很多,具体的看介绍吧。

更多 >

Hyper-V的自动化 (1) 获取虚拟机信息

连接到服务器上之后,第一步要做的当然是拿到虚拟机的列表了:

private ManagementObjectCollection RefreshVirtualMachines()
{
    ManagementScope scope = new ManagementScope(@"\\" + ServerName + @"\root\virtualization");
    scope.Connect();
    ObjectQuery query = new ObjectQuery("SELECT * FROM MsVM_ComputerSystem WHERE Caption LIKE 'Virtual%' ");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
    return searcher.Get();
}

很简单吧,一个查询就搞定了。得到的ManagementObjectCollection中的每个ManagementObject,对应一个虚拟机的数据。接下来就是生成虚拟机的对象:

public class VirtualMachine
{
    internal VirtualMachine(ManagementObject obj)
    {
        BaseObject = obj;
    }

    private ManagementObject BaseObject { get; set; }

    public string Name
    {
        get
        {
            return BaseObject.GetPropertyValue("ElementName").ToString();
        }
    }

    public VirtualMachineState State
    {
        get
        {
            return VirtualMachineState.GetState(BaseObject.GetPropertyValue("EnabledState").ToString());
        }
    }

    public Guid Id
    {
        get
        {
            return new Guid(BaseObject.GetPropertyValue("Name").ToString());
        }
    }

    public TimeSpan UpTime
    {
        get
        {
            return TimeSpan.FromMilliseconds((double)(ulong)BaseObject.GetPropertyValue("OnTimeInMilliseconds"));
        }
    }
}

每个ManagementObject中包含一个虚拟机的数据,详细的列表在这里。不过我只找到4个有用的:Name, ElementName, EnabledState和OnTimeInMilliseconds:

  • Name是一个GUID,它是虚拟机的标识符。
  • ElementName相当于Display Name,也就是用户所看到的名字。
  • EnabledState是虚拟机当前的状态,有很多,详见后面的代码。
  • OnTimeInMilliseconds表示虚拟机开启了多少时间。OnTimeInMilliseconds indicates how long the virtual machine is on.

EnabledState是一个字符串形式的数字,要把它转换成用户看得懂的数据,还需要一个类:

public class VirtualMachineState
{
    private VirtualMachineState(ushort id, string name, string displayName)
    {
        Id = id;
        Name = name;
        DisplayName = displayName;
    }

    public string Name { get; private set; }
    public ushort Id { get; private set; }
    public string DisplayName { get; private set; }

    public override string ToString()
    {
        return DisplayName + " (" + Id + ")";
    }

    public static VirtualMachineState GetState(string name)
    {
        ushort id = 0;
        bool useId = UInt16.TryParse(name, out id);
        foreach (VirtualMachineState state in states)
        {
            if ((useId && state.Id == id) || (state.Name == name))
            {
                return state;
            }
        }
        return Unknown;
    }

    private static List states = new List();
    static VirtualMachineState()
    {
        states.Add(Unknown);
        states.Add(Enabled);
        states.Add(Disabled);
        states.Add(Paused);
        states.Add(Suspended);
        states.Add(Starting);
        states.Add(Sanpshotting);
        states.Add(Saving);
        states.Add(Stopping);
        states.Add(Pausing);
        states.Add(Resuming);
    }

    public static VirtualMachineState Unknown = new VirtualMachineState(0, "Unknown", "Unknown");
    public static VirtualMachineState Enabled = new VirtualMachineState(2, "Enabled", "Running");
    public static VirtualMachineState Disabled = new VirtualMachineState(3, "Diabled", "Off");
    public static VirtualMachineState Paused = new VirtualMachineState(32768, "Paused", "Paused");
    public static VirtualMachineState Suspended = new VirtualMachineState(32769, "Suspended", "Saved");
    public static VirtualMachineState Starting = new VirtualMachineState(32770, "Starting", "Starting");
    public static VirtualMachineState Sanpshotting = new VirtualMachineState(32771, "Snapshotting", "Snapshooting");
    public static VirtualMachineState Saving = new VirtualMachineState(32773, "Saving", "Saving");
    public static VirtualMachineState Stopping = new VirtualMachineState(32774, "Stopping", "Shuting down");
    public static VirtualMachineState Pausing = new VirtualMachineState(32776, "Pausing", "Pausing");
    public static VirtualMachineState Resuming = new VirtualMachineState(32777, "Resuming", "Resuming");
}

用VirtualMachineState.GetState把ManagementObject里的EnableState转化成VirtualMachineState。一共有11种可能的状态,最常见的Enabled和Disabled,即开着和关着。

这样就可以获取服务器上的所有虚拟机的信息,然后显示给用户了。

Hyper-V的自动化 (0) 远程连接

Hyper-VVirtual Server的升级版,主要用于运行和管理虚拟机。它的优点是可以同时管理和维护多台虚拟机,在不需要某台虚拟机的时候,可以把它关掉,用到再开开来,相比于使用物理机器,Hyper-V可以更好的优化资源的利用。利用强大的快照(Snapshot)功能,可以省去重装机器的烦恼。比如在机器刚装好的时候,做一个快照,用了一会觉得系统有问题了,再恢复到之前的状态,就相当于重装了一遍机器了。

Windows Server 2008 (及R2)中提供了一个直观的Hyper-V的管理界面,不仅可以管理本机的虚拟机,也可以连到别的服务器上去。但这毕竟是用户界面,需要手工操作的。在人们越来越懒的时代,我们更希望有自动化的管理,比如每隔一小时刷新一下虚拟机的状态,看看哪台机器不正常,然后发一封邮件出来……生活是多么惬意呀……

接下来开始第一步,连接到远程的Hyper-V服务器。Hyper-V的API是基于WMI的。至于WMI是什么,就不多说了,直接上代码:

public static VirtualSystemService Connect(string serverName)
{
    ManagementObject service = null;
    try
    {
        ManagementScope scope = new ManagementScope(@"\\" + serverName + @"\root\virtualization");
        scope.Connect();
        ObjectQuery query = new ObjectQuery("SELECT * FROM MsVM_VirtualSystemManagementService");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
        ManagementObjectCollection coll = searcher.Get();
        foreach (ManagementObject obj in coll)
        {
            service = obj;
        }
    }
    catch (ManagementException)
    {
        return null;
    }
    if (service == null)
    {
        return null;
    }
    return new VirtualSystemService(service, serverName);
}

第一行中的VirtualSystemService是一个自定义类型,用于对Hyper-V的控制。关键代码是第7行,当目标机器上没有Hyper-V服务的时候,scope.Connect();会抛出一个异常……不多说了,这段代码还是很简单易懂的。

强大的批处理 (3) 判断目录在%Path%中

貌似没有很优美的做法,只能把%Path%按分号分割,然后一段一段地比较。

:InPath [In]Path [Out]0/1
SETLOCAL
SET LocalPathCopy=%PATH%
SET Result=0
:WHILE
IF "%LocalPathCopy%" == "" GOTO WEND
FOR /F "delims=;" %%I IN ("%LocalPathCopy%") DO (
    IF /I "%%~I" == "%~1" (
        SET Result=1
        GOTO WEND
    )
)
FOR /F "delims=; tokens=1,*" %%I IN ("%LocalPathCopy%") DO (
    SET LocalPathCopy=%%~J
)
GOTO WHILE

:WEND

:InPathRet
ENDLOCAL & SET %2=%Result% & GOTO :EOF

使用方法:

SET x=C:\Windows
Call :InPath %x% Result
IF %Result% == 0 SET Path=%Path%;%x%

在命令行中以管理员权限启用应用程序

自从Vista带来了UAC之后,应用程序就变成了两种,有管理员权限的,和没有管理员权限的。一些老的应用程序会莫名其妙地出错,这时候就要考虑右击应用程序,然后“以管理员身份运行”。这还不是什么大问题,exe文件的右键菜单里都会有这个,但是对于一些脚本文件(cmd, js一类)来说,就没那么方便了。通常需要重新开一个带管理员权限的命令行窗口,然后打很多cd回到刚的文件夹,然后再运行脚本,相当麻烦。

搜了一下,找到一个解决办法。把下面的代码保存为Elevate.js:

var command = WScript.Arguments.Item(0);
var argument = "";
for (var i = 0; i < WScript.Arguments.Count(); ++i){
    argument += WScript.Arguments.Item(i) + " ";
}

try{
    var shellapp = new ActiveXObject("Shell.Application");
    shellapp.ShellExecute(command, argument, null, "runas", 1);
}
catch(e){
    WScript.Echo("Something wrong: " + e.description);
}

以后要以管理员身份运行程序的时候,只要输入“Elevate <exefile> <arguments>”就可以了,比如“Elevate cmd /k”。

当然,这个逃不过UAC的检查,还是会有一个对话框弹出来要点“确定”的。

Yes Man (2008)

宅男宅女们都看一下这部片子吧。

尽管它的中文译名(好好先生)不那么切题,但这的确是一部值得看的片子。全新的生活方式,(只不过感觉会忙不过来-_-),特别是觉得最近状况不好的同学们,更要体验一下。

我很欣赏那个周末旅游的方式,有机会要尝试一下,有兴趣的联系我吧:P

强大的批处理 (2) Fibonacci函数

小无聊一下,不过真的很强大……

@ECHO OFF

SETLOCAL

SET X=10

CALL :Fib %X% Y
ECHO Fib^(%X%^)=%Y%
GOTO :EOF

:Fib [In]X [Out]Result
SETLOCAL
SET A=%1
SET D=1
SET E=0

IF %A% LEQ 1 (
    GOTO FibRet
)

SET /A B=%A%-1
SET /A C=%A%-2
CALL :Fib %B% D
CALL :Fib %C% E

:FibRet
ENDLOCAL & SET /A %2=%D%+%E% & GOTO :EOF

输出是“Fib(10)=89”

强大的批处理 (1) 字符串截取

获取当前的小时数:

@ECHO OFF

SET Hour=%TIME:~0,2%

IF %Hour% GTR 12 (
    ECHO Afternoon
) ELSE (
    ECHO Morning
)

打印Windows的版本:

@ECHO OFF

FOR /F "tokens=1,2,3,4" %%I IN ('VER') DO (
    SET Ver_Temp=%%L
)

SET Ver_Major=%Ver_Temp:~0,1%
SET Ver_Minor=%Ver_Temp:~2,1%
SET Ver_Build=%Ver_Temp:~-5,4%

ECHO Windows Version:
ECHO   Major %Ver_Major%
ECHO   Major %Ver_Minor%
ECHO   Build %Ver_Build%

Causality

还记得《死神来了》么?无论怎么样都逃不过命运的安排……

46c692a3283124a8

这个有点BT的游戏要求你把所有的火柴小人都杀掉-_-

尽管只有3关,但过关好难啊……全鼠标操作,每样物品都暗藏玄机……

更多 >