Burnett

淡定,执着......
posts - 29, comments - 99, trackbacks - 13, articles - 11
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

置顶随笔

http://www.windwhisper.cn
同时,园子里的文章也会跟着这个Blog同步更新的。

posted @ 2007-12-11 09:05 Burnett 阅读(68) | 评论 (0)编辑

2008年3月11日

招聘职位:.NET开发工程师

工作地点:南京

主要职责:
1、完成对企业的需求分析及详细的规划设计
2、以Sharepoint为中心的企业级应用软件开发、部署、维护
3、整合异构的应用系统


任职要求:
1、有良好的沟通能力和团队合作能力;

2、熟悉Windows域控制原理,熟悉AD,了解IIS的使用和管理;
 
3、熟悉C++、  ASP.Net 1.1/2.0、XML、工作流的开发,有参与过相关Web应用开发经验优先;

4、了解Microsoft SQL Server 2000/2005的安装和使用;

5、熟悉Sharepoint环境优先


职业规划:
MS应用专家
Sharepoint应用专家
职业IT管理者

请感兴趣者发送简历至:liu.bo22@zte.com.cn

posted @ 2008-03-11 15:52 Burnett 阅读(809) | 评论 (8)编辑

2008年2月24日


大家都知道,Sharepoint的列表实际上是对数据库中表(Table)的概念的延伸。但是当我们打开Sharepoint的时候,会发现,你建立的列表并没有存储成数据库中的一张表。那么列表是存储在哪里的呢?他们在运行中又是怎么被提取出来的呢?从这篇文章开始,我们要一点一点将MOSS的神秘的存储结构剖析清楚,不仅仅对MOSS的开发有帮助,也可以拓宽我们的软件体系设计的思维。

  打开SqlServer 中对应的数据库,我们会发现有很多很多的表存在,其中最为重要的当属dbo.AllUserData表。里边存储了基本上所有的数据。当然,你存储在列表中的数据也是存储在这里的。
  打开这个表,你会发现有很多的列。在后边就会知道这些列都是用来做什么的。
 

   其实,MOSS的列表概念可以理解成一张虚表,它并不是真实存在的,而是在需要的时候,从AllUserData中动态的提取出来,不过AllUserData存储的是所有的数据,像被丢在回收站的数据也是在里边被保留下来的,只不过被做了一个特殊的标记。

聪明的读者一定发现了,AllUserData中的tp_ListId就是确定不同的“虚表”的,如果写成sql查询,应该类似于这样

SQL代码
  1. select * from dbo.AllUserData where tp_ListId='your list id'  

是的,这样就可以简单的将自己需要的数据单独提取出来了。不过这只是第一步。最重要的是,列表中的列,在AllUserData中怎么表示呢?反正不能新建一个列,就改动AllUserData的结构吧。并且怎么处理不同列的相同列名的情况呢(比如内容类型)?聪明的MS开发者使用的是这么一种办法。在AllUserData表中,预先留置了很多很多的,多到你用不完的数据列,这些列的列名就是他们的类型+编号。比如nvarchar1,nvarchar2,float1,int3,datatime1......在MOSS中创建栏的时候,MOSS根据栏的类型,就会将数据存储到相应的这些数据列中。比如用户姓名会存入nvarchar1中,而年龄也许会存入int1中,这些存储不是随机的,而是采用的先到先服务(FIFS)的思想的。并且这些列与列名的映射都会存入dbo.AllLists表中的tp_Fields属性中。你可以在这个属性中看到映射。如果你稍微处理一下,这个属性中的数据可以按照XML文件来处理(后边会给出代码)。

好了,这个就是MOSS数据库的结构。有人会问,既然MOSS给了这么好用的List的概念,为什么还用煞费苦心的自己来读取数据呢?我想首先一个是更加了解MOSS体系结构,另外一个绕过了MOSS的一些体系上的效率问题,直接存取数据库的效率和灵活性,sql查询的强大,列表和列表自带的CAML查询应该是做不到的。


文章来源:http://www.windwhisper.cn/default.asp?id=32

posted @ 2008-02-24 21:50 Burnett 阅读(601) | 评论 (1)编辑

2007年12月14日

  MOSS 2007经过近一年的使用体验,终于在2007年底的时候放出了SP1,可谓是千呼万唤始出来。

不但让MOSS2007支持了AJAX的web part,而且更新了STSADM的工具。

其中有几个比较重要的HotFixes:
You configure an advanced search Web part to use a custom scope. However, when you perform the advance search operation, the result that you obtain is not limited to the custom scope.
搜索Web部件并不会限定在特定的站点内部。

When you use Forms-based authentication, no search results are returned. However, when you use NTLM authentication, search results are returned.
Form认证的时候,不会返回搜索结果。

