[转贴]小技巧:在 Windows 资源管理器链入 SkyDrive

293 views 五月 24, 10 by Timothy

本文转自cnbeta,原文地址:http://www.cnbeta.com/articles/111849.htm
SkyDrive的25GB的空间,想起来还是比较不错的,闲置起来不用,确实比较浪费。把SkyDrive嵌入到”我的电脑”是个不错的主意,所以我之前装了SDExplorer 。无意中发现cnbeta有了这篇文章,挺实用的小技巧,所以忍不住要转贴一下,跟大家分享……

=========================原文开始==========================
自从Dropbox阵亡以后,寻找下一个好用的和系统高度集成的网络硬盘就成为了大家追逐的热点。
有传言说,微软计划在Windows 8中加入对SkyDrive的原生支持,也就是让这款25G的网络硬盘成为“计算机”中的一个盘符。但是这么好的主意怎么在Windows7 发布的时候就没有想出来呢?既然没有想出来,我们现在就只能自力更生,让SkyDrive进驻我们的资源管理器了。好在方法并不是没有,有两款第三方工具,以及Office 2010都可以帮助我们实现。不装Office,也不想装第三方工具的朋友们可能要多花点心思了。以下是详细讲解,来自 Paul Thurrott:

1、第三方工具

下载:Gladinet Cloud Desktop
下载:SDExplorer
这两款软件做的工作完全一样,都是把 SkyDrive 虚拟成网络驱动器。第一款除了SkyDrive之外,还链接包括 Amazon S3, Google PicasaWeb, Windows Azure 在内的云存储服务器。可惜完全版是要收费的,免费版在同时传输文件的数量上有限制,且不支持Google Docs。完全版售价40刀。
1
尽管图标不一样,但两款软件运行后的效果差不多。
2、原生支持之Office 2010篇
细心的朋友们会发现,在Office 2010组件中多出了保存到网络驱动器的功能。这一功能就指出了 SkyDrive 存储文档的物理位置,因此我们可以利用它获取属于我们的 SkyDrive 存档的唯一地址,接下来做的就是映射为网络驱动器了。
首先链接你的 Windows Live ID。Windows XP 中的“用户账户”直接提供链接到Live ID(系统称之为.NET Passport)的入口。只需按照程序操作即可。
对于 Windows 7 用户,需要下载专门的链接支援插件,安装后再到“用户账户”面板去登录。
2
点击“添加一个在线 ID 提供商”,并到微软的网站下载 Windows Live ID 插件(目前只有这一款)。
3
登陆后的样子。
现在,打开一个 Office 2010 组件(比如 Word),点击“文件”面板-“另存为”-“保存到网络驱动器”:
4
在弹出窗口中用Live ID登录后,找到目标位置点击“另存为”。
会出现一个标准的另存为窗口,在窗口的地址栏中复制形如下列的网址:
https://12345.docs.live.net/8940bd da44ff5ac8/Documents
接着打开“计算机”/“我的电脑”,点击菜单栏“工具”-“映射网络驱动器”(或者工具栏的“映射网络驱动器”),设置一个盘符,在网络位置处粘贴刚才复制的那一串网址,确定即可。
5
这样就大功告成了。
顺便一提,删除它的方式是右键点击盘符,选择“断开”。
3、没有装Office又不想用第三方软件的傲娇人士专用
首先按照上文所述链接Windows Live ID。
紧接着下载SkyDrive Simple Viewer for WebDAV 。解压后直接运行SkyDriveSimpleViewer.exe,同样是输入Live ID登录。
6
7
登陆后右侧就出现了如上文所述那样的网址。将网址按照上文所述方法映射成网络驱动器即可。 在映射过程中,有可能要求你再次输入Live ID,可以选择“记住密码”。
8

Dynamic Plugins Manager (五) Plugins Manager 源码下载

113 views 四月 01, 08 by Timothy

今天和同事一起把Plugins Manager放在了google code上面。大家可以从下面的地址获取所有的源码了。

http://code.google.com/p/dynamic-plugins-manager/

Dynamic Plugins Manager (四) 插件及Demo源码下载

186 views 三月 29, 08 by Timothy

这里提供了插件的Demo程序,和编译好的Plugin Manager下载。
Plugin Manager的代码待整理后放上来。[cool]

开发运行环境:
Windows Vista Ultimate
.NET Framework 3.5
Microsoft Visual Studio 2008

点击下载此文件

Dynamic Plugins Manager (三) Demo

212 views 三月 29, 08 by Timothy

下面来演示一下Plugins Manager,先看看我们事先做好的Interface和两个具体实现的插件.

