感悟生活

Life is like a box of chocolates. You never know what you're gonna get.
随笔 - 97, 评论 - 983, 引用 - 46

导航

关于

标签

每月存档

最新留言

  • iwobz
    <p>看了你那篇用程序登陆asp.net的文章,我觉得你是在骗人,昨天我也写这样的程序,我也把那些viewstate,username,password和eventvalidation那些...
    by iwobz(注册) on 2009/11/29 15:10:41
  • re:SharePoint的小秘密
    <p>@开心就好:测试2</p>
    by 开心就好(注册) on 2009/1/8 22:36:27
  • re:SharePoint的小秘密
    <p>@开心就好:测试</p>
    by 开心就好(注册) on 2009/1/8 22:30:45
  • 回复: 微软拼音输入法2003
    你好,我需要下载,谢谢
    by 李鑫龙(匿名) on 2008/2/20 12:56:00
  • 回复: 微软拼音输入法2003
    你好,我需要下载,谢谢
    by ヤ偽妳變儍い(匿名) on 2008/2/18 16:07:00
  • 回复: 微软拼音输入法2003
    我要用反体字聊QQ
    by 郝语情(匿名) on 2008/2/14 3:33:00
  • 回复: 微软拼音输入法2003
    我要下载
    by ﹏賎侽魜▓(匿名) on 2008/1/23 1:04:00
  • 回复: 有限状态机 理论联系实际
    写程序没理论指导,不重视基础,到现在才发现问题,本末倒置的学习过程。要是有正确的学习方法,水平远应比现在高。
    by wr(匿名) on 2008/1/15 18:08:00
  • SOA基本介绍
    Webservice已经不再是新婚的娘子。众多企业都已经创建各种实验性WebServices项目,事实证明,这项新兴的分布式计算技术确实能够降低集成和开发的成本。另外,一些关键的WebServ...
    by IamV(匿名) on 2007/12/31 16:31:00
  • 回复: SharePoint的小秘密
    在管理中心可以查看Site Collection使用哪个Content DB!
    by it(匿名) on 2007/12/25 11:10:00

广告

【第1页/共11页,104条】
首页
前页
1
...
2007年12月04日

工作重心转移到SharePoint上来已经有很长一段时间了。随着使用的深入,我常常会在SharePoint中遇到一些貌似神秘的行为,我称之为SharePoint的小秘密。如果有时间,我会将自己的一些观察和研究与大家分享。

刚才看到kaneboy在他的blog里讨论了迁移网站集所使用内容数据库的方法。一个Web Application支持多个Content DB是SharePoint一个很核心的功能,比如通过Content DB备份,迁移和恢复SharePoint网站,网站的性能等等,许多重要的功能都与此相关。

那么,当我们在一个Web Application中使用了多个Content DB时,我们会遇到一个有趣的问题,即我所谓的SharePoint的小秘密。我们知道,在建立新的Site Collection的时候,我们是无法选择该Site Collection使用哪个Content DB的,那么我们的Site Collection到底被建在了哪个Content DB中呢?

很久没写Blog,突然不太习惯.Text的编辑方式了。这个问题的答案等我用Word写好,再贴进来吧。正好也卖个关子,大家有兴趣可以测试一下,找找答案。

posted on 2007-12-04 22:14:00 by sam1111  评论(9) 阅读(4218)

 
2005年09月20日

有客户问我,怎么拿到应用到WebPart上的Audiences。一想很简单,还不就是用AudienceManage通过Audience所对应的GUID来Get吗。谁知道一写才发现了问题,与某个WebPart对应的GUID去哪里找到呢?难道要去Query database?不信WebPart类有这么傻。

查了半天终于发现,WebPart的IsIncludedFilter属性包含了所有应用到WebPart上的Audiences的GUID,它们使用逗号分隔。知道了这个就简单了。

