Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CommandLineToArgvW to Shell32 and corresponding util #1360

Merged
merged 1 commit into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ Features
* [#1336](https://github.com/java-native-access/jna/pull/1336): Add `HKEY_CURRENT_USER_LOCAL_SETTINGS` to `c.s.j.p.win32.WinReg` - [@Dani-Hub](https://github.com/Dani-Hub).
* [#1337](https://github.com/java-native-access/jna/pull/1337): Add `REG_NOTIFY_THREAD_AGNOSTIC` to `c.s.j.p.win32.WinNet` and update `REG_LEGAL_CHANGE_FILTER` - [@Dani-Hub](https://github.com/Dani-Hub).
* [#1338](https://github.com/java-native-access/jna/pull/1338): Add `RegNotifyChangeKeyValue` to `c.s.j.p.win32.Advapi32` - [@Dani-Hub](https://github.com/Dani-Hub).
* [#1340](https://github.com/java-native-access/jna/issues/1340): Added `CM_Get_DevNode_Registry_Property` to `c.s.j.p.win32.Cfgmgr32` and corresponding util in `c.s.j.p.win32.Cfgmgr32Util` - [@dbwiddis](https://github.com/dbwiddis).
* [#1340](https://github.com/java-native-access/jna/issues/1340): Add `CM_Get_DevNode_Registry_Property` to `c.s.j.p.win32.Cfgmgr32` and corresponding util in `c.s.j.p.win32.Cfgmgr32Util` - [@dbwiddis](https://github.com/dbwiddis).
* [#1352](https://github.com/java-native-access/jna/pull/1352): Add `BringWindowToTop` to `c.s.j.p.win32.User32` - [@kahgoh](https://github.com/kahgoh).
* [#1354](https://github.com/java-native-access/jna/pull/1352): Add `GetParent` to `c.s.j.p.win32.User32` - [@kahgoh](https://github.com/kahgoh).
* [#1360](https://github.com/java-native-access/jna/issues/1360): Add `CommandLineToArgvW` to `c.s.j.p.win32.Shell32` and corresponding util in `c.s.j.p.win32.Shell32Util` - [@dbwiddis](https://github.com/dbwiddis).

Bug Fixes
---------
Expand Down
26 changes: 26 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Shell32.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@
package com.sun.jna.platform.win32;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.WTypes.LPWSTR;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HICON;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.INT_PTR;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
Expand Down Expand Up @@ -409,5 +412,28 @@ public interface Shell32 extends ShellAPI, StdCallLibrary {
*/
HRESULT SetCurrentProcessExplicitAppUserModelID(WString appID);

/**
* Parses a Unicode command line string and returns an array of pointers to the
* command line arguments, along with a count of such arguments, in a way that
* is similar to the standard C run-time {@code argv} and {@code argc} values.
*
* @param lpCmdLine
* A Unicode string that contains the full command line. If this
* parameter is an empty string the function returns the path to the
* current executable file.
* @param pNumArgs
* Pointer to an {@code int} that receives the number of array
* elements returned, similar to {@code argc}.
* @return A pointer to an array of {@link LPWSTR} values, similar to
* {@code argv}. If the function fails, the return value is
* {@code null}. To get extended error information, call
* {@link Kernel32#GetLastError}. <br>
* CommandLineToArgvW allocates a block of contiguous memory for
* pointers to the argument strings, and for the argument strings
* themselves; the calling application must free the memory used by the
* argument list when it is no longer needed. To free the memory, use a
* single call to the {@link Kernel32#LocalFree} function.
*/
Pointer CommandLineToArgvW(WString lpCmdLine, IntByReference pNumArgs);
}

27 changes: 27 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Shell32Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
package com.sun.jna.platform.win32;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

/**
Expand Down Expand Up @@ -112,4 +115,28 @@ public static final String getSpecialFolderPath(final int csidl, final boolean c
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
return Native.toString(pszPath);
}

/**
* Parses a command line string and returns an array of Strings of the command
* line arguments.
*
* @param cmdLine
* A string that contains the full command line. If this parameter is
* an empty string the function returns the path to the current
* executable file.
* @return An array of strings, similar to {@code argv}.
*/
public static final String[] CommandLineToArgv(String cmdLine) {
WString cl = new WString(cmdLine);
IntByReference nargs = new IntByReference();
Pointer strArr = Shell32.INSTANCE.CommandLineToArgvW(cl, nargs);
if (strArr != null) {
try {
return strArr.getWideStringArray(0, nargs.getValue());
} finally {
Kernel32.INSTANCE.LocalFree(strArr);
}
}
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
*/
package com.sun.jna.platform.win32;

import static org.junit.Assert.assertArrayEquals;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.ShellAPI.APPBARDATA;
Expand All @@ -36,11 +39,11 @@
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

import junit.framework.TestCase;


/**
* @author dblock[at]dblock[dot]org
* @author markus[at]headcrashing[dot]eu
Expand Down Expand Up @@ -260,4 +263,16 @@ public void testCurrentProcessExplicitAppUserModelID() {
Ole32.INSTANCE.CoTaskMemFree(ppszAppID.getValue());
}

public void testCommandLineToArgvW() {
WString cl = new WString("\"foo bar\" baz");
String[] argv = { "foo bar", "baz" };
IntByReference nargs = new IntByReference();
Pointer strArr = Shell32.INSTANCE.CommandLineToArgvW(cl, nargs);
assertNotNull(strArr);
try {
assertArrayEquals(argv, strArr.getWideStringArray(0, nargs.getValue()));
} finally {
Kernel32.INSTANCE.LocalFree(strArr);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*/
package com.sun.jna.platform.win32;

import static org.junit.Assert.assertArrayEquals;

import junit.framework.TestCase;

/**
Expand Down Expand Up @@ -85,4 +87,10 @@ public void testGetKnownFolderPath()
// assertNotNull(Shell32Util.getKnownFolderPath(KnownFolders.FOLDERID_UserProgramFiles));
// assertNotNull(Shell32Util.getKnownFolderPath(KnownFolders.FOLDERID_UserProgramFilesCommon));
}

public void testCommandLineToArgv() {
String cl = "\"foo bar\" baz";
String[] argv = { "foo bar", "baz" };
assertArrayEquals(argv, Shell32Util.CommandLineToArgv(cl));
}
}