Interface,接口定义:
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Component
{
public interface IComponent
{
string Invoke();
}
}
[/code]

整个接口,只声明了一个Invoke方法,这也是具体的插件必须实现的一个方法。

第一个插件类 class1.cs
[code]
namespace Component
{

public class Class1 : MarshalByRefObject,IComponent
{
string message = string.Empty;
int number;
float number2;

public Class1(string input, int num)
{
message = input;
number = num;
number2 = 0;
}

public Class1(int num1, float num2)
{
message = "none";
number = num1;
number2 = num2;
}

public string Invoke()
{
return "This is TestLibrary. member---message:" + message + "number:" + number.ToString() + "number2:" +number2.ToString();
}
}
}

[/code]

第二个插件类 class2.cs
[code]
namespace Component
{
public class Class2 : MarshalByRefObject,IComponent
{
public Class2()
{
}

public string Invoke()
{
return "This is TestLibrary2 without construct param";
}
}
}

[/code]

这里我们看到区别,第一个插件,需要构造函数,第二个插件不需要构造函数,所以在配置文件中,第二个插件可以关闭掉ConstructParam这个节点。

下面我们将Class1.cs编译好,放到插件目录中,改名为TestLibrary.dll,将Class2.cs直接改名为TestLibrary2.cs,放到插件目录中。
演示的目的:插件1需要在加载时,构造初始化函数,而插件2不需要。
插件1,是已经编译好的dll,不需要实时编译,但是插件2需要。

下面是测试的截图

1.插件目录,一个放入编译好的dll,一个放入.cs源码

2.启动测试程序,看到2个插件都已经被加载

3.此时,再查看插件的目录,我们会看到Plugin Manager为我们编译,并生成的插件2的dll

4.查看插件的日志记录

5.插件的调用
选中TestLibrary,点击Invoke按钮:

选中TestLibrary2,点击Invoke按钮:

6.插件的动态卸载和发布
a.动态卸载,可以直接使用Plugins Manager的UnloadPluginByName直接通过程序调用卸载。也可以手动打开插件的配置文件,将EnablePlugin设置为False
b.动态发布,直接在插件目录中,建立一个新的子目录,然后将插件的dll和xml配置文件直接拷入即可
关于第6点,这些功能的演示,截图比较麻烦,大家可以直接使用测试程序测试即可。

Dynamic Plugins Manager (二) 配置及实现分析

115 views 三月 29, 08 by Timothy

整个Plugins Manager是一个基于dll的程序集,开发平台,基于VS2008和.NET 3.5 Framework。为何要用.NET 3.5呢?没别的原因,只要是为了尝试一下Linq to XML [cool]

使用改组件,需要在应用程序中,添加引用。另外,还需要在应用程序中,建立相关的配置项:
[code]







[/code]

PluginsPath是插件的主目录,里面通过子目录的方式,存放不同的插件。Plugins Manager在启动的时候,会遍历插件主目录,并搜寻可加载的插件。
LogPath是插件的日志目录,里面的日志文件,会详细记载插件管理器当前的运行情况。

另外,在Plugins Manager中,区别不同的插件,是根据不同的插件名称来决定的,这取决于插件dll的命名。
对于不同的插件,Plugins Manager也提供不同的特性配置文件。配置文件是.xml文件,命名需要和插件dll相一致。
下面是一个配置文件的示例:
[code]

Component.Class1
True



D:\MyCode\C# Projects\DynamicPlugInsApp\ITestInterface\bin\Debug\ITestInterface.dll
[/code]

TypeName:插件的类名,和具体的插件命名空间和类名有关,Plugins Manager根据配置文件提供此相关信息,通过.NET的反射技术,生成具体的插件Instance
EnablePlugin:插件开关,True表示当前插件可用,False表示阻止Plugins Manager加载此插件。该开关可以在Plugins Manager运行前设定,也可以在Plugins Manager运行时动态更改。Plugins Manager会检测配置文件变化,并留意EnablePlugin开关,以决定是否动态加载或者卸载该插件。
ConstructParams:此节点,及其子节点,用以读取插件是否需要在运行时初始化构造函数。子节点用以描述构造函数中的参数,以及类型,和初始化的值。构造初始化函数,也是在.NET的反射中实现。这里要注意,节点顺序和构造函数参数顺序有关。如果插件不需要构造函数,可以关闭此节点。
ReferenceList:此节点用以需要动态编译的插件,如果插件代码中还引用了其他的程序集,需要在此进行描述。

