背景:
目前游戏行业内的很多团队采用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中的常用的方法,以及对应的操作。