In Firefox 2.0, any author-time action does not finish when that action involves a SharePoint Server 2007 dialog box that lets you perform the following actions: • Edit the HTML source code of a given HTML field 
• Select assets such as an image or a link 
• Perform a state action, such as "check-in," "submit for approval," or "approval" 
This issue also occurs when any Microsoft Windows SharePoint Services or SharePoint Server 2007 dialog box passes non-string values back to the caller.
这个fix是针对Firefox的,看来微软真是下了血本了:D

You install Windows SharePoint Services 3.0 and then upgrade to SharePoint Server 2007. Then, you uninstall SharePoint 2007. When you try to reinstall SharePoint 2007, the installation fails. Additionally, you receive the following error message:
Error 997
当你从WSS3.0升级到MOSS2007,然后你删掉MOSS2007,在安装的时候,会出现997错误。

大部分是对从wss2.0升级带来的问题,搜索爬网的问题,多语言的问题,字符大小写问题,还有对Windows Server 2008的兼容等作出的补丁。其他的小问题,可以参看这两个文件。

WSS 3.0 SP1 HOTFIXES

OSS SP1 HOTFIXES

PS:如果在使用MOSS之前就知道了这些BUG,不知道当时心里会怎么想:D

文章来源:http://www.windwhisper.cn/default.asp?id=16

posted @ 2007-12-14 16:26 Burnett 阅读(622) | 评论 (0)编辑

2007年12月10日

  因为老大的要求,需要将MOSS的Window认证改为较为友好的Form认证。因为这是一个很老的话题,所以懒得自己想,上网google了一下。这一下不要紧,发现网络上的教程,所用的数据源要不是text的,要不就是sql server上的,唯独没有AD的。看来还是要自己动手哇。
  OK,让我们先了解一下升级的大致原理。
  
  这是Memebership在整个应用结构中的位置。观察发现,Membership的位置位于较为底层,可以预见的是,很多具体的应用操作可以通过Membership实现过滤。
  因为我们是使用的现成的AD组件,所以我们并不需要写什么代码,直接对web.config文件做一些修改即可,告诉MOSS该将取得的用户名与密码送到哪里去,然后获得一个布尔型的结果,既可以达到以前windows认证相同的效果了。
  在这里,我们假设,你要对http://moss:8082站点进行form认证的升级。
  注意,请在修改web.config文件之前做一下备份!
一,修改8082文件夹下的web.config文件

打开此文件,定位到<system.web>节点下,增加此节点
程序代码 程序代码
      <membership defaultProvider="MembershipADProvider">
          
<providers>
              
<add
                
name="MembershipADProvider"
                type
="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                connectionStringName
="ADConnectionString"
                connectionUsername
="administrator"
                connectionPassword
="your password" attributeMapUsername="SAMAccountName" enableSearchMethods="true"/>
          
</providers>
      
</membership>

并且在<system.web>的父级节点增加此节点
程序代码 程序代码


    
<connectionStrings>
        
<add name="ADConnectionString"
         connectionString
="LDAP://yourcompany.com/CN=Users,DC=YOURCOMPANY,DC=com" />
    
</connectionStrings>

二,修改管理中心的web.config文件

打开IIS,打开管理中心站点的属性查看管理中心的文件目录

进入文件目录,按照步骤一的改法再次修改一遍web.config。
这里要注意的几个问题:
一个就是attributeMapUsername属性,必须赋上SAMAccountName(注意大小写),否则会在添加用户的时候出现"找不到完全匹配的项目"的错误。如下图


另外一个问题就是关于LDAP配置,你需要根据你自己域树的形状设定LDAP地址。
最后一个是关于设定应用程序和管理中心的web.config文件。为什么非要修改管理中心的web.config文件呢?管理中心中有时候必须要到域里取用户的信息,比如设定站点集的管理员。如果你还是用的域里的信息,那么会生成类似于下面这种形式的登录名:YOURDOMAIN\YOURNAME,而你用的Form认证,会生成YOURPROVIDERNAME/YOURNAME格式的登录名。显然,这两种登录名是不一样的。这也是为什么在更换到Form认证以后,所有的角色会失效的原因。


三,管理中心中配置

好了,现在web.config文件设定完毕了。
进入管理中心-》应用程序管理-》应用程序安全性 -》验证提供程序 。选择8082端口的应用程序。

然后按照你设定的Provider名称填入。


   注意:此时数据虽然还是AD中的,但是因为映射改变,角色也就失效了,要在“网站集管理员”中重新设定管理员,并且你的站点里也要重新分配员工到角色上,并且一个可爱的功能没了(添加所有已验证用户)。



大功告成,现在登陆看看,记得,此时只要用户名就可以了,域名就不要填了:)


