jna CoCreateInstance

时间:2013-02-05 16:38:43

标签: jna

我正在尝试在Windows 7中创建一个带有图标的链接。我正在使用JNA库。我在调用CoCreateInstance时遇到问题。它返回错误。首先,我不确定IShellLink的GUID是否正确(我不是Windows程序员)。以下是我的代码。一旦我得到指向IShellLink的指针,我需要填写链接的参数(目标,图标,描述等)。我正在通过此链接(http://www.codeproject.com/Articles/11467/How-to-create-short-cuts-link-files)下面的C代码对此调用进行建模。我知道我可以使用mklink命令,但它确实有一个添加图标和描述的选项。

private void createLink(){
    Pointer reserved = null; //Must be null
    int dwCoInit = 0;

    HRESULT oleInitResult = Ole32.INSTANCE.CoInitializeEx(reserved,dwCoInit);
    if(oleInitResult.equals(W32Errors.S_OK)){
        GUID rclsid = Ole32Util.getGUIDFromString("{e82a2d71-5b2f-43a0-97b8-81be15854de8}"); //Shell object
        GUID riid = Ole32Util.getGUIDFromString("{000214EE-0000-0000-C000-000000000046}"); //CLSID of the IShellLink object
        PointerByReference ppv = new PointerByReference();
        HRESULT oleCreateResult = Ole32.INSTANCE.CoCreateInstance(rclsid,null,ObjBase.CLSCTX_INPROC,riid,ppv);
        if(oleCreateResult.equals(W32Errors.S_OK)){

        }else{
            System.out.println("Failed to create link error "+oleCreateResult.intValue());
        }
    }
    Ole32.INSTANCE.CoUninitialize();
}
###################### C ++示例代码
/*
--------------------------------------------------------------------------------
Description: Creates the actual 'lnk' file (assumes COM has been initialized).
Parameters: pszTargetfile    - File name of the link's target, must be a non-empty string.
pszTargetargs    - Command line arguments passed to link's target, may be an empty string.
pszLinkfile      - File name of the actual link file, must be a non-empty string.
pszDescription   - Description of the linked item. If this is an empty string the description is not set.
iShowmode        - ShowWindow() constant for the link's target. Use one of:
                       1 (SW_SHOWNORMAL) = Normal window.
                       3 (SW_SHOWMAXIMIZED) = Maximized.
                       7 (SW_SHOWMINNOACTIVE) = Minimized.
                     If this is zero the showmode is not set.
pszCurdir        - Working directory of the active link. If this is an empty string the directory is not set.
pszIconfile      - File name of the icon file used for the link.  If this is an empty string the icon is not set.
iIconindex       - Index of the icon in the icon file. If this is < 0 the icon is not set.
Returns: HRESULT value >= 0 for success, < 0 for failure.
--------------------------------------------------------------------------------
*/
static HRESULT CreateShortCut(LPSTR pszTargetfile, LPSTR pszTargetargs, LPSTR pszLinkfile, LPSTR pszDescription, 
int iShowmode, LPSTR pszCurdir, LPSTR pszIconfile, int iIconindex) {
HRESULT       hRes;                  /* Returned COM result code */
IShellLink*   pShellLink;            /* IShellLink object pointer */
IPersistFile* pPersistFile;          /* IPersistFile object pointer */
WORD          wszLinkfile[MAX_PATH]; /* pszLinkfile as Unicode string */
int           iWideCharsWritten;     /* Number of wide characters written */
hRes = E_INVALIDARG;
if (
       (pszTargetfile != NULL) && (strlen(pszTargetfile) > 0) &&
       (pszTargetargs != NULL) &&
       (pszLinkfile != NULL) && (strlen(pszLinkfile) > 0) &&
       (pszDescription != NULL) && 
       (iShowmode >= 0) &&
       (pszCurdir != NULL) && 
       (pszIconfile != NULL) &&
       (iIconindex >= 0)
) {
    hRes = CoCreateInstance(&CLSID_ShellLink,     /* pre-defined CLSID of the IShellLink object */
                            NULL,                 /* pointer to parent interface if part of aggregate */
                            CLSCTX_INPROC_SERVER, /* caller and called code are in same process */
                            &IID_IShellLink,      /* pre-defined interface of the IShellLink object */
                            &pShellLink);         /* Returns a pointer to the IShellLink object */
    if (SUCCEEDED(hRes))
    {
      /* Set the fields in the IShellLink object */
      hRes = pShellLink->lpVtbl->SetPath(pShellLink, pszTargetfile);
      hRes = pShellLink->lpVtbl->SetArguments(pShellLink, pszTargetargs);
      if (strlen(pszDescription) > 0)
      {
        hRes = pShellLink->lpVtbl->SetDescription(pShellLink, pszDescription);
      }
      if (iShowmode > 0)
      {
        hRes = pShellLink->lpVtbl->SetShowCmd(pShellLink, iShowmode);
      }
      if (strlen(pszCurdir) > 0)
      {
        hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink, pszCurdir);
      }
      if (strlen(pszIconfile) > 0 && iIconindex >= 0)
      {
        hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, pszIconfile, iIconindex);
      }

      /* Use the IPersistFile object to save the shell link */
      hRes = pShellLink->lpVtbl->QueryInterface(pShellLink,        /* existing IShellLink object */
                                                &IID_IPersistFile, /* pre-defined interface of the IPersistFile object */
                                                &pPersistFile);    /* returns a pointer to the IPersistFile object */
      if (SUCCEEDED(hRes))
      {
        iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, pszLinkfile, -1, wszLinkfile, MAX_PATH);
        hRes = pPersistFile->lpVtbl->Save(pPersistFile, wszLinkfile, TRUE);
        pPersistFile->lpVtbl->Release(pPersistFile);
      }
      pShellLink->lpVtbl->Release(pShellLink);
    }

  }
  return (hRes);
}