private void button1_Click(object sender, System.EventArgs e) { // Get PortalContext. TopologyManager tm = new TopologyManager(); PortalSite ps = tm.PortalSites[new Uri("http://testsrv")]; PortalContext pc = PortalApplication.GetContext(ps); // Get all WebParts. SPSite site = new SPSite("http://testsrv"); SPWeb web = site.OpenWeb(); SPWebPartCollection wpcollection = web.GetWebPartCollection("default.aspx", Storage.Shared); // Get all audiences for each webpart. AudienceManager am = new AudienceManager(pc); foreach(WebPart wp in wpcollection) { if(wp.IsIncludedFilter == string.Empty) { Debug.WriteLine("No Target Audience was selected for " + wp.Title); } else { // IsIncludedFilter contains a comma delimited list of audience GUID, // which format is "'guid1','guid2'" string[] GUIDs = wp.IsIncludedFilter.Split(','); foreach(string GUID in GUIDs) { Audience au = am.GetAudience(new Guid(GUID.Substring(1, GUID.Length - 2))); if(au != null) { Debug.WriteLine("Target Audience, " + au.AudienceName + ", was selected for " + wp.Title); ArrayList membership = au.GetMembership(); if(membership != null) { for(int i = 0; i < membership.Count; i++) { Debug.WriteLine(" --" + ((UserInfo)membership[i]).PreferredName); Debug.WriteLine(" --" + ((UserInfo)membership[i]).Email); Debug.WriteLine(" --" + ((UserInfo)membership[i]).NTName); } } } } } } }

posted on 2005-09-20 17:42:00 by sam1111  评论(11) 阅读(4136)

 
2005年07月04日

根据InfoPath team blog里介绍的File Attachment Control的内容,写了两个类来处理文件的编码与解码。

public class InfoPathAttachmentEncoder { private string base64EncodedFile = string.Empty; private string fullyQualifiedFileName; /// <summary> /// Creates a encoder to create an InfoPath attachement string /// </summary> /// <param name="fullyQualifiedFileName"></param> public InfoPathAttachmentEncoder(string fullyQualifiedFileName) { if (fullyQualifiedFileName == string.Empty) throw new ArgumentException("Must specify file name", "fullyQualifiedFileName"); if (!File.Exists(fullyQualifiedFileName)) throw new FileNotFoundException("File does not exist: " + fullyQualifiedFileName, fullyQualifiedFileName); this.fullyQualifiedFileName = fullyQualifiedFileName; } /// <summary> /// Returns a Base64 encoded string /// </summary> /// <returns>String</returns> public string ToBase64String() { if (base64EncodedFile != string.Empty) return base64EncodedFile; // This memory stream will hold the InfoPath file attachment buffer before Base64 encoding MemoryStream ms = new MemoryStream(); // get the file information using (BinaryReader br = new BinaryReader(File.Open(fullyQualifiedFileName, FileMode.Open, FileAccess.Read, FileShare.Read))) { string fileName = Path.GetFileName(fullyQualifiedFileName); uint fileNameLength = (uint)fileName.Length + 1; byte[] fileNameBytes = Encoding.Unicode.GetBytes(fileName); using (BinaryWriter bw = new BinaryWriter(ms)) { // Write InfoPath attachment signature bw.Write(new byte[] { 0xC7, 0x49, 0x46, 0x41 }); // Write the default header information bw.Write((uint)0x14); // size bw.Write((uint)0x01); // version bw.Write((uint)0x00); // reserved // Write the file size bw.Write((uint)br.BaseStream.Length); // Write the size of the file name bw.Write((uint)fileNameLength); // Write the file name (Unicode encoded) bw.Write(fileNameBytes); // Write the file name terminator (which is two nulls in Unicode) bw.Write(new byte[] {0,0}); // Iterate through the file reading data and writing it to the outbuffer byte[] data = new byte[64*1024]; int bytesRead = 1; while (bytesRead > 0) { bytesRead = br.Read(data, 0, data.Length); bw.Write(data, 0, bytesRead); } } } // This memorystream will hold the Base64 encoded InfoPath attachment MemoryStream msOut = new MemoryStream(); using (BinaryReader br = new BinaryReader(new MemoryStream(ms.ToArray()))) { // Create a Base64 transform to do the encoding ToBase64Transform tf = new ToBase64Transform(); byte[] data = new byte[tf.InputBlockSize]; byte[] outData = new byte[tf.OutputBlockSize]; int bytesRead = 1; while (bytesRead > 0) { bytesRead = br.Read(data, 0, data.Length); if (bytesRead == data.Length) tf.TransformBlock(data, 0, bytesRead, outData, 0); else outData = tf.TransformFinalBlock(data, 0, bytesRead); msOut.Write(outData, 0, outData.Length); } } msOut.Close(); return base64EncodedFile = Encoding.ASCII.GetString(msOut.ToArray()); } }
public class InfoPathAttachmentDecoder
{ private const int SP1Header_Size = 20; private const int FIXED_HEADER = 16; private int fileSize; private int attachmentNameLength; private string attachmentName; private byte[] decodedAttachment; /// <summary> /// Accepts the Base64 encoded string /// that is the attachment /// </summary> public InfoPathAttachmentDecoder(string theBase64EncodedString) { byte [] theData = Convert.FromBase64String(theBase64EncodedString); using(MemoryStream ms = new MemoryStream(theData)) { BinaryReader theReader = new BinaryReader(ms); DecodeAttachment(theReader); } } private void DecodeAttachment(BinaryReader theReader) { //position the reader to get the filesize byte[] headerData = new byte[FIXED_HEADER]; headerData = theReader.ReadBytes(headerData.Length); fileSize = (int)theReader.ReadUInt32(); attachmentNameLength = (int)theReader.ReadUInt32() * 2; byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength); //InfoPath defaults to UTF8 encoding. Encoding enc = Encoding.Unicode; attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2); decodedAttachment = theReader.ReadBytes(fileSize); } public void SaveAttachment(string saveLocation) { string fullFileName = saveLocation; if(!fullFileName.EndsWith(Path.DirectorySeparatorChar.ToString())) { fullFileName += Path.DirectorySeparatorChar; } fullFileName += attachmentName; if(File.Exists(fullFileName)) File.Delete(fullFileName); FileStream fs = new FileStream(fullFileName, FileMode.CreateNew); BinaryWriter bw = new BinaryWriter(fs); bw.Write(decodedAttachment); bw.Close(); fs.Close(); } public string Filename { get{ return attachmentName; } } public byte[] DecodedAttachment { get{ return decodedAttachment; } } }
这样,我们就能根据需要对File Attachment Control来做进一步的控制了。
 

posted on 2005-07-04 13:07:00 by sam1111  评论(3) 阅读(4397)

 
2004年11月08日

为偶的NotesManager小程序写了一个带滚动条的Label控件,效果看起来象下面这样:

 

这个控件的实现思路说起来很简单,就是使用的一般Windows桌面程序中的窗口(Window)和视口(View)的概念。

考虑到Label本身不需要支持编辑的功能,出于效率的考虑,我在ScrollLabel控件中用一个Bitmap对象来保存Window的所有内容。在OnPaint中,如果发现Bitmap对象是空值(通常是第一次Paint),则根据当前Text的内容判断是否需要显示ScrollBar,并创建Bitmap对象,然后根据View的位置来显示应当显示在界面上的内容。以后每次Paint的时候,都只是根据滚动条的位置来计算View的位置,然后显示相应的Bitmap上的内容即可。当Text或者Font改变时,将原有的Bitmap销毁重新计算即可。整个OnPaint方法看起来象下面这样:

         protected override void OnPaint(PaintEventArgs e)

         {

              base.OnPaint (e);

 

              if(bmpWindow == null)

              {

                   Rectangle drawRect;

 

                   // Calculate the height of the window

                   SizeF size = e.Graphics.MeasureString(this.Text, this.Font);

                   rowHeight = size.Height;

                   float height = (size.Width / ClientSize.Width + 1) * rowHeight;

 

                   // Indicate if the scrollbar need to be shown.

                   if(height > ClientRectangle.Height)

                   {

                       // Recalculate the height of window.

                       height = (size.Width / (ClientSize.Width - scrollWidth)) * rowHeight + ClientSize.Height / 2;

 

                       // Show scrollbar

                       vs.Bounds = new Rectangle(this.ClientSize.Width - scrollWidth, 0,

                            scrollWidth, ClientSize.Height);

                       vs.LargeChange = (int)(ClientSize.Height / rowHeight);

                       vs.Maximum = (int)(height / rowHeight);

                       vs.Visible = true;

 

                       // Create window bitmap.

                       bmpWindow = new Bitmap(ClientSize.Width - scrollWidth, (int)height + 1);

                       drawRect = new Rectangle(0, 0, ClientSize.Width - scrollWidth, (int)height + 1);

                   }

                   else

                   {

                       bmpWindow = new Bitmap(ClientSize.Width, ClientSize.Height);

                       drawRect = this.ClientRectangle;

                   }

 

                   // Paint on the window bitmap.

                   Graphics g = Graphics.FromImage(bmpWindow);

                   g.FillRectangle(new SolidBrush(this.BackColor), drawRect);

                   g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), drawRect);

                   g.Dispose();

              }

 

              // Draw view.

              e.Graphics.DrawImage(bmpWindow, 0, 0 - (int)rowHeight * vs.Value);

         }

这个ScrollLabel的代码可以从这里下载。

不过这里使用的方法也有一些小缺陷,主要是源于目前版本的.NET CF不支持的一些功能。比如,为了得到作为Window的Bitmap的宽度和高度,我使用了MeasureString这个方法。但是目前版本的.NET CF中,MeasureString并不支持按给定宽度度量所需要的高度的功能,只能量出将所有的字画在一行上的宽度和高度。我的解决办法是,用MeasureString得到的高度作为行高,用MeasureString得到的宽度和整个ClientSize的宽度比值作为所有的行数,从而得到Window所需的高度。但是这样一来,就无法顾及由于英文的分词所带来的误差。比如MeasureString这个词,如果恰好在行尾,在Paint的时候它不会被截断,而时候整个的被放到下一行来显示。这样不断的叠加,最终在行数上是会产生一定的误差的。我暂时使用的解决方法是,对我用MeasureString得到的Window高度进行了1/2个ClientSize高度的误差补偿,这样你会发现,ScrollBar在滚动时并不是精确地滚动到最后一行,而是还会向下滚动一段空白区域。在大多数情况下,这段误差补偿是可以解决问题的,但是对于包含很多非常长的单词的情况,可能仍然会有问题。

更新后的NotesManager可以在这里下载。

 

posted on 2004-11-08 13:49:00 by sam1111  评论(14) 阅读(4911)

 
2004年11月04日

刚才收到mvm的邮件,说我的上一个post不能加comment,comment的submit按钮不work了,试了一下果然不能submit评论了。

刚才我用上一个post做了个测试,用来试验开心说的避免帖子显示在博客堂首页的方法,开始我以为这是引起问题的原因。Advanced里面的那一堆Checkbox前几个我都试了试,结果发现,似乎取消选中“显示在首页”并不能避免帖子显示在博客堂首页上,倒是帖子不会显示在自己的首页上了;取消选中“发布”的话,帖子不会显示在博客堂首页上,但是同时也不会显示在自己的首页上了,这样的话帖子也就没人能看到了;取消选中“允许评论”的话,帖子上不会有Feedback的链接。现在我选中了所有的选项,但是评论的submit按钮仍然不work。

再仔细想想今天我还改了什么,想起来下午我给自己的blog加了一个google站内搜索,但是测试下来发现,这段站内搜索代码似乎不能用。首先,click了google search按钮之后并没有按预期转到google的页面,而只是将本来的首页刷新了一遍似的。我在自己本地建了个测试页面,放上google的这段代码是可以work的,这说明可能是博客堂本身的代码与它有冲突;其次,google的站内搜索其实还是使用的site关键字,而这个site关键字搜索是不支持搜索类似http://blog.joycode.com/sam1111 这样的URL地址的,只支持类似blog.joycode.com这样的顶级域名,所以其实并不能按我的预期实现对http://blog.joycode.com/sam1111 的站内搜索;

虽说这段站内搜索不Work,我还是将那段代码留在那里了,主要是懒得去删了。刚才想起这会不会是引起不能submit comment的原因呢?因此去把它删了,现在submit comment果然可以用了。看来还真是google的search按钮与comment的submit按钮有冲突呢,难道是使用了相同的ID?

附:耽误了mvm的comment,特附在下面 :)