文章来源:http://www.windwhisper.cn/default.asp?id=14 [来自于我的www.windwhisper.cn,文章总是会现在这里发布的。]

posted @ 2007-12-10 19:56 Burnett 阅读(413) | 评论 (6)编辑

2007年10月17日

  最近接到了一个需求,需要将保存在Infopath表单中的数据提取出来。可是这么做出现了一个问题,就是经过IP上传的文件,似乎都被IP的附件控件增加了一些数据,这会导致一种颇为致命的错误,这么来做会破坏原文件的二进制布局。如果容错性不好的程序,会直接报错。比如我把word文件提出来序列化到硬盘上打开,2003会直接提示错误,2007倒是在提示错误以后,可以自动修复。不过我们不需要这种功能。
 Here we go!
 首先应该找出,调皮的Infopath到底将哪些数据藏在了文件的什么地方。动手写了一个程序,将未处理过的文件和被处理过的文件逐字节匹配,遇到不匹配的数据以后会尝试查找匹配的数据。
            FileStream fs1 = new FileStream(@"c:\source", FileMode.Open);
            FileStream fs2 
= new FileStream(@"c:\dest", FileMode.Open);
            BinaryReader brSrc 
= new BinaryReader(fs1);
            BinaryReader brDst 
= new BinaryReader(fs2);
            
byte[] src=brSrc.ReadBytes(int.Parse(brSrc.BaseStream.Length.ToString()));
            
byte[] dst = brDst.ReadBytes(int.Parse(brDst.BaseStream.Length.ToString()));
            
int destPtr = 0;
            
for (int srcPtr = 0; srcPtr < src.Length; srcPtr++, destPtr++)
            {

                
if (dst[destPtr] != src[srcPtr])
                {
                    Console.WriteLine(
string.Format("目标文件的第{0}位置出现与源文件{1}不匹配的情况,不匹配的字符{2}",srcPtr,destPtr,dst[destPtr]));
                    
                    
for (; destPtr < dst.Length; destPtr++)
                    {
                        
if (dst[destPtr] == src[srcPtr])
                        {
                            Console.WriteLine(String.Format(
"在第{0}个位置上,找到对应byte", destPtr)); Console.Read();
                            
break;
                        }
                    }
                }
                
else
                    Console.WriteLine(
"source的第{0}位与dest的第{1}位匹配",srcPtr,destPtr);                
            }
            Console.Read();

经过测试发现,新的文件比老文件增大了58个字节,看来我的猜测是对的,Infopath的确在文件中动了手脚!
再看一下结果:


还好,数据只被增加到了Infopath文件的头部。剩下的就是要分析头的格式,因为一般头都是可变长度的,所以分析格式可以动态的取出实际的infopath文件。

取出这58个字节,经过Unicode解码,发现了我上传文件的文件名。联想到infopath的xml文件中,并没有存有文件名的节点,但是仍然可以在infopath中将数据显示出来的情况,问题就很好解释了。

参考Infopath的官方博客的文章,http://blogs.msdn.com/infopath/archive/2004/03/18/92221.aspx
发现了这么一段话:
·         BYTE[4]: Signature (based on the signature for PNG): 

(decimal)                       
199       73         70         65
(hexadecimal)                C7        
49         46         41 
(ASCII C notation)          \
307      I           F          A  


The first byte is chosen as a non-ASCII value to reduce the probability that a text file may be misrecognized as a file attachment.  The rest identifies the file as an InfoPath File Attachment.  


·         DWORD: Size of the header 

·         DWORD: IP Version 

·         DWORD: dwReserved 

·         DWORD: File size 

·         DWORD: Size of file name buffer 

·         File name buffer: variable size 

注意到这个头文件的格式分为六个部分,除了BYTE[4]中的四个字节,其余五部分都是DWORD类型。注意,DWORD是双字,一字是两个字节,也就是说一个DWORD的大小是4个字节。问题到这里就很清楚了,前4*(4+1)个字节是固定不变的,其中,在第20到24字节保存的正是文件名的大小。