此外,插件还提供了事件通知功能,供应用程序进行响应和处理,实现的事件类型有以下几种:

[code]
public enum PluginEventType
{
PluginLoadOver, //所有插件加载完毕
PluginAdded, //插件新增完毕
PluginRemoved, //插件卸载完毕
PluginStopped, //插件管理器已停止
PluginStarted //插件管理器已启动
}
[/code]

插件的事件参数定义如下,只包含简单的事件类型和文本描述:

[code]
public class PluginEventArgs : EventArgs
{
#region Private Members
public PluginEventType EventType { get; set; }
public string EventMessage { get; set; }
#endregion

public PluginEventArgs(PluginEventType eventtype, string message)
{
EventType = eventtype;
EventMessage = message;
}

}
[/code]

以上是使用该插件,需要配置的地方,下一篇日志,将演示该插件的Demo.

Dynamic Plugins Manager (一) 介绍

121 views 三月 29, 08 by Timothy

Dynamic Plugins Manager是一个基于.NET的动态插件管理组件,也是我在业余时间做的一个小东东,代码在07年底就开始动工,因为一直没充裕时间完成,趁这个周末休息,加班加点的Coding,出来了一个原型,估计里面还有很多的显而易见的以及隐而未现的bug。
设计这个组件的初衷,是为了能方便的应用于今后的项目中。先进的企业级项目中,变化最为突出的,还是业务,业务的变化,直接导致编码中业务逻辑代码的变化。如果将这些业务逻辑混杂在一起,业务的变化,最终会导致代码的混乱,甚至难以维护。这对于一个长期迭代的项目来说,是相当痛苦的事。就像直接拿一个成千上万行的代码给开发人员,估计开发人员不是晕厥,就是吐血。而一个难以维护的业务逻辑代码,对于每一次迭代,都是一次冒险。很可能在某次的迭代中,会对以前的业务逻辑,产生影响或者风险。
对于复杂的业务逻辑,需要进行重构,并且将不断变化的业务逻辑,抽离出来。比较折中的方法,就是将这些变化的逻辑,做成独立的插件形式。这样一来,独立的业务,在物理上进行了分离。开发人员也不用担心修改某处业务逻辑,会影响其他的业务模块。而动态的插件管理形式,对后期维护也带来益处,独立的业务逻辑插件之间,不会相互影响。开发人员还可以在程序运行而又不影响业务的情况下,动态的发布、替换原有的业务逻辑模块。
Dynamic Plugins Manager(以下简称Plugins Manager),也就是按照这样的思路和需求来设计的,其实现的功能,具体有一下几个特点:
1.所有的插件,都以DLL程序集的方式发布,Plugins Manager在启动的时候,搜索加载所有可加载的插件并进行加载
2.Plugins Manager,支持插件的动态卸载功能。借助于AppDomain的特性,所有的组件,在动态加载后,可以动态从内存中卸载。插件的实现,需要继承自MarshalByRefObject。
3.与接口无依赖性,Plugins Manager负责插件的管理、动态加载、动态卸载、调用。但是和具体的插件接口无关,这样一来,开发人员可以定义自己的插件接口,并开发不同的插件实现接口。
4.插件可以动态发布和卸载,Plugins Manager会监视当前目录中,插件的变化,对于以xcopy方式,拷贝入插件目录的插件,可以进行动态加载。对于插件的卸载,可以Plugins Manager提供的接口进行动态卸载,也可以实时更改插件配置文件中的具体开关进行卸载。
5.动态编译功能:Plugins Manager允许直接发布插件代码。通过读取插件配置文件中的引用信息,可以直接从代码生成dll插件,并加载。
6.允许插件实现不同的构造函数重载,并将构造函数参数以及值信息,定义在插件配置文件中。Plugins Manager在加载插件的时候,采用配置文件中的值,调用相应的构造函数,并加载插件。
7.事件通知:Plugins Manager在不同的插件操作完成后,会触发相应的事件机制,通知客户端程序进行相应的处理

插件的结构一览:

PluginsManager:插件管理类,实现插件功能的主要代码逻辑,以及对插件容器的维护
AssemblyLoader:插件加载类,实现从AppDomain加载插件的逻辑
PluginEntity:插件实体类,包含插件的信息(插件实例、插件名称……)
AssemblyFactory:插件生成类,实现从插件代码生成dll的功能

下一篇日志中,将会介绍这个插件的具体配置,及简单分析其实现。

Dynamic Plugins Manager

186 views 三月 29, 08 by Timothy

Dynamic Plugins Manager (一) 介绍

http://www.xiaozhou.net/article.asp?id=187