kaka, 居然不能在vpc里面运行sp的模拟器?

 

那能在vpc里面运行SFC模拟器么?

 

Btw, 无法在http://blog.joycode.com/sam1111/archive/2004/11/04/38033.aspx里面留言,本来想留在那个上面的。我这里居然click submit以后没有反应。很郁闷。

 

20:27更新:

SFC模拟器suppose应该是可以在VPC中运行的吧。SP的模拟器不能运行是因为SP的模拟器本质上是一个WinCE虚拟机,因此不能嵌在其他的Windows虚拟机中运行。虽然没试过,不过我想一定不能在一个Win2k3的虚拟机中再run一个WinXP的虚拟机。而SFC的模拟器应该与Windows虚拟机没什么关系。有空试试先。:)

 

21:05更新:

趁下班之前这段时间作了个测试,在虚拟机中安装VPC2004时报错无法安装虚拟网卡;能成功安装,但无法在WinXP虚拟机中运行,报与SP模拟器差不多的错,即无法在一个Virtual Machine中运行。SFC的模拟器倒是可以运行,只是声音似乎有点问题。

posted on 2004-11-04 20:08:00 by sam1111  评论(20) 阅读(9033)

 

作了个小升级,主要是界面上的:

??

新版本可以在这里下载。

原打算为Smartphone建个专门的VirtualPC环境来开发,down了个干净的WinXP SP2 Image,然后在上面一步一步装好了需要的所有软件。安装好了之后,写了个小程序作测试,发现Emulator无法运行起来,报个错,错误信息很具调侃性质,说,Emulator不能运行在另一个Emulator中,你只是试试对吧?一时摸不着头脑,上网查了一下发现,Emulator原来也是一种虚拟机,而两个虚拟机是无法嵌套使用的。等偶有空了倒要试试,看看能不能在一个VPC中run另外一个VPC。