OK,现在我们要做的就是找出动态的文件头,并把他们从我们的文件中剔除出去!文件的偏移量应该是 24+文件名长度。

            int namebufferlen = dst[20* 2;
            
byte[] namebuf=new byte[namebufferlen];
            
int headLength = 24 + namebufferlen;
            
string name = Encoding.Unicode.GetString(dst, 0, headLength);
            
byte[] realContent = new byte[dst.Length - headLength];

realContent就是我们实际的文件的内容!

Enjoy Infopath!

posted @ 2007-10-17 17:23 Burnett 阅读(247) | 评论 (2)编辑

2007年9月4日

前几日需要在Infopath中保存文件,但是发现在web方式下只要上传文件,就产生如下提示(找不到所选文件):



假设你的MOSS2007是默认安装。

首先,打开工作流的workflow.xml文件,定位到<Workflow>节点。查看此节点下的此三个属性的值,
         AssociationUrl="_layouts/CstWrkflIP.aspx"
         InstantiationUrl="_layouts/IniWrkflIP.aspx"
         ModificationUrl="_layouts/ModWrkflIP.aspx"


然后在以下目录中定位这三个文件:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS

依此打开这些文件,查看他们的master文件。往往他们是这么来描述的:
MasterPageFile="~/_layouts/application.master"

然后定位到这个文件,打开它,然后定位到<form>标签,添加一个属性,enctype="multipart/form-data"。然后的结果类似于这个:
<form runat="server" onsubmit="return _spFormOnSubmitWrapper();" enctype="multipart/form-data">

接着保存,再重新启动IIS(必须要重启,否则会出现未知错误的提示,我想应该是MOSS的内部文件验证机制的问题)

修改后,文件即可以正常上传了



背景知识:
让我们来看看“multipart/form-data”属性在W3C里的定义吧。
The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
可见这个属性的功能是打开表单在上传中可能存在的非ASCII数据。比如照片、word文档等二进制数据。

posted @ 2007-09-04 11:14 Burnett 阅读(354) | 评论 (8)编辑

2007年9月3日

  问题描述:在继承于SequentialWorkflowActivity的Workflow1类里,调用自定义的IPBTask和IPBTaskContainer类,其中IPBTaskContainer类是标记为[Serializable]的自定义类,而且在Workflow1里,其生命周期是类级别上的。并且在Workflow1里实例化了IPBTaskContainer。
  问题过程:首先启动一条新的工作流,初始化表单可以正常调出,然后启动,此时的工作流标记应该变成“进行中”,可是一旦按照问题描述中的问题进行设定,那么工作流就会直接变成“已完成”。但是任务还是可以正常生成。并且在CreateTask中的断点也可以产生中断。

  不知道各位在工作流中引入自己的类的时候,是不是会出现这个问题。

  这个问题我足足调试了半个星期,一开始没有想到错误居然是因为引入了自定义类。编译器在编译期也没有给出任何的警告和错误信息。总之这种异常非常隐蔽,大家以后一定要小心。

posted @ 2007-09-03 10:38 Burnett 阅读(134) | 评论 (1)编辑

2007年8月27日

     摘要: 仰慕vs2008的一键调试工作流大法,周末抽空装了一下,可惜......[08/25/07,16:33:23]Microsoft.NETFramework3.5:[2]Errorcode1603forthiscomponentmeans"安装时发生严重错误"[08/25/07,16:33:23]Microsoft.NETFramework3.5:[2]SetupFailedoncomponentM... 阅读全文

posted @ 2007-08-27 15:08 Burnett 阅读(3321) | 评论 (28)编辑

2007年8月3日

在公司要用代理,回来又要把代理关掉,比较繁琐,所以无事写了一个软件,
虽然只有一个功能,就是一键切换浏览器在注册表中的设置。但是麻雀虽小五脏俱全,具有完整的8个类实现代理切换操作,还有异常捕获机制和配置差异化同步,比较适合.net入门者解剖学习^_^

ezProxySwitch


posted @ 2007-08-03 13:56 Burnett 阅读(290) | 评论 (0)编辑

2007年8月2日

最近没有事情,写了一个可以方便切换浏览器代理的软件,可是在最后测试阶段,发现在尝试将设置写入注册表的时候出现UnauthorizedAccessException异常,提示“无法写入注册表”。百思不得其解。后来逐条查看RegisterKey的相关代码,发现在OpenSubKey方法的第二个布尔类型的参数必须设置为true。再次测试通过。
稍后放出这个小代理切换软件o(∩_∩)o..

posted @ 2007-08-02 09:06 Burnett 阅读(115) | 评论 (0)编辑

2007年3月29日

我在使用对象模型读取列表中的栏的时候,发现如果是读取带有链接的栏,比如“用户和用户组”类型的栏,会得到类似于这种效果的东东:41;#小龙女。“;”前边的是id号,“#”后边的是用户名。这个似乎很好理解,因为链接嘛,就是要有一个ID在内的,可是无论我怎么转换,都无法转换成用户类型的对象。没有办法,只有自己写Split解析的,可以行通,但是感觉很不爽。不知道是不是还有其他办法

posted @ 2007-03-29 19:56 Burnett 阅读(377) | 评论 (2)编辑

2007年3月26日

  前一段时间为了满足公司的要求,需要使用Timer的特性来进行开发。当时碰到这个需求的时候,首先想到的,就是写一个控制台程序放在服务器上跟着MOSS2007一起跑算了,可是后来想了一下,似乎在管理中心见过计时器的特性。随即打开了“计时器作业定义”,研究了半天也没有头绪,接着一头栽进SDK里搜寻了半天,发现了这个SPJobDefinition类似乎有点意思,不过需要使用SPFeatureReceiver这个类来进行部署,也就是说,制作一个可以部署的计时器,需要分成两个部分来设计:
   首先,编写计时器程序,也就是继承于SPJobDefinition的类,我写的叫做EventCheckTimer。
   其次,编写部署这个计时器所需要的安装器,也就是继承SPFeatureReceiver的类,我这里叫做EventCheckTimerInstaller
   然后就很清楚了,使用这个Installer将EventCheckTimer部署到服务器上,部署的方式,是将feature.xml、mainifest.xml、强命名密钥、以及这两个类生成的dll文件打包成wsp格式的文件(其实就是cab文件),你也许会用到这个wsp部署的模板:wsp模板
  好的,我们引入程序:
这一个类是Timer Job的主类,系统主要是调用里边的Execute方法,这个方法的参数targetInstanceId(内容数据库ID)并不需要你来传递,而是系统在合适的时间在调用的时候自动传递的,你可以把它看作几乎被我们写烂的Main函数:)

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace MyCompany.Management.Employees
{
    
/// <summary>
    
/// 这一个类是计时器的主工作类,系统会按照在Installer中
    
/// 设定的schedule定期调用此类中的Execute方法
    
/// </summary>
    public class EventCheckTimer : SPJobDefinition
    {
        
public EventCheckTimer() : base() { }

        
/// <summary>
        
/// 初始化EventCheckTimer
        
/// 更多的构造函数请参看SDK
        
/// </summary>
        
/// <param name="_timername">计时器的名称</param>
        
/// <param name="_wp">Web应用程序名称</param>
        public EventCheckTimer(string _timername, SPWebApplication _wp)
            : 
base(_timername, _wp, null, SPJobLockType.ContentDatabase)
        {
            
this.Title = "合同到期提醒器0.04";
        }

        
/// <summary>
        
/// 此方法由系统调用,contentDbId也由系统传递
        
/// </summary>
        
/// <param name="_contentdbid">内容数据库的id</param>
        public override void Execute(Guid targetInstanceId)
        {
            SPWebApplication webApplication 
= this.Parent as SPWebApplication;
            SPContentDatabase contentDb 
= webApplication.ContentDatabases[targetInstanceId];
            DateTime dt;

            
//遍历当前员工库中的员工,审查所有可能的提醒事件
            foreach (SPListItem li in contentDb.Sites[0].AllWebs["Employees"].Lists["员工库"].Items)
            {
                
if (li["合同止时间"!= null)
                {
                    dt 
= Convert.ToDateTime(li["合同止时间"]);
                    TimeSpan ts 
= (dt.Date - DateTime.Today.Date);
                    
//如果合同止时间小于当前时间,这种情况一般只发生在服务崩溃的时候
                    if (dt.Date < DateTime.Now.Date)
                    {
                        SPListItem si 
= contentDb.Sites[0].AllWebs["Employees"].Lists["任务"].Items.Add();
                        si[
"标题"= String.Format("{0}的合同已经到期!", li["员工姓名"]);
                        si[
"截止日期"= DateTime.Now.AddDays(7);
                        si.Update();
                    }
                    
else
                        
if (ts.Days <= 30)//如果距离现在有30天的时间,那么发出提醒
                        {
                            SPListItem si 
= contentDb.Sites[0].AllWebs["Employees"].Lists["任务"].Items.Add();
                            si[
"截止日期"= DateTime.Now.AddDays(7);
                            si[
"标题"= String.Format("{0}的合同将于{1}天后到期,日期:{2}", li["员工姓名"], (dt.Date - DateTime.Now.Date), li["合同止时间"]);
                            si.Update();
                        }
                }
            }
        }
    }
}

在设定完TimerJob的时候,就可以编写安装器了,下边是代码:其实可以照抄的,不过要注意在FeatureActivated中改成你要部署的计时器的对象,还有就是计时器的计时周期,需要改成你自己需要的。这里的BeginSecond和EndSecond指的是计时器满足触发条件的时候,在一分钟内的那一段时间内执行,比如我这就是可以在0~59秒内执行。其他计时周期类似。
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace MyCompany.Management.Employees
{
    
/// <summary>
    
/// 这一个类的作用主要是安装某一个功能到站点上
    
/// 被安装的对象的类必须是从SPJobDefinition继承
    
/// 过来的
    
/// </summary>
    class EventCheckTimerInstaller : SPFeatureReceiver
    {
        
const string MY_TASK = "EventCheckTimer";

        
/// <summary>
        
/// 在功能被安装以后被调用
        
/// </summary>
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
        }

        
/// <summary>
        
/// 在功能被卸载的时候被调用
        
/// </summary>
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
        }

        
/// <summary>
        
/// 在功能被激活的时候被调用
        
/// </summary>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            
// 取得当前站点的作用域
            SPSite site = properties.Feature.Parent as SPSite;

            
// 确保在安装此功能之前系统不被调用
            foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
            {
                
if (job.Name == MY_TASK)
                    job.Delete();
            }

            
// 安装TimerJob
            EventCheckTimer timer = new EventCheckTimer(MY_TASK, site.WebApplication);
            
//设置记时器的工作计划表,在这里是每日启动一次,运行时间00:00-05:00,更多的Timer请参看SDK,最小是只执行一次,最长是一天
            
//SPDailySchedule schedule = new SPDailySchedule();
            
//schedule.BeginHour = 0;
            
//schedule.EndHour = 5;
            SPMinuteSchedule schedule = new SPMinuteSchedule();
            schedule.BeginSecond 
= 0;
            schedule.EndSecond 
= 59;
            schedule.Interval 
= 1;
            timer.Schedule 
= schedule;
            
            timer.Update();
        }

        
/// <summary>
        
/// 在功能被冻结的时候被调用
        
/// </summary>
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPSite site 
= properties.Feature.Parent as SPSite;

            
// 删除这个功能
            foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
            {
                
if (job.Name == MY_TASK)
                    job.Delete();
            }
        }
    }
}

如果你用了wsp安装包,那么部署激活的顺序是这样的
stsadm -o addsolution -filename yourwspfile.wsp
stsadm -o deploysolution -name yourwspfile.wsp -immediate -allowgacdeployment -force
stsadm.exe -o execadmsvcjobs '这一段是立即执行部署操作
net stop "Windows SharePoint Services Timer" '重启计时器服务,
net start "Windows SharePoint Services Timer"
resetiis
在解决方案管理里部署你的解决方案
在网站集功能里打开这个功能,就OK了。
如果你要卸载Timer,就比较麻烦~~~
首先需要在网站集功能里关闭功能,然后执行
stsadm -o deletesolution -name ZTEsoft.Management.Employees.EventCheckTimer.wsp -override
千万记着最后要重启Windows SharePoint Services Timer刷新服务,否则网站集还是会继续执行Timer服务的。
这点也许对于调试不是很爽,其实因为你写的程序是周期性的执行,所以你可以先模拟TimerJob的执行环境在控制台程序里执行一下,确保万事OK了,再放在Execute函数里,用Installer包装一下安装就可以了。
如果你只是测试,那么测试完成后一定要记得关掉网站集功能,否则也许在将来的某天,你的数据库会被同样的信息塞满的:)

