基于Python调用封装Hansoft-SDK经验分享

  • Post author:
  • Post category:python



背景:

目前游戏行业内的很多团队采用Hansoft作为团队敏捷规划工具,Hansoft的开发商Perforce,能很好的和P4V协作,所以得到了很多国外公司的青睐,国内虽然不是很多,但是也有一些团队在使用。

在团队项目中,我们会对协作工具做一些DIY需求,经常会使用SDK来封装一些自己的服务来支持团队需求,以提高工作效率,但我作为国内开发者,在使用该工具的SDK的过程充满了痛苦和折磨,最大的原因就是几乎没有关于HansoftSDK的开发者的经验分享,以及它晦涩的开发文档,除此外,SDK仅支持C/C++、Java、C#/.NET,Python也是最近的版本才支持,但并不为官方所推荐和维护,所以开发过程中充满了各种各样的困难,为了避免其他开发者走同样的弯路,我将遇到的问题和一些代码整理下来供有同样问题面临的同学参考,希望能提供一点微小的帮助。

首先整理了一些官方文档:

1.官方文档:

HansoftSDK

sdk库文件下载地址:

Hansoft SDK | Perforce

下载好与你访问的Hansoft版本一致的sdk压缩包后,解压取出’HPMSdkManaged_4_5.x64.dll’文件放在与你的代码文件一致的目录下。我是用的是Hansoft11版本。

如果想调用sdk访问Hansoft数据库,首先需要一个在后台创建一个SDK账户,并如下图所示配置在代码中或配置文件中。

通过PIP安装一些必备的包:


pythonnet 2.5.2 如果版本不一致有可能会报错或无法访问dll.

以下是Hansoft官方提供的Python样例代码。只包括基础的与Hansoft建立连接功能。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys

import clr
from System import IntPtr
from System import String
from System import IO
from System import Array
from System.Collections import *


dll_path = 'path/to/HPMSdkManaged_4_5.x64' #不能有.dll后缀
clr.AddReference( dll_path )
import HPMSdk


SERVER_NAME = 'hansoft'
PORT_NO = 50256
DATABASE_NAME = 'Company Projects'
USER_NAME = 'SDKUser'
PASSWORD = 'hpmadm'


class SessionCallbacks(HPMSdk.HPMSdkCallbacks):
    __namespace__ = "SessionCallbacks"
    def __init__( self ):
        super(HPMSdk.HPMSdkCallbacks, self).__init__()

    def On_ProcessError( self, inError ):
        print 'SessionCallbacks.On_ProcessError:', inError


class Hansoft( object ):
    def __init__( self, server_name=SERVER_NAME ):
        self.session = None
        self.server_name = server_name
        self.project_id = -1
        self.project_name = ''
    def __del__( self ):
        self.sessionDestroy()

    def sessionOpen( self ):
        self.ensureConnected()

    def _sessionOpenMain( self ):
        callback = None

        try:
            callback = SessionCallbacks()
            self.session = HPMSdk.HPMSdkSession.SessionOpen( self.server_name, PORT_NO, DATABASE_NAME, USER_NAME, PASSWORD, callback, None, True, HPMSdk.EHPMSdkDebugMode.Off, IntPtr.op_Explicit(0), 0, "", "", None )
        except HPMSdk.HPMSdkException, e:
            print 'HPMSdk.HPMSdkException'
            print e.ErrorAsStr()
            pass
        except HPMSdk.HPMSdkManagedException, e:
            print 'HPMSdk.HPMSdkManagedException'
            print e.ErrorAsStr()
            pass
        except Exception, e:
            print e

    def ensureConnected( self, force=False ):
	    try:
            if self.session:
                self.session.ResourceEnum()
        except HPMSdk.HPMSdkException, e:
            print e.ErrorAsStr()
            self.sessionDestroy()
        except HPMSdk.HPMSdkManagedException, e:
            print e.ErrorAsStr()
            self.sessionDestroy()
        except Exception, e:
            print e
            self.sessionDestroy()

        if self.session:
            return

        self._sessionOpenMain()
        if self.project_name != '':
            self.setProject( self.project_name )

    def sessionDestroy( self ):
        if self.session is not None:
            try:
                HPMSdk.HPMSdkSession.SessionDestroy( self.session )
            except HPMSdk.HPMSdkException, e:
                print 'sessionDestroy : HPMSdk.HPMSdkException:', e.ErrorAsStr()
            except HPMSdk.HPMSdkManagedException, e:
                print 'sessionDestroy : HPMSdk.HPMSdkManagedException:',e.ErrorAsStr()
            except Exception, e:
                pass
            self.session = None


def test():
    h = Hansoft()
    h.sessionOpen()
    h.sessionDestroy()

# EOD

run后返回Hansoft connect success即为访问成功,可以开展下一步的工作。



重要!!!!在这一行代码中,self.session = HPMSdk.HPMSdkSession.SessionOpen( self.server_name, PORT_NO, DATABASE_NAME, USER_NAME, PASSWORD, callback, None, True, HPMSdk.EHPMSdkDebugMode.Off, IntPtr.op_Explicit(0), 0, “”, “”, None ),倒数第二个参数是DLL的目录,在我们下载官方SDK下有个Win32目录,这个也是我们必须要填的,比如“C:/Windows/HansoftSDK/Win32”,否则有可能出现英文报错“找不到DLL目录。”



这里困扰了我很久,之前我以为是因为只支持Python2,导致我代码重构,最近才发现,原来是因为这里的问题。

Q&A:

在调用的过程中可能存在以下需要注意点:

1.如下图中显示报错 Unresolved reference ‘System’.

忽视即可,原因是通过该代码的实现方案是通过Pythonnet包跨语言调用C#的.dll文件实现

2.pythonnet版本需要为2.5.2

3.使用try except代码块捕获异常时,需要如下图红框所示捕获异常,否则会无法正确显示报错内容。

4.HansoftSDK版本要和Hansoft服务器的版本一致。之前我因为这个问题卡了很久,才排查出来是这个原因。

备注:如何下载到旧版本SDK:

后面我会介绍一些SDK中的常用的方法,以及对应的操作。



版权声明:本文为li99yangg原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。