我有以下JNA界面:
public interface MsiVersion extends StdCallLibrary {
MsiVersion INSTANCE = (MsiVersion)Native.loadLibrary( "msi", MsiVersion.class,
W32APIOptions.UNICODE_OPTIONS );
int MsiOpenDatabase( String szDatabasePath,
String szPersist,
Memory phDatabase );
}
如果我打开这样的MSI,一切都很好:
int oparationResult = MsiVersion.INSTANCE.MsiOpenDatabase( "example.msi", "0",
dbPointerMemory );
如果我尝试打开补丁,我会收到错误代码110.在文档中,我发现如果我想打开一个补丁,我应该以某种方式将MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE传递为“szPersist”而不是“0”。
我试图根据这个调用以下内容:this one
int oparationResult = MsiVersion.INSTANCE.MsiOpenDatabase( "example.msp", "32",
dbPointerMemory );
但是仍然得到错误代码110.有人可以帮我找到正确的参数吗?
谢谢, 巴林特
答案 0 :(得分:0)
您可能遇到此处所述的Ansi / Unicode问题:
https://blogs.msdn.microsoft.com/heaths/2006/03/31/opening-patch-files-when-compiled-for-unicode/
但请确保您需要说明您是否处于Unicode模式以及MSIDBOPEN_PATCHFILE的实际值
答案 1 :(得分:0)
问题是,MsiOpenDatabase
期望szPersist
参数的字符串指针,但是如果指定了持久性模式,这实际上是一个数字转换为字符串指针< /强>
来自“msiquery.h”:
#define MSIDBOPEN_READONLY (LPCTSTR)0
#define MSIDBOPEN_PATCHFILE 32/sizeof(*MSIDBOPEN_READONLY)
您正在将字符串文字“32”传递给szPersist
参数,但您需要传递一个值为32的指针 :
Pointer openMode = Pointer.createConstant(32);
int operationResult = MsiVersion.INSTANCE.MsiOpenDatabase( "example.msp", openMode, dbPointerMemory );
我不是Java程序员,所以我刚刚阅读了reference和FAQ(如何获得任意指针值?)。
我不确定您是否还需要更改JNA界面:
int MsiOpenDatabase( String szDatabasePath,
Pointer szPersist,
Memory phDatabase );
注意:作为Heath Stewart explained,头文件“msiquery.h”中的定义不正确。即使编译Unicode,MSIDBOPEN_PATCHFILE的值也必须始终为32
。