2 个答案:

答案 0 :(得分:2)

事实证明这很简单。因此,如果您点击此页面,您可能会按照以下说明保存几天: 根据com4j站点中的说明生成shell32.dll的映射: http://com4j.java.net/tutorial.html 然后只需调用以下内容即可创建图标。一旦你知道,这很简单。

IWshShell3 shellLink = ClassFactory.createWshShell();
Com4jObject obj =  shellLink.createShortcut(linkPath.getAbsolutePath());
IWshShortcut link = obj.queryInterface(IWshShortcut.class);
link.workingDirectory(desktopPath.getAbsolutePath());
link.description("My Link");
link.arguments(" Hello ");
link.iconLocation(iconPath.getAbsolutePath());
link.targetPath(javawsPath.getAbsolutePath());
link.setName("Test Link");
link.save();

答案 1 :(得分:0)

我已通过更改GUID将调用修复为CoCreateInstance。下面是代码,它返回OK。但是现在我得到了指针,我不知道如何设置我需要的参数(链接名称,目标名称,desc,图标)。有人有什么建议吗?

GUID rclsid = Ole32Util.getGUIDFromString("{00021401-0000-0000-C000-000000000046}"); //CLSID_ShellLink 
if (W32Errors.FAILED(hr.intValue())) { 
    Ole32.INSTANCE.CoUninitialize(); 
    throw new Exception("Shell Object GUID failed."); 
}       
GUID riid = Ole32Util.getGUIDFromString("{000214EE-0000-0000-C000-000000000046}"); //CLSID of the IShellLink object
PointerByReference ppv = new PointerByReference();
hr = Ole32.INSTANCE.CoCreateInstance(rclsid,null,WTypes.CLSCTX_LOCAL_SERVER,riid,ppv);
if(hr.equals(W32Errors.S_OK)){
    Pointer type = ppv.getValue();

}else{
    System.out.println("Failed to create link error "+hr.intValue());
}