Dynamic Plugins Manager (二) 配置及实现分析

http://www.xiaozhou.net/article.asp?id=188

Dynamic Plugins Manager (三) Demo

http://www.xiaozhou.net/article.asp?id=189

Dynamic Plugins Manager (四) 插件及Demo源码下载

http://www.xiaozhou.net/article.asp?id=190

Dynamic Plugins Manager (五) Plugins Manager 源码下载

http://www.xiaozhou.net/article.asp?id=191

Windows 任务管理器如何确定应用程序”没有响应”

307 views 十一月 17, 04 by Timothy

最近参加的一个项目要求实现远程任务管理功能,也就是”Remote Task Manager”(RTM)。我把它与Windows NT的任务管理器进行了比较,发现标准的任务管理器显示应用程序的状态(正在运行或者没有响应)。标准的任务管理器发送(通过SendMessageTimeout函数)一个消息到主应用窗口,如果函数调用失败或者超时–则应用程序的状态就是”没有响应”,否则状态为”正在运行”。
但我发现还有一个更好的解决方法。本文将通过实例程序进行示范。这个方法的思路是通过调用User32.dll中一个未公开的函数来实现的。这个函数存在于Windows 9x和Windows NT/2000系统中,但在两个系统中的名字是不同的。Windows 9x系统中的名字为:IsHungThread,在Windows NT/2000系统中的名字为IsHungAppWindow。下面是它们的原型:
BOOL IsHungAppWindow (
HWND hWnd, // 主应用窗口句柄
);

BOOL IsHungThread (
DWORD dwThreadId, // 主应用窗口的线程ID
);
不幸的是,微软在User32.lib中没有提供这两个函数的输出。也就是说,这两个函数是未公开函数,如果要在程序中使用它们,则必须通过GetProcAddress和GetModuleHandle函数动态加载:

typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW) (HWND);
typedef BOOL (WINAPI *PROCISHUNGTHREAD) (DWORD);

PROCISHUNGAPPWINDOW IsHungAppWindow;
PROCISHUNGTHREAD IsHungThread;

HMODULE hUser32 = GetModuleHandle(“user32″);

IsHungAppWindow = (PROCISHUNGAPPWINDOW)
GetProcAddress(hUser32,”IsHungAppWindow”);

IsHungThread = (PROCISHUNGTHREAD)
GetProcAddress(hUser32,”IsHungThread”);

//////////////////

// ishung.cpp (Windows 95/98/NT/2000)
//
// This example will show you how you can obtain the current status
// of the application.
//
//
// (c)1999 Ashot Oganesyan K, SmartLine, Inc
// mailto:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com

#include
#include

// User32!IsHungAppWindow (NT specific!)
//
// The function retrieves the status (running or not responding) of the
// specified application
//
// BOOL IsHungAppWindow(
// HWND hWnd, // handle to main app’s window
// );
typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW)(HWND);

// User32!IsHungThread (95/98 specific!)
//
// The function retrieves the status (running or not responding) of the
// specified thread
//
// BOOL IsHungThread(
// DWORD dwThreadId, // The identifier of the main app’s window thread
// );
typedef BOOL (WINAPI *PROCISHUNGTHREAD)(DWORD);

PROCISHUNGAPPWINDOW IsHungAppWindow;
PROCISHUNGTHREAD IsHungThread;

void main(int argc, char* argv[])
{
/* if (argc<2)
{
printf(“Usage:\n\nishung.exe hWnd\n”);
return;
}
*/
// HWND hWnd;
// sscanf(argv[1],”%lx”,&hWnd);

HWND hWnd = ::FindWindow(NULL, “CLENT”);
if (hWnd == NULL)
{
printf(“Incorrect window handle(handle is NULL)\n”);
return;

}

if (!IsWindow(hWnd))
{
printf(“Incorrect window handle\n”);
return;
}

HMODULE hUser32 = GetModuleHandle(“user32″);
if (!hUser32)
return;

IsHungAppWindow = (PROCISHUNGAPPWINDOW)
GetProcAddress( hUser32,
“IsHungAppWindow” );

IsHungThread = (PROCISHUNGTHREAD) GetProcAddress( hUser32,
“IsHungThread” );

if (!IsHungAppWindow && !IsHungThread)
return;

OSVERSIONINFO osver;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
return;

BOOL IsHung;

if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
IsHung = IsHungAppWindow(hWnd);
else
IsHung = IsHungThread(GetWindowThreadProcessId(hWnd,NULL));

if (IsHung)
printf(“Not Responding\n”);
else
printf(“Running\n”);
}