posted on 2004-11-04 18:14:00 by sam1111  评论(20) 阅读(3579)

 
2004年10月08日
Pocket C#是一个for Windows CE的C#编译器,可以用来在Windows Mobile平台上编译.NET CF的程序。这个编译器是从DotGNU中移植过来的,作者Vitaliy Pronkin还只不过是一个20岁的学生,他还打算开发Mobile Device上的IDE。随着Mobile Device的运算能力越来越强大,直接在这些设备上编写调试程序真的不是梦了。

posted on 2004-10-08 20:20:00 by sam1111  评论(12) 阅读(4050)

 
2004年10月05日

一直想为俺的dopod 565找个好用的记Notes的工具,可是找到的几个都是收美金的,只好暂时用npad来记录一些东西。可是每次记得东西都要保存成txt文件,找起来不是很方便。正好今天比较空,于是就按照自己的想法写了一个,感兴趣的可以到http://www.91mobile.com/dispbbs.asp?boardID=36&ID=47135下载。由于是用VS 2005 beta 1写的,就没有上传代码。

  

之所以用VS 2005来写,主要有两个原因。一是VS 2005 beta 1内建了SmartPhone 2003 Second Edition模拟器,设计UI的时候可以直接在模拟的手机界面中进行,连接模拟器和调试也比配置VS 2003容易些,而且整个开发过程可以充分使用到VS 2005 IDE提供的强大功能,比如Refactoring;第二个原因嘛,就是俺的这台本本上暂时只装了VS 2005这一个开发环境。:D 有一点要说的是,虽然VS 2005在开发环境上支持SmartPhone 2003,但是编译的时候还是需要.NET Framework 1.1的。道理很简单,SmartPhone 2003并不支持.NET Framework 2.0,因此VS 2005仍然使用1.1的编译器。