posted @ 2007-03-26 20:13 Burnett 阅读(1160) | 评论 (5)编辑

2007年3月22日

     摘要: 在MOSS2007企业版里,默认提供了很多的过滤器,但是没有一种过滤器可以实现事先设定过滤条件,比如选择当前列表栏作为筛选条件,然后输入对应值,为了满足需求,使用了IFilterProvider接口实现一个Web部件。可以实现的功能:可以实现多条件候选值下的单一条件过滤。可以根据当前连接部件的视图自动适应栏,不需要使用者自己干预。前期的知识准备:需要有基本的Web部件的制作部署知识,需要了解Web... 阅读全文

posted @ 2007-03-22 15:46 Burnett 阅读(806) | 评论 (1)编辑

2007年3月16日

当前标识(NT AUTHORITY\NETWORK SERVICE)没有对“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files”的写访问权限。

到网上查了一下需要重新安装asp.net服务,
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -i -enable
开始安装 ASP.NET (2.0.50727)。
......................
ASP.NET (2.0.50727)安装完毕。
安装程序检测到操作过程中出现了一些错误。有关详细信息,请查看安装程序日志文件 C:\
DOCUME~1\ADMINI~1\LOCALS~1\Temp\1\ASPNETSetup_00003.log

查看了一下日志,发现了这个错误:
2007-03-16 16:02:17 Failure  Determining if we are running on a domain controller: IsDomainController failed with HRESULT 80070842: '没有启动服务器服务。  '
在“服务”里启动Server服务,重新运行命令,通过!

