чацвер, 5 сакавіка 2009 г.

If anybody look for fix for http://bugs.sun.com/view_bug.do?bug_id=4947220
(process) Runtime.exec() cannot invoke applications with unicode parameters (win)
You can try mi fixes:
it`s a wrapper around CreateProcessW with a little bit of process control.


// must match constants at Win32Process class
#define SUCCESS 0
#define CREATE_ERROR 0
#define WAIT_ERROR 1
#define TERMINATE_ERROR 2
#define GET_EXIT_CODE_ERROR 3
#define EXIT_VALUE 4
#define ARRAY_SIZE 5
#define INVALID_VALUE -31

#include
#include "utils_os_windows_SystemUtils.h"
/*
* Class: utils_os_windows_SystemUtils
* Method: createProcess
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jintArray JNICALL Java_utils_os_windows_SystemUtils_createProcessAndWaitInternal
(JNIEnv * env, jobject obj, jstring processCommandLine, jlong millis, jboolean needTerminate) {
    // hold all info about proces state
    jint returnCodesArray[ARRAY_SIZE] = {INVALID_VALUE, INVALID_VALUE, INVALID_VALUE, INVALID_VALUE, INVALID_VALUE};
    jboolean isCopy;
    const jchar *pCommandLine = env->GetStringChars(processCommandLine, &isCopy);

    // make a copy of pCommandLine - CreateProcessW modified it...
    size_t commandLineLength = wcslen((wchar_t *)pCommandLine) + 1;
    wchar_t * muttableCommandLine = new wchar_t[commandLineLength];
    wcscpy_s(muttableCommandLine, commandLineLength, (wchar_t*)pCommandLine);

    // free unused chars
    env->ReleaseStringChars(processCommandLine, pCommandLine);
    // addionalional structures for CreateProcessW
    STARTUPINFOW startupInfo;
    PROCESS_INFORMATION processInfo;
    // fill memory with 0
    ZeroMemory( &startupInfo, sizeof(startupInfo) );
    startupInfo.cb = sizeof(startupInfo);
    ZeroMemory( &processInfo, sizeof(processInfo) );

    // Start the child process.
    if (CreateProcessW( NULL, // No module name (use command line)
                muttableCommandLine, // Command line
                NULL, // Process security attribues
                NULL, // Thread security attribues
                FALSE, // Set handle inheritance to FALSE
                CREATE_NO_WINDOW, // if console program - without console window, else if non-console prog - ignored
                NULL, // Use parent's environment block
                NULL, // Use parent's starting directory
                &startupInfo, // Pointer to STARTUPINFO structure
                &processInfo ) // Pointer to PROCESS_INFORMATION structure
            ) {
        // if successfull
        returnCodesArray[CREATE_ERROR] = SUCCESS;
        // start wait for time
        if (millis > 0) {
            returnCodesArray[WAIT_ERROR] = SUCCESS;
            DWORD waitRetCode = WaitForSingleObject(processInfo.hProcess, (long)millis);
            if ( waitRetCode == WAIT_FAILED) {
                // we have an error
                returnCodesArray[WAIT_ERROR] = GetLastError();
            } else if ( needTerminate ) {

                // do it atomic
                CRITICAL_SECTION criticalSection;
                InitializeCriticalSection(&criticalSection);
                EnterCriticalSection(&criticalSection);
                // first check, if process still alive
                DWORD exitCode;
                if (GetExitCodeProcess(processInfo.hProcess, &exitCode)) {
                    if (exitCode == STILL_ACTIVE) {
                        // if true - terminate it
                        // kill process
                        returnCodesArray[TERMINATE_ERROR] = SUCCESS;
                        if (!TerminateProcess(processInfo.hProcess, 1)) { // 1 - because of origin sources has this value
                            returnCodesArray[TERMINATE_ERROR] = GetLastError();
                            returnCodesArray[EXIT_VALUE] = 1; // value from TerminateProcess
                        }
                    } else {
                        returnCodesArray[EXIT_VALUE] = exitCode;
                    }
                } else {
                    returnCodesArray[GET_EXIT_CODE_ERROR] = GetLastError();
                }
                // leave criticaval section
                LeaveCriticalSection(&criticalSection);
                DeleteCriticalSection(&criticalSection);
            }
        }
        CloseHandle(processInfo.hProcess);
        CloseHandle(processInfo.hThread);
    } else {
        // if unsuccessfull
        returnCodesArray[CREATE_ERROR] = GetLastError();
    }
    // clear up...
    delete[] muttableCommandLine;
    muttableCommandLine = 0;
    // obtain new java int array
    jintArray returnArray = env->NewIntArray(ARRAY_SIZE);
    env->SetIntArrayRegion(returnArray, 0, ARRAY_SIZE, returnCodesArray);
    return returnArray;

}