至于程序本身嘛,倒是没什么可说的,就是读写XML而已。简单起见,所有的Control都使用的是.NET内建的,这就有了一些局限性,比如这个ListView的主界面就不是我所设想的那样。这些只能等什么时候有空了写一些User Control来解决了。同时还有一些重要的功能没写,比如Search,因为发现CF对XPath的支持好像不怎么样,就没写。

先dog food一阵子再说。:D

2004-10-06更新:

91还是不太稳定,放了个下载在Hi!PDA:

http://www.hi-pda.com/forum/viewthread.php?tid=208229&pid=2031529&page=1&sid=QOjWCe#pid2031529

另外,感谢jerome在他的网站上介绍这个小工具:

http://www.mmpet.com/forum_posts.asp?TID=172&PN=1

posted on 2004-10-05 18:37:00 by sam1111  评论(18) 阅读(4989)

 
2004年09月14日

Paul Stubbs的blog上有几段关于VSTO 2005的Video

如果安装了VS2005 beta1,VSTO 2005已经集成在里面了。对比VSTO 2003,2005加入了许多新特性,使得基于他来开发Office Solution变得更加简单。比如,用VSTO 2005写Word、Excel Solution的时候,Word或Excel被作为设计器整个的host进了IDE环境中,这样我们就可以充分利用VS2005提供的强大的IDE进行所见即所得的设计与编码了;在使用VSTO 2003的时候,你也许会有这样的感觉,就是有时会觉得能够利用的事件或方法太少,很多事情需要绕很大的弯子才能实现。VSTO 2005在这方面也改进了不少,增加了许多control,比如bookmark、XMLNode等等,现在都以控件的形式提供出来,有属于自己的事件和方法,开发时的自由度无疑更强了。

posted on 2004-09-14 10:39:00 by sam1111  评论(13) 阅读(8970)

 
2004年09月08日

最近gmail放松了新帐号的邀请,一时间似乎人人都有gmail的帐号,甚至有点送都送不出去的感觉,前段时间那种洛阳纸贵的情景一去不复返了。:)

这样倒好,用的人多了,研究的人自然也就多了。看看这个for .Net的Gmail Agent API ,用GET/POST的方式实现的,代码写的很精巧。记得以前有人讨论过gmail的为什么比别的web-based的邮件系统快,这个页面上给出了答案。

其他的比如这个在Linux上将gmail作为一个文件系统的GmailFS,for Python的库libgmail甚至能将gmail作为一个FTP Server,真是没有做不到,只有想不到。

posted on 2004-09-08 18:29:00 by sam1111  评论(33) 阅读(5974)

 
【第1页/共11页,104条】
首页
前页
1
...

Powered by: Joycode.MVC引擎 0.5.2.0