posted @ 2007-03-16 16:18 Burnett 阅读(510) | 评论 (0)编辑

2007年3月14日

刚才测试SPS中的列表功能,准备添加自定义的内容类型“员工信息”,可是发现自己自定义一个内容类型以后,在“添加内容类型”页面中,根本无法找到此内容类型。而后比照一下可以显示的内容类型的父类型,发现父级是以下类型的内容类型是可以添加到列表的内容类型中的:项目、公用指标列、文件夹以及继承此内容类型的子内容类型。而父级是以下内容的内容类型是无法添加到列表的内容类型中的:文档、空白页以及继承此类型的子类型。

posted @ 2007-03-14 11:21 Burnett 阅读(304) | 评论 (0)编辑

2007年3月2日

重新安装了Windows 2003操作系统,可是无法登录到远程文件夹,查阅了一下网上的资料,发现是服务里的workstation服务没有被打开,看看workstation的描述:“创建和维护到远程服务的客户端网络连接。如果服务停止,这些连接将不可用。如果服务被禁用,任何直接依赖于此服务的服务将无法启动”。呵呵,符合症状,打开这个服务,重新登录一下,OK了~~~

posted @ 2007-03-02 10:13 Burnett 阅读(5200) | 评论 (4)编辑

显示农历

posted @ 2007-03-02 09:28 Burnett 阅读(81) | 评论 (0)编辑

