MsiOpendatabase使用jna为补丁返回错误110

时间:2017-04-13 13:47:35

标签: java java-native-interface windows-installer jna

我有以下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.有人可以帮我找到正确的参数吗?

谢谢, 巴林特

2 个答案:

答案 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程序员,所以我刚刚阅读了referenceFAQ如何获得任意指针值?)。

我不确定您是否还需要更改JNA界面:

int MsiOpenDatabase( String szDatabasePath,
                     Pointer szPersist,
                     Memory phDatabase );

注意:作为Heath Stewart explained,头文件“msiquery.h”中的定义不正确。即使编译Unicode,MSIDBOPEN_PATCHFILE的值也必须始终为32