『求助』在Webpage上调用Windows Messenger API
最近在工作中遇到一个在WebPage上调用Windows Messenger API的需求,于是到MSDN上大搜一番,还是有所收获。相关链接如下:http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx?pf=true
其中包含了一段MSN Instant Messenger代码。首先要提出的一个大家容易混淆的概念:Windows Messenger 与 MSN Messenger 到底有什么区别和联系?
·MSN Messenger不是系统自带的,而Windows Messenger在非Windows 2003的Microsoft系统上都已经作为默认组件安装,这里我们要使用到的就是Windows Messenger API
·MSN Messenger只能用.Net Passport这个微软统一身份验证来登陆,也就意味着它只能在一台联入了互联网的电脑上登陆使用。而Windows Messenger则有三种登陆方式:a. Exchange身份验证 b. .Net Passport身份验证 c. SIP身份验证。其中c. SIP身份验证不太常用。而现在很多企业都已经建立了内部Exchange服务器,这样就经常会采用Windows Messenger的Exchange身份验证来进行登录后内部员工IM联系。而如果使用b. .Net Passport身份验证则功能上与MSN Messenger完全一样。
·Windows Messenger可以同时使用三种身份验证登陆,换句话说就是我可以同时登陆企业内网的Windows Messenger IM以及互联网上的MSN Messenger。其中的联系人列表是整合的。就有点像MyIM能整合MSN以及QQ、Yahoo IM等等IM软件一样。而MSN Messenger不行
·MSN Messenger的聊天记录可以保存,且通讯功能更加强大,如最新的7.5版本“传情动漫”以及“手写”功能已经完全超越了QQ等同类IM软件。而Windows Messenger聊天记录在关闭聊天窗口后消失不自动保存,只集成了一些最基本的通信方式。可以算作是简化版的MSN Messenger
有了以上的信息,我们已经可以开始试验了。将MSDN上的那段MSN Instant Messenger代码复制到本地,保存成.html文件,用IE打开。嗯。一切正常。请看下图(由于本人在台企上班,公司要求使用繁体操作系统,请大家见谅):
图一
然后,我们把这个文件复制到wwwroot发布目录下。再通过 http://172.18.77.60/ (我电脑的IP地址)前缀来访问。如下图所示:
图二
大家可以看到。同样一段代码。直接访问与发布后访问执行结果不同。我本想将此功能制作成一个WebPart以便在SharePoint上的任意地点引用。但是现在的问题是,只有我直接双击该html文件才能正常显示“联系人名单”,而我无论使用http://127.0.0.1/ 或者 http://localhost/ 或者 http://我的电脑IP地址/ 三种方式访问,联系人列表都会发生错误。但是通过点击“undefined”链接是可以实现对话功能的,通过查看源代码得知,其是通过枚举id来实现的,所以这里仅仅是一个显示上的问题。
下面让我们来看看完整的代码,完全使用JavaScript调用Windows Messenger API来实现。
作为代码本身是很简单的,不用过多解释,整个实现的原理就是:首先new了两个Windows Messenger实例,分别为oMsgrObj以及oMsgrApp。然后通过对好友列表oList = oMsgrObj.List(0);循环枚举,并利用DOM技术塞入新的Element来列出好友名称oNewElement.innerText = oContact.FriendlyName; 以及好友状态switch (oContact.State)。最后通过function sendMessage()函数来实现OnClick事件,调用对应的Windows Messenger实例弹出好友对话框。整段代码是清晰明了也很容易懂的。这里我们主要看看造成上面图二错误的代码段:
function populateContacts()
{
var oList = oMsgrObj.List(0);
var oContact;
var i;
for (i = 0; i < oList.Count; i++)
{
oContact = oList.Item(i);
oNewElement = document.createElement("DIV");
oNewElement.innerText = oContact.FriendlyName;
接着我换了一个思路去做这个功能,直接在VS.Net中新建一个工程,引入COM中的MessengerAPI类,然后加入以下测试代码都会报错,不知道为什么。
我百思不得其解,同样的方法难道只能在本地使用?那这段代码不就没有意义了吗?恳请各位大虾指点迷津。m(_ _)m 拜..
附Windows Messenger下载地址:
http://nj.onlinedown.net/soft/3366.htm
其中包含了一段MSN Instant Messenger代码。首先要提出的一个大家容易混淆的概念:Windows Messenger 与 MSN Messenger 到底有什么区别和联系?
·MSN Messenger不是系统自带的,而Windows Messenger在非Windows 2003的Microsoft系统上都已经作为默认组件安装,这里我们要使用到的就是Windows Messenger API
·MSN Messenger只能用.Net Passport这个微软统一身份验证来登陆,也就意味着它只能在一台联入了互联网的电脑上登陆使用。而Windows Messenger则有三种登陆方式:a. Exchange身份验证 b. .Net Passport身份验证 c. SIP身份验证。其中c. SIP身份验证不太常用。而现在很多企业都已经建立了内部Exchange服务器,这样就经常会采用Windows Messenger的Exchange身份验证来进行登录后内部员工IM联系。而如果使用b. .Net Passport身份验证则功能上与MSN Messenger完全一样。
·Windows Messenger可以同时使用三种身份验证登陆,换句话说就是我可以同时登陆企业内网的Windows Messenger IM以及互联网上的MSN Messenger。其中的联系人列表是整合的。就有点像MyIM能整合MSN以及QQ、Yahoo IM等等IM软件一样。而MSN Messenger不行
·MSN Messenger的聊天记录可以保存,且通讯功能更加强大,如最新的7.5版本“传情动漫”以及“手写”功能已经完全超越了QQ等同类IM软件。而Windows Messenger聊天记录在关闭聊天窗口后消失不自动保存,只集成了一些最基本的通信方式。可以算作是简化版的MSN Messenger
有了以上的信息,我们已经可以开始试验了。将MSDN上的那段MSN Instant Messenger代码复制到本地,保存成.html文件,用IE打开。嗯。一切正常。请看下图(由于本人在台企上班,公司要求使用繁体操作系统,请大家见谅):
图一
然后,我们把这个文件复制到wwwroot发布目录下。再通过 http://172.18.77.60/ (我电脑的IP地址)前缀来访问。如下图所示:
图二
大家可以看到。同样一段代码。直接访问与发布后访问执行结果不同。我本想将此功能制作成一个WebPart以便在SharePoint上的任意地点引用。但是现在的问题是,只有我直接双击该html文件才能正常显示“联系人名单”,而我无论使用http://127.0.0.1/ 或者 http://localhost/ 或者 http://我的电脑IP地址/ 三种方式访问,联系人列表都会发生错误。但是通过点击“undefined”链接是可以实现对话功能的,通过查看源代码得知,其是通过枚举id来实现的,所以这里仅仅是一个显示上的问题。
下面让我们来看看完整的代码,完全使用JavaScript调用Windows Messenger API来实现。
1
<HTML>
2
<HEAD>
3
<TITLE>Embedding MSN Messenger Test</TITLE>
4
5
<OBJECT CLASSID="clsid:F3A614DC-ABE0-11d2-A441-00C04F795683"
6
CODEBASE="#Version=2,0,0,83"
7
CODETYPE="application/x-oleobject" ID="oMsgrObj" WIDTH="0"
8
HEIGHT="0" OnUserStateChanged="alert();">
9
</OBJECT>
10
<OBJECT CLASSID="clsid:FB7199AB-79BF-11d2-8D94-0000F875C541"
11
CODETYPE="application/x-oleobject"
12
ID="oMsgrApp" WIDTH="0" HEIGHT="0">
13
</OBJECT>
14
15
<STYLE>
16
BODY
17
{
18
FONT-FAMILY: Verdana, Arial, Helvetica;
19
FONT-SIZE: 8pt;
20
}
21
INPUT
22
{
23
FONT-FAMILY: Verdana, Arial, Helvetica;
24
FONT-SIZE: 8pt;
25
}
26
.clsHeading
27
{
28
FONT-WEIGHT: bolder;
29
FONT-SIZE: 10pt;
30
}
31
.clsContact
32
{
33
PADDING: 2px;
34
CURSOR: hand;
35
}
36
</STYLE>
37
</HEAD>
38
39
<BODY onLoad="body_onLoad();">
40
41
<SCRIPT LANGUAGE="JScript">
42
43
// Here are the definitions for the Messenger enumerated values we use
44
45
var MSTATE_OFFLINE = 1;
46
var MSTATE_ONLINE = 2;
47
var MSTATE_BUSY = 10;
48
var MSTATE_BE_RIGHT_BACK = 14;
49
var MSTATE_IDLE = 18;
50
var MSTATE_AWAY = 34;
51
52
function body_onLoad()
53
{
54
// First, we need to make sure that the Messenger controls got instantiated correctly
55
56
if ("undefined" != typeof(oMsgrObj) && null != oMsgrObj.object && "undefined"
57
!= typeof(oMsgrApp) && null != oMsgrApp.object)
58
{
59
// If so, let's check to see if we're online and (if so) populate our contacts UI
60
61
if (oMsgrObj.LocalState == MSTATE_ONLINE)
62
{
63
populateContacts();
64
}
65
else if (oMsgrObj.LocalState == MSTATE_OFFLINE)
66
{
67
btnLogon.disabled = false;
68
}
69
}
70
else
71
{
72
// Uh, oh - the controls didn't get instantiated correctly;
73
// the user probably needs to install Messenger
74
75
alert("You need to install the latest version of MSN Messenger!\nGo to http://messenger.msn.com right now!");
76
}
77
}
78
79
function populateContacts()
80
{
81
var oList = oMsgrObj.List(0);
82
var oContact;
83
var i;
84
85
// To populate our contact list, we're going to iterate throught the
86
// default list collection, check the state of each contact,
87
// and add a DIV with the approppriate appearance to our UI
88
89
for (i = 0; i < oList.Count; i++)
90
{
91
oContact = oList.Item(i);
92
93
oNewElement = document.createElement("DIV");
94
oNewElement.innerText = oContact.FriendlyName;
95
96
switch (oContact.State)
97
{
98
case MSTATE_ONLINE:
99
// Don't need to do anything
100
break;
101
case MSTATE_OFFLINE:
102
oNewElement.innerText += " (Offline)";
103
oNewElement.style.color = "graytext";
104
break;
105
case MSTATE_BUSY:
106
oNewElement.innerText += " (Busy)";
107
break;
108
case MSTATE_BE_RIGHT_BACK:
109
oNewElement.innerText += " (Be Right Back)";
110
break;
111
case MSTATE_IDLE:
112
oNewElement.innerText += " (Idle)";
113
break;
114
case MSTATE_AWAY:
115
oNewElement.innerText += " (Away)";
116
break;
117
default:
118
oNewElement.innerText += "(Just plain not around!)";
119
oNewElement.style.color = "graytext";
120
break;
121
}
122
oNewElement.className = "clsContact";
123
124
// To enable us to respond to the onclick event,
125
// we're programmatically setting the event
126
// handler AND we're defining an expando property
127
// on the contact DIV whose value is set to
128
// the index of the contact in the default list (so we can find them later)
129
130
oNewElement.onclick = sendMessage;
131
oNewElement.setAttribute("CONTACTID", i.toString());
132
133
divContacts.appendChild(oNewElement);
134
}
135
}
136
function doLogon()
137
{
138
// To logon, we just ask Messenger to display its logon UI
139
140
if (oMsgrObj.LocalState == MSTATE_OFFLINE)
141
{
142
btnLogon.disabled = true;
143
oMsgrApp.LaunchLogonUI();
144
}
145
}
146
147
function sendMessage()
148
{
149
// To send a message, we likewise just ask Messenger to do the heavy
150
// lifting (we just have to
151
// pass it a contact from the default list)
152
153
var nContactID = parseInt(window.event.srcElement.getAttribute("CONTACTID"));
154
if (!isNaN(nContactID))
155
{
156
var oContact = oMsgrObj.List(0).Item(nContactID);
157
oMsgrApp.LaunchIMUI(oContact);
158
}
159
}
160
161
</SCRIPT>
162
163
<SCRIPT LANGUAGE="JScript" EVENT="onLocalStateChangeResult(hr)" FOR="oMsgrObj">
164
165
if (hr == 0)
166
{
167
if (oMsgrObj.LocalState == MSTATE_ONLINE)
168
{
169
// Now we're online
170
171
window.setTimeout("populateContacts();", 3000);
172
}
173
else if (oMsgrObj.LocalState == MSTATE_OFFLINE)
174
{
175
// Now we're offline
176
177
divContacts.innerHTML = "";
178
btnLogon.disabled = false;
179
}
180
}
181
182
</SCRIPT>
183
184
<DIV CLASS="clsHeading">Contacts (click on a contact to send a message!)</DIV>
185
<DIV ID="divContacts" STYLE="MARGIN-TOP: 8px;
186
MARGIN-BOTTOM: 8px; BORDER: 1px solid steelblue"></DIV>
187
<INPUT TYPE="BUTTON" ID="btnLogon" VALUE="Logon" onClick="doLogon();" DISABLED="yes">
188
189
</BODY>
190
</HTML>

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

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

作为代码本身是很简单的,不用过多解释,整个实现的原理就是:首先new了两个Windows Messenger实例,分别为oMsgrObj以及oMsgrApp。然后通过对好友列表oList = oMsgrObj.List(0);循环枚举,并利用DOM技术塞入新的Element来列出好友名称oNewElement.innerText = oContact.FriendlyName; 以及好友状态switch (oContact.State)。最后通过function sendMessage()函数来实现OnClick事件,调用对应的Windows Messenger实例弹出好友对话框。整段代码是清晰明了也很容易懂的。这里我们主要看看造成上面图二错误的代码段:












其中由oList变量得到oMsgrObj的实例后枚举oList的各个Item并存放到oContact变量中。种种现象表明oMsgrObj以及oMsgrApp两个实例已经创建成功,否则无法调用其内部方法如 oMsgrObj.List(0) 以及 oList.Count,但是现在出问题的方法是 oContact.FriendlyName。图二现象表明如果使用IP访问该网页则 oContact.FriendlyName 方法无法正常得到联系人名称,所以会显示为 undefined。而直接通过IE打开该页面则一切正常。
有些朋友说是安全性的问题,我已经把几个地址都加入“信任的网站”了,问题依旧。请看下图:
接着我换了一个思路去做这个功能,直接在VS.Net中新建一个工程,引入COM中的MessengerAPI类,然后加入以下测试代码都会报错,不知道为什么。
1
using System;
2
using System.Collections;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Web;
7
using System.Web.SessionState;
8
using System.Web.UI;
9
using System.Web.UI.WebControls;
10
using System.Web.UI.HtmlControls;
11
using MessengerAPI;
12
13
namespace WebMessenger
14
{
15
/// <summary>
16
/// WebForm1 的摘要说明。
17
/// </summary>
18
public class WebForm1 : System.Web.UI.Page
19
{
20
private void Page_Load(object sender, System.EventArgs e)
21
{
22
// 在此处放置用户代码以初始化页面
23
getMsgrObj();
24
}
25
26
Web 窗体设计器生成的代码
46
47
private void getMsgrObj()
48
{
49
MessengerAPI.MessengerClass oMsgr = new MessengerAPI.MessengerClass();
50
Response.Write(oMsgr.MyStatus.ToString());
51
}
52
}
53
}

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

46

47

48

49

50

51

52

53

我百思不得其解,同样的方法难道只能在本地使用?那这段代码不就没有意义了吗?恳请各位大虾指点迷津。m(_ _)m 拜..
附Windows Messenger下载地址:
http://nj.onlinedown.net/soft/3366.htm