2007年2月28日

     摘要: 最近工程进展顺利,需要从测试服务器搬迁到正式服务器上进行最后测试。测试服务器上的一个Web应用程序已经具有了正式版本的体貌特征,所以本着“码为己用”的原则,以备份还原的方式迁移此应用程序到正式服务器上应用。但是在管理中心的备份还原功能中,实在难以搞定很简单的备份操作,所以Google了一下,做一个工作总结。   阅读全文

posted @ 2007-02-28 14:49 Burnett 阅读(1598) | 评论 (15)编辑

     摘要: 内容类型是贯穿整个Microsoft Windows SharePoint Services 3.0中提供的功能和服务的核心概念,它是为帮助用户以一种有意义的方式来组织他们SharePoint内容而设计的。一种内容类型是一组可以重用的设置集合,这组设置集合是应用于某一个特定的目录内容的。内容类型可以让你使用一种集中的,可重用的方式来管理文档或者项目类型的元信息和行为。  阅读全文

posted @ 2007-02-28 09:57 Burnett 阅读(578) | 评论 (0)编辑

2007年2月27日

     摘要: 在WSS 3.0中,用户使用基于角色的成员系统来访问Web站点,列表,文件夹和列表项目。用户也通过扮演某一个角色的认证方式来操作WSS对象模型。
  阅读全文

posted @ 2007-02-27 11:58 Burnett 阅读(739) | 评论 (4)编辑

如果发现代码段功能里没有workflow和feature的选项可以参考一下这篇文章:
http://www.cnblogs.com/xiaoshatian/archive/2006/12/31/608479.html

这篇文章也向您展示了这两个文件的作用。
http://weblog.vb-tech.com/nick/archive/2006/09/04/1760.aspx

我的Workflow.xml的内容:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    
<Workflow
         
Name="My Workflow"
         Description
="This workflow "
         Id
="9e22a7b0-4fef-411a-b8c2-4ff8cca31e85"
         CodeBesideClass
="HelloSPWF.ApplyWorkFlow" 
         CodeBesideAssembly
="HelloSPWF, Version=3.0.0.0, Culture=neutral, PublicKeyToken=4bfa53b046e311f6"
         TaskListContentTypeId
="0x01080100C9C9515DE4E24001905074F980F93160"
         AssociationUrl
="_layouts/CstWrkflIP.aspx"
         InstantiationUrl
="_layouts/IniWrkflIP.aspx"
         ModificationUrl
="_layouts/ModWrkflIP.aspx">

        
<Categories/>
        
<!-- Tags to specify InfoPath forms for the workflow; delete tags for forms that you do not have -->
        
<MetaData>
            
<Association_FormURN>urn:schemas-microsoft-com:office:infopath:bxd-apply1:-myXSD-2007-02-06T06-43-51</Association_FormURN>
            
<Instantiation_FormURN>urn:schemas-microsoft-com:office:infopath:bxd-apply1:-myXSD-2007-02-06T06-43-51</Instantiation_FormURN>
            
<Task0_FormURN>urn:schemas-microsoft-com:office:infopath:bxd-mark:-myXSD-2007-02-09T08-06-41</Task0_FormURN>

            
<Modification_GUID_FormURN>modificationURN</Modification_GUID_FormURN>
            
<Modification_GUID_Name>Name of Modification</Modification_GUID_Name>

            
<StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl>
        
</MetaData>
    
