src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp
branchJDK-8200758-branch
changeset 57413 45c74e654794
child 57909 c7de06ed4b54
equal deleted inserted replaced
57412:02034583f4dc 57413:45c74e654794
       
     1 /*
       
     2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 #include <algorithm>
       
    27 #include "Executor.h"
       
    28 #include "Log.h"
       
    29 #include "WinErrorHandling.h"
       
    30 
       
    31 
       
    32 namespace {
       
    33 
       
    34 void escapeArg(std::wstring& str) {
       
    35     if (str.empty()) {
       
    36         return;
       
    37     }
       
    38 
       
    39     if (str.front() == L'\"' && str.back() == L'\"' && str.size() > 1) {
       
    40         return;
       
    41     }
       
    42 
       
    43     if (str.find_first_of(L" \t") != std::wstring::npos) {
       
    44         str = L'"' + str + L'"';
       
    45     }
       
    46 }
       
    47 
       
    48 } // namespace
       
    49 
       
    50 
       
    51 std::wstring Executor::args() const {
       
    52     tstring_array tmpArgs;
       
    53     // argv[0] is the module name.
       
    54     tmpArgs.push_back(appPath);
       
    55     tmpArgs.insert(tmpArgs.end(), argsArray.begin(), argsArray.end());
       
    56 
       
    57     std::for_each(tmpArgs.begin(), tmpArgs.end(), escapeArg);
       
    58     return tstrings::join(tmpArgs.begin(), tmpArgs.end(), _T(" "));
       
    59 }
       
    60 
       
    61 
       
    62 int Executor::execAndWaitForExit() const {
       
    63     UniqueHandle h = startProcess();
       
    64     
       
    65     const DWORD res = ::WaitForSingleObject(h.get(), INFINITE);
       
    66     if (WAIT_FAILED ==  res) {
       
    67         JP_THROW(SysError("WaitForSingleObject() failed", WaitForSingleObject));
       
    68     }
       
    69 
       
    70     DWORD exitCode = 0;
       
    71     if (!GetExitCodeProcess(h.get(), &exitCode)) {
       
    72         // Error reading process's exit code.
       
    73         JP_THROW(SysError("GetExitCodeProcess() failed", GetExitCodeProcess));
       
    74     }
       
    75 
       
    76     const DWORD processId = GetProcessId(h.get());
       
    77     if (!processId) {
       
    78         JP_THROW(SysError("GetProcessId() failed.", GetProcessId));
       
    79     }
       
    80 
       
    81     LOG_TRACE(tstrings::any() << "Process with PID=" << processId
       
    82                                 << " terminated. Exit code=" << exitCode);
       
    83     
       
    84     return static_cast<int>(exitCode);
       
    85 }
       
    86 
       
    87 
       
    88 UniqueHandle Executor::startProcess() const {
       
    89     const std::wstring argsStr = args();
       
    90 
       
    91     std::vector<TCHAR> argsBuffer(argsStr.begin(), argsStr.end());
       
    92     argsBuffer.push_back(0); // terminating '\0'
       
    93 
       
    94     STARTUPINFO startupInfo;
       
    95     ZeroMemory(&startupInfo, sizeof(startupInfo));
       
    96     startupInfo.cb = sizeof(startupInfo);
       
    97 
       
    98     PROCESS_INFORMATION processInfo;
       
    99     ZeroMemory(&processInfo, sizeof(processInfo));
       
   100 
       
   101     DWORD creationFlags = 0;
       
   102 
       
   103     if (!theVisible) {
       
   104         // For GUI applications.
       
   105         startupInfo.dwFlags |= STARTF_USESHOWWINDOW;
       
   106         startupInfo.wShowWindow = SW_HIDE;
       
   107 
       
   108         // For console applications.
       
   109         creationFlags |= CREATE_NO_WINDOW;
       
   110     }
       
   111 
       
   112     tstrings::any msg;
       
   113     msg << "CreateProcess(" << appPath << ", " << argsStr << ")";
       
   114 
       
   115     if (!CreateProcess(appPath.c_str(), argsBuffer.data(), NULL, NULL, FALSE,
       
   116                     creationFlags, NULL, NULL, &startupInfo, &processInfo)) {
       
   117         msg << " failed";
       
   118         JP_THROW(SysError(msg, CreateProcess));
       
   119     }
       
   120 
       
   121     msg << " succeeded; PID=" << processInfo.dwProcessId;
       
   122     LOG_TRACE(msg);
       
   123 
       
   124     // Close unneeded handles immediately.
       
   125     UniqueHandle(processInfo.hThread);
       
   126 
       
   127     // Return process handle.
       
   128     return UniqueHandle(processInfo.hProcess);
       
   129 }