Posted by bianbian on 2011-08-11 04:50
本文Tags: AddPicture, C#, PowerPoint, PPT
powerpoint 2003 直接 “AddPicture (http://” 可行,如:
- string pic = "http://bianbian.org/example.gif";
- _Slide.Shapes.AddPicture(pic, MsoTriState.msoFalse, MsoTriState.msoTrue,
- 0, 0, _Pres.PageSetup.SlideWidth, _Pres.PageSetup.SlideHeight);
但在ppt 2007中,无法通过AddPicture添加http开头的图片,必须先AddShape,然后Fill:
- PPT.Shape shape = _Slide.Shapes.AddShape(MsoAutoShapeType.msoShapeRectangle,
- 0, 0, _Pres.PageSetup.SlideWidth, _Pres.PageSetup.SlideHeight);
- shape.Fill.UserPicture(pic);
详见:http://support.microsoft.com/kb/928983/en-us
标签:
AddPicture,
C#,
PowerPoint,
PPT遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Technology, Windows | No Comments »
Posted by bianbian on 2011-07-27 12:53
本文Tags: CLR, Linq, 存储过程
使用C#写CLR存储过程确实很方便。
不过遗憾的是,如果CLR里通过SqlContext.Pipe.Send()返回Select结果的话,并不能被Linq to SQL自动识别而返回ISingleResult的。(因为部署CLR存储过程实际产生的代码是不包含select语句的)
换句话说,所有CLR存储过程的返回值在Linq to SQL里都会被当成int。
解决办法:
1)如果该存储过程没有out的参数,比较好办:使用ExecuteQuery并EXEC 存储过程
如:
var query = DataContext.ExecuteQuery(“EXEC P_LoadUserWithTraining @trainingId={0}”, id).Single();
这种方法能取到结果,但是没有办法获得out参数。
2)如果该存储过程又有out的参数需要获得值,又返回select结果集的:
非常麻烦,只能部署CLR存储过程前,先手动在数据库里create procedure(同名,里面填上参数和select语句),
然后骗取Linq to SQL生成返回ISingleResult的代码,然后drop procedure,再部署CLR存储过程。
否则,即使把返回int的代码手动改成返回ISingleResult的,也会报错。我这里一直报 ArgumentOutOfRangeException
所以针对这种存储过程,最好还是T-SQL语句写。CLR的反而好麻烦。
标签:
CLR,
Linq,
存储过程遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Database, Technology | 1 Comment »
Posted by bianbian on 2010-09-23 03:17
本文Tags: C#, DataTable, JSON
最近实现一种将数据表转为JSON表示的新方法。
这种方法表示的JSON数据更省空间(尤其是网络传输,能省很多数据量),使用起来也很方便。
假设有这样一张数据表:
| ID |
Name |
Location |
| 1 |
周杰伦 |
香港 |
| 2 |
侯佩岑 |
台湾 |
| 3 |
张靓颖 |
大陆 |
一般的JSON表示方法为:
- [
- {"ID":1, "Name": "周杰伦", "Location": "香港"},
- {"ID":2, "Name": "侯佩岑", "Location": "台湾"},
- {"ID":3, "Name": "张靓颖", "Location": "大陆"}
- ]
可以看到,数据表的字段信息(column)在每条记录里都写了一遍,比较浪费空间。如果字段很多很长,甚至会比有效内容更多。随着记录数增加,浪费的数据量是很可观的。尤其像以前小百合BBS自己付流量费的时候,流量啊流量。。。。。。
我实现的表示方法产生的JSON格式是这样的:
- {
- "C":{"ID":0, "Name":1, "Location":2},
- "D":[
- [1, "周杰伦", "香港"],
- [2, "侯佩岑", "台湾"],
- [3, "张靓颖", "大陆"]
- ]}
这种方法将字段信息单独提取到C属性里,而D属性是纯粹的记录数据。
其实D属性本身已经完全能表示记录内容,C属性只是为了使用时方便。
在这短短几个字段及几条数据的极端情况下,已经省下几十字节。
下面对比使用方法,我承认这种方法稍微比通用的方法复杂一点,但是带来的节省,个人认为还是值得的:
- 通用方法取周杰伦:[0].Name
- 我的方法取周杰伦:D[0][C.Name]
下面是上述DataTable转JSON的C#代码:
- using System;
- using System.Text;
- using System.Web.Script.Serialization;
- /// <summary>
- /// 一种JSON表示DataTable的新方法
- /// <see href="http://bianbian.org/technology/javascript/361.html" />
- /// </summary>
- public static class JsonUtil
- {
- static JavaScriptSerializer _jss = new JavaScriptSerializer();
-
- /// <summary>
- /// DataTable 转换成 JSON string。
- /// </summary>
- /// <param name="dt">需要转换的DataTable</param>
- /// <returns>JSON结构字符串</returns>
- public static string FromDataTable(System.Data.DataTable dt)
- {
- StringBuilder sb = new StringBuilder(256);
- FormDataTable(dt, sb);
- return sb.ToString();
- }
-
- /// <summary>
- /// DataTable 转换成 JSON string。
- /// </summary>
- /// <param name="dt">需要转换的DataTable</param>
- /// <param name="sb">StringBuilder</param>
- public static void FormDataTable(System.Data.DataTable dt, StringBuilder sb)
- {
- sb.Append("{C:{");
- // -> {"ID":0, "Name":1}
- for (int j = 0; j < dt.Columns.Count; j++)
- {
- if (j > 0)
- sb.Append(',');
- sb.Append('"').Append(dt.Columns[j].ColumnName).Append('"')
- .Append(':').Append(j);
- }
- sb.Append("},D:[");
-
- for (int i = 0; i < dt.Rows.Count; i++)
- {
- if (i > 0)
- sb.Append(',');
- sb.Append('[');
- for (int j = 0; j < dt.Columns.Count; j++)
- {
- if (j > 0)
- sb.Append(',');
- _jss.Serialize(dt.Rows[i][j], sb);
- }
- sb.Append(']');
- }
- sb.Append("]}");
- }
- }
标签:
C#,
DataTable,
JSON遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, JavaScript, Technology | 11 Comments »
Posted by bianbian on 2010-04-16 12:42
本文Tags: C#, COM, CreateObject, PowerPoint, PPT, 进程
前阵子一直纳闷一件事,不是写了个早上10点自动生成天气会商ppt的程序嘛,不过时好时坏。具体的说:我去维护了一下后第二天是正常的,但是第三天就又不行了。看cron的日志(顺便推荐一下nnCron Lite),程序都正常启动了,但是ppt就是没有正常生成。
像我现在写的代码一般都不会有问题了,很少需要debug;看了几遍也没问题,所以很纳闷呀很纳闷。
后来没办法,开始在程序里输出log,才发现cron运行的时候(用户是SYSTEM),第二次运行:
using PPT = Microsoft.Office.Interop.PowerPoint;
_App = new PPT.Application();
这里会报COMException,真是奇怪了。
而调试的时候又是一切正常(用户是Administrator)。
最后总算捕捉到问题出现的情形:
cron运行,第一次正常产生ppt后,进程里仍驻留了PowerPNT.exe这个程序。
尽管程序是写了:
_App.Quit();
_App = null;
但是进程不会退出。不退出就算了,关键在SYSTEM用户下,第二次再跑程序的时候就会报前面提到的COMException,似乎一Quit(),这个PowerPNT.exe就挂在那里了。而在有用户界面的Administrator用户下,即使上一次进程没退出,也是可以正常工作的。
试了两种办法,可以使功能正常:
1)暴力一点,用完直接把进程kill掉:
Process ps = Process.GetProcessesByName(“POWERPNT.EXE”)[0];
ps.Kill();
2)最后不写 _App.Quit() ,让进程在内存里驻留。
最后还是选了2),毕竟服务器内存有10G,一个PPT进程也就20多M,而且PPT进程一个用户只有一个,相当于preload了,呵呵。。。
回家后找了一下文章,这个确实是Microsoft的问题。希望这篇文章对遇到这个问题的朋友有用。
如下是相关地址:
PPT2000: PowerPoint 2000 Remains in Memory After Getting a Presentation and Being Closed
powerpnt.exe remains running after OLE Quit()
GetObject and CreateObject behavior of Office automation servers
标签:
C#,
COM,
CreateObject,
PowerPoint,
PPT,
进程遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Meteorology | No Comments »
Posted by bianbian on 2009-03-02 09:26
本文Tags: C#, Marshal, struct, 泛型
背景简单提一下:好多个C/C++构成的结构体(struct)数据需要在C#中读取,他们可能在文件中或网络中(总之有办法转为流Stream)。
在C#中用Marshal的PtrToStructure()可以实现byte[]向struct的转变。
不过如果每个struct都要写个方法也太低效了,尤其是我现在遇到几十个struct的情况。。。。
研究了一下泛型(C#2.0就支持了),发现方法泛型可以解决这个问题。
Read the rest of this entry »
标签:
C#,
Marshal,
struct,
泛型遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Technology | 2 Comments »
Posted by bianbian on 2009-03-02 11:27
本文Tags: C#, delegate, Lambda, Micaps, 委派
C# 3.0新增了很多特性,其中委托(delegate)配合Lambda表达式使得程序简洁了很多。
我也就来尝尝鲜(其实也不算鲜了,C# 4.0都出来了。。。),说说我的应用实例:读取Micaps(一种气象上用的软件)数据文件。
Micaps有各类数据文件,比如第一类表示地面填图,格式是:
diamond 1 屏幕上需显示的内容
年 月 日 时次 总站点数
区站号 经度 纬度 ……(后面的你也不关心,就略掉了)
第二类表示高空填图,格式是:
diamond 2 屏幕上需显示的内容
年 月 日 时次 层次 总站点数
…… (参数与地面当然不一样)
如上,第一行是所有文件的通用信息,表示了该文件的类型、标题等,后面就是具体数据,每类文件格式不一。
于是,就要针对不同类型写不同的处理方法,但是,打开文件、关闭文件、检验第一行 这些又是一样的,导致代码重复。
这时候,委托就非常有意义:可以在父类里完成通用处理,而具体的数据处理通过委托交给子类具体负责。
Read the rest of this entry »
标签:
C#,
delegate,
Lambda,
Micaps,
委派遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Technology | 1 Comment »
Posted by bianbian on 2007-03-07 10:59
本文Tags: .NET, 反编译
其实.NET的dll和Java的class文件是类似的,果然也有对应的“反编译”工具:Reflector
真的很好用,我谢谢它了!
到Reflector官方网站(http://www.aisto.com/roeder/dotnet/)下载最新版本下载后
(要填姓名、单位和email,姓名要中间空一格,比如“bianbian xuxu”)
解压缩会有一个Reflector.exe直接就可以运行,界面如下:

打开一个.NET的库DLL,直接点方法就可以看源码了。。。。
这里是它的一些插件:
http://www.codeplex.com/reflectoraddins
其中我就用了FileDisassembler,功能就是将所有dll反编译的源码导出来。
标签:
.NET,
反编译遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Technology | 2 Comments »
Posted by bianbian on 2007-03-01 11:00
本文Tags: C#, Z-index, Z顺序, 解决
Z顺序(Z-Index)就是控件在绘制时候哪个在上哪个在下的顺序,就像PhotoShop里面的图层顺序。这个是很有用的,最早的虚拟形象(QQShow之类)就是利用Z顺序将N多小图片组合在一起拼合成一张图片,用图层相互覆盖的原理显示复杂的虚拟形象。扯远了,其实简单的说就是如下所示(B的Z-Index比A大,于是遮住了重叠的部分):

可是今天在C#里找了半天也没有发现设置Z顺序的方法。真是郁闷得紧。
于是想看看C#的设计器是怎么实现的,用设计器分别设计了A重叠B和B重叠A(又怀念Delphi一下),查看Design的源代码,OMG,还是没有涉及Z-Index的方法。。。
再看了一下,看来只跟Add到this.Controls里面的顺序有关了。验证了一下,果然如此:先Add的控件会在最上面。。。。。真是汗颜。。。。。
知道了原理,想个解决办法也不难了:就是Add控件进this.Controls之前根据啥属性(我看Tag属性挺好的)排个序。
如果需要运行中间改变某个控件的Z顺序,我看只能在this.Controls里综合运用Remove、Add了。。。
试验了一下,是可以的,代码写得实在太丑了,我就不献丑了。:(
标签:
C#,
Z-index,
Z顺序,
解决遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C#, Technology | 4 Comments »