</Workflow>
</Elements>
Element元素中包含的Workflow子节点就是对工作流属性的描述。
   Workflow的属性含义:
  • Name::工作流的名称,将会在站点集功能里标识工作流。
  • Description:工作流的描述,将会显示工作流介绍中
  • Id:工作流的Id,这里的IdGUID,可以使用System.GUid.NewGuid()来获取,也可是使用下面我自己写的一个程序来获得GUid,可以放心的去取,因为对于我们有生之年,这种编号是用之不尽的。
  • CodeBesideClass:这个属性标记了工作流存在于哪一个命名空间下的哪一个类中。在这里我的工作流是存在于HelloSPWF命名空间下的ApplyWorkFlow中的。
  • CodeBesideAssembly 程序集信息,就是部署到GAC(Global Assembly Cache)中的程序集,可以由Reflector获取完整的程序集信息
  • TaskListContentTypeId:任务的内容类型ID,一般不需要修改。
  • AssociationUrl:Association表单的默认路径
  • InstantiationUrl:Instantiation表单的默认路径
  • ModificationUrl:Modification表单的默认路径

    MetaData节点中保存了表单的标识信息,也是我们关心的一个节点。比如我们的一个工作流的应用中,会使用到联合表单(用于SPS管理层在部署工作流到一个项目的时候设定数据信息),初始化表单(工作流启动者填写的表单),还有任务处理表单(用于审批者处理审批信息的表单)。这个工作流使用到的表单由这些表单的URN(Uniform Resource Name,是URI的一个子集)唯一标识,然后存储在MetaData中。

    • Association_FormURN:联合表单的URN
    • Instantiation_FormURN:初始化表单的URN
    • TaskN_FormURN:任务编辑表单的URN,这里的N可以是0,1,2,....,n的自然数,表示不同的任务所使用到编辑表单,比如经理用到的编辑表单也许会和会计使用到的编辑表单有所不同。
    Note:如何获取InfoPath表单的URN

    首先以设计的模式打开InfoPath表单
    1.


    2.

    我的feature.xml的内容
    <Feature  Id="4d44d6cb-50ac-4e2b-a15d-2d9eb0db56d2"
              Title
    ="宸梾璐规姤閿€鍗曞鎵?
              Description="
    宸梾璐规姤閿€鍗曞鎵瑰伐浣滄祦"
              Version
    ="12.0.0.0"
              Scope
    ="Site"
              ReceiverAssembly
    ="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
              ReceiverClass
    ="Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver"
              xmlns
    ="http://schemas.microsoft.com/sharepoint/">
        
    <ElementManifests>
            
    <ElementManifest Location="workflow.xml" />
        
    </ElementManifests>
        
    <Properties>
            
    <Property Key="GloballyAvailable" Value="true" />

            
    <!-- Value for RegisterForms key indicates the path to the forms relative to feature file location -->
            
    <!-- if you don't have forms, use *.xsn -->
            
    <Property Key="RegisterForms" Value="*.xsn" />
        
    </Properties>
    </Feature>
    Feature节点中的元素标识了工作流的功能描述:
  • Name::节点的名称,将会在站点集功能里标识工作流。
  • Description:节点的描述,将会显示工作流介绍中
  • Id:节点的Id,这里的IdGUID
  • ElementManifests:制定工作流的xml定义文件

  • posted @ 2007-02-27 09:21 Burnett 阅读(631) | 评论 (6)编辑

    2007年2月10日

    http://www.mscourse.com/blog/u/windie/archives/2007/143.html

    主要还是模板安装的时候没有完全定制好~~

    posted @ 2007-02-10 12:23 Burnett 阅读(258) | 评论 (0)编辑

    2007年2月8日

         摘要: VS2005在工具箱中的控件丢失,主要是Visual Studio 2005 Extensions for Windows Workflow Foundation版本问题。  阅读全文

    posted @ 2007-02-08 10:55 Burnett 阅读(770) | 评论 (0)编辑

    2007年2月7日

    http://www.microsoft.com/china/MSDN/library/netFramework/netframework/intronetfx30.mspx?mfr=true

    着重介绍了四个新增加的组件:Windows Workflow Foundation、Windows Communication Foundation、Windows CardSpace 和 Windows Presentation Foundation

    posted @ 2007-02-07 14:16 Burnett 阅读(146) | 评论 (0)编辑

    2006年4月28日

    最近应同学邀请,帮他的老板做一个增值业务的平台,这是我正式接触商业编程环境,也是第一次用.net做实际的东西.做的时候不敢妄称最好,但是我的确是为了性能,每一步都尽量优化系统的结构.以下是我积累起来的经验,以后会陆续加入的.因为是工程上的东西,所以可以采百家之长,各路高手前辈不吝指点!

    • 详细设计阶段用的时间长不是坏事.现在我越来越深入到系统细节,发现当时的文档写的越是粗糙.感觉到有必要停下来和同事再把