首页 > c#, SAP Business One > 质量甚差的 SAP B1 SDK C# Samples

质量甚差的 SAP B1 SDK C# Samples

sap_09_logo 我这里所讲的是 SAP Business One 2005B 光碟上的 SDK – Sample。我看过全部 C# 的例子。非常明显,是先写好 VB 的源码,再换成 C# 写出来的,而不是直接从新写 C#。这没什么关系。问题是当中某些部分的源码质量,我实在不敢恭维。

我也是个新手,连我都看得出有问题,那就太可惜了。作为发送给编程员的例子,而且是 SAP 的牌头,我以为他们不可能这么丢脸。唉…… 我只把AddOnInstaller 例子的一部分展示出来,亦把我的见解写出来,大家请自行判断。

安装 SDK 后会相关路径找到三个文件夹:

  1. Help,这里是放置 Documentation 的;
  2. Tools,这里放置“工具”,英文语法有误,因为里面只有一个工具,应命名为 Tool,没有 s;
  3. Samples,这里放置了一大堆 Visual Studio 的项目档和源码,作为给开发者的开发实例,分别有 VB6,VB.NET和 C#。 本篇所说的就是在 Samples 内的 AddOnInstaller 例子 C#版本。

问题一:C# 代码混合 VB 代码

首先,看看这个 installer 的例子,代码用 C# 的:

image怎么会在 C# 内引用 Microsoft.VisualBasic 的呀,我奇怪,在 using 内发现一句 using Microsoft.VisualBasic; ,什么飞机,删掉,引用页删掉,再编译… 错误出来了,源码真的有用到 VisualBasic 命名空间内的东西。

五个错误,出现在两行内(第538行、第608行),说是 Interaction、MsgBoxStyle、Constant 不在目前的命名空间内。我不太会VB,去那两行看看,一行是出现在安装的 method 代码 Catch block 内:

Interaction.MsgBox(ex.Message, MsgBoxStyle.Information, "Addon Installer"); 

 

另一行出现在一个名为ShowError 的 method 内,而且这就只有这一句,而ShowError只被调用过一次:

Interaction.MsgBox(ex.Message + Constants.vbNewLine + "Source:" + ex.StackTrace, MsgBoxStyle.Information, "Addon Installer");

我写的话,当然是 System.Windows.Forms.MessageBox.Show(…) 啦。

细心的你,可能也看到以上的截图,也引用 mscorlib,这一点也是无厘头得很。

问题二:冗长语句、String array 大小错误

这不知道是代码 style 的问题还是从 VB 抄过来而产生的问题,一行写完的东西我真的觉得没必要分两行。比如:

        //Dim strAppPath As String

        // The command line parameters, seperated by '|' will be broken to this array
        string[] strCmdLineElements = new string[3];

        string strCmdLine; // The whole command line

        int NumOfParams; //The number of parameters in the command line (should be 2)
        

        NumOfParams = Environment.GetCommandLineArgs().Length;

        if (NumOfParams == 2)
        {
          strCmdLine = Environment.GetCommandLineArgs().GetValue(1).ToString();
          if (strCmdLine.ToUpper() == "/U")
          {
            UnInstall();
          }
          strCmdLineElements = strCmdLine.Split("|".ToCharArray());

          // Get Install destination Folder
          strDest = strCmdLineElements.GetValue(0).ToString();
          txtDest.Text = strDest;

          // Get the "AddOnInstallAPI.dll" path
          strDll = strCmdLineElements.GetValue(1).ToString();

//Dim strAppPath As String ,我狂倒,官方 SDK 居然出现这样的东西,这个也就算了,看看 NumOfParams 这个数。整个 method 内,只有这里用到,它是用来存放命令行参数的数量,用来测试此程序是否在 SAP B1 环境下运行。

我写的话,会这样:

if (Environment.GetCommandLineArgs().Length == 2)

或者建个string[] 在 stack,这样:

string[] arguments = Environment.GetCommandLineArgs();

if (arguments.Length == 2)
{
  strCmdLine = arguments.GetValue(1).ToString();
  ....

然后判断了不是 Uninstall 之后,奇怪了,strCmdLineElements = strCmdLine.Split(“|”.ToCharArray()); 这样的话……按照官方说明,pass 过去安装程序的参数格式是 “…|…”,把建议安装路径和AddOnInstallAPI.dll的路径用“|”连在一起作为一个字串的。用 Split 后,得到的 string[] 大小将会是 2。看看上面的 declaration:

string[] strCmdLineElements = new string[3];

我再次狂倒… 多出的一个用来养老鼠乎?我写的会直接在判断不是 uninstall 之后,一句搞定,这样写(这里也修复了原来那个多余的 ToCharArray() ):

string[] strCmdLineElements = strCmdLine.Split('|');

我对编程的 style 不熟,我没有接受过正规编程培训,不知道怎样才是正规。我写的版本,只有 string[] arguments; 是放在最前面的,我认为只有这个 string[] 才是整个 method 都用到的。可能 declaration 全部放在前面才是好方式,不晓得。我只知道,这份源码,真的很难看,看得我好累。

问题三:逻辑顺序

顺序这一点说成问题有点牵强,SDK 这个例子,判断程序是否在 SAP B1 中运行的办法很简单,就是看看是否只有一个命令行参数,不管这个参数是什么的。判断的逻辑不谈,判断的代码是写了在 Form_Load 这个句柄内的。即是说,Application.Run(new form); 中,new form 已产生,但显示在屏幕之前。

我认为,把此检查放在 Application.Run 之前,更合理,我亦是那样写的。

问题四:忽略 Read() 回传值

以上的,是不好看,貌似也没什么大不了的。现在这个不一样。

         byte[] buffer;
        buffer = new byte[file.Length + 1];

        file.Read(buffer, 0, (int) (file.Length));
        AddonExeFile.Write(buffer, 0, (int) (file.Length));
        AddonExeFile.Close();

这代码的目的,是把内嵌资源 HelloWorld.exe (即Add-On执行档)抄送到目的地文件夹。file 是 System.IO.Stream,AddonExeFile 是 System.IO.FileStream。先把内嵌资源抄到 file (file = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(…) ),再用 byte[] buffer 抄过去 AddonExeFile (file.Read 和 AddonExeFile.Write)。

问题在于 Read 是有回传值的,只有回传值是等于file.Length的时候,才真正、完整读取。据前人教导,任何 I/O,不可能假设没错误。这里漏了个检查,这里忽略了Read() 的回传值。若说 Read/Write 都是用 file.Length,不同就会 throw exception,这样的假设不但难看,而且 file.Length相同就代表没错误这本身亦是一个假设。

啰嗦了那么久,其实原因是,本来我以为可以抄,但我实在接受不了这样的东西出自我手笔,亦看不顺眼所谓的 SAP 官方例子。

分类: c#, SAP Business One 标签:, , , , , ,
  1. 还没有评论。
  1. No trackbacks yet.

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Connecting to %s

加关注

Get every new post delivered to your Inbox.