This website uses cookies. By clicking Accept, you consent to the use of cookies. Click Here to learn more about how we use cookies.
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
- Revenera Community
- :
- InstallShield
- :
- InstallShield Forum
- :
- LaunchAppAndWait privilege elevation problem - Error 740 on Vista
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 02, 2007
05:18 AM
LaunchAppAndWait privilege elevation problem - Error 740 on Vista
I am attempting to launch another process using LaunchAppAndWait from within an IS2008 Basic MSI project. However, on Vista, the app fails to launch and the return code from LaunchAppAndWait is 740 - which I believe is ERROR_ELEVATION_REQUIRED. That makes sense since the launched app is another install (I know that nested installs are bad - but this worked before on Vista using IS12).
Is there a way around this problem? - I don't mind another UAC dialog popping up if it has to - I'd just prefer that the system attempted to gain elevated privileges somehow rather than just failing.
Is there a way around this problem? - I don't mind another UAC dialog popping up if it has to - I'd just prefer that the system attempted to gain elevated privileges somehow rather than just failing.
(3) Replies
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jul 02, 2007
10:40 AM
I would suggest using the new LaunchApplication API with the LAAW_OPTION_USE_SHELLEXECUTE flag. This makes it use ShellExecute (which can show UAC prompts) instead of CreateProcess (which won't). Don't forget to fill in the SHELLEXECUTEINFO structure.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Apr 03, 2008
01:39 PM
Hi,
I got problem calling LaunchAppAndWait() on Vista, but it sounds different from the one posted here.
In a Basic MSI project (IS 2008), we call our CA by a dll function, the (C++) function itself calls (c) LaunchAppAndWait(), which I posted the function code here:
/////////////////////////////////////////////////////////////////////////////
int LaunchAppAndWait
(
const char* szProgram, // Executable to be launched with command-line
// parameters.
BOOL bWait, // TRUE = Launch exe and wait until it's done.
// FALSE = Launch exe and continue.
int iShow, // SW_SHOWNORMAL = Normal console window (if applicable).
// SW_HIDE = Launch the program invisibly.
// Other ShowWindow() switches can be used.
int iTimeOut, // Time-out interval, in milliseconds. The function
// returns if the interval elapses, even if the
// launched process is not finished (only if WAIT
// was specified in the third parameter).
// Use INFINITE to wait indefinitely.
ULONG& ulReturn // Returns the result code of the launched program
// (only if bWait = TRUE). If the function returns
// before the launched process is finished (because
// the time-out interval has elapsed) STILL_ACTIVE
// is returned in this parameter.
)
{
STARTUPINFO stStartupInfo;
PROCESS_INFORMATION stProcessInfo;
// Initialize the process structures.
ZeroMemory(&stStartupInfo,sizeof(stStartupInfo));
stStartupInfo.cb = sizeof(stStartupInfo);
stStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
stStartupInfo.wShowWindow = iShow;
ZeroMemory(&stProcessInfo,sizeof(stProcessInfo));
// CreateProcess has difficulties with its first and second arguments. So,
// combine everything and pass it all into the second parameter.
int iLen = strlen(szProgram) + 1;
char* szExe = new char[iLen];
strcpy_s(szExe,iLen,szProgram);
// Start the process.
if (!CreateProcess(0,szExe,0,0,FALSE,0,0,0,&stStartupInfo,&stProcessInfo)) {
// Process didn't start.
if (szExe) delete []szExe;
return -1;
}
// Not waiting for process to end. Set the return codes.
if (!bWait) {
ulReturn = 1;
return 0;
}
// Wait until the process is done, then get the return code.
WaitForSingleObject(stProcessInfo.hProcess,iTimeOut);
GetExitCodeProcess(stProcessInfo.hProcess,&ulReturn);
CloseHandle(stProcessInfo.hProcess);
CloseHandle(stProcessInfo.hThread);
if (szExe) delete []szExe;
return 0;
}
/////////////////////////////////////////////////////////////
And the CA function is:
//////////////////////////////////////////
UINT WINAPI ManagePeernet
(
MSIHANDLE hMSI // Handle to the MSI database.
)
{
int iErr = 0;
ULONG ulReturn = 0;
CString sDestUNCPath(""),sExe(""),sKey(""),sPeerNet(""),sRemove("");
PeernetSetupProps* pPnProps = new PeernetSetupProps(hMSI);
sRemove = pPnProps->m_szRemove;
sPeerNet = pPnProps->m_szPeerNet;
sDestUNCPath = pPnProps->m_szMapDriveUNCPath;
// Check if the Target Directory is a map drive or not.
if (sDestUNCPath != "0") {
// Mapped Drive.
CStrPathAppend(sDestUNCPath,"MyProd\\Peernet\\");
sPeerNet = sDestUNCPath;
}
CString sLog("");
sLog.Format("sPeerNet = %s ",sPeerNet);
LogStr(hMSI,"ManagePeernet",sLog);
// Install Peernet.
// PDF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"pdf\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
//debug
CString sDbg("");
sDbg.Format("iErr=%d, ulReturn=%d", iErr, ulReturn);
LogStr(hMSI, "LaunchAppAndWait return for PDF", sDbg);
// TIFF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"tiff\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
//debug
sDbg.Format("iErr=%d, ulReturn=%d", iErr, ulReturn);
LogStr(hMSI, "LaunchAppAndWait return for tiff", sDbg);
return ERROR_SUCCESS;
}
////////////////////////////////////////////////
The installation worked fine on systems except Vista, here are the installation log results from the above (ManagePeernet) function from a W2K (succeeded to install Peernet) and a Vista (failed to install Peernet):
//////////////////////////////////////////////////////////
from W2K:
----------
Custom Function: PeerNetSetupProps: 0|M:\MyComp\PeerNet\|\\Mylab7112\My_test|
Custom Function: PeernetSetupProps: LogClass
m_szRemove = 0
m_szPeerNet = M:\MyComp\PeerNet\
m_szMapDriveUNCPath = \\Mylab7112\My_test
Custom Function: ManagePeernet: sPeerNet = \\Mylab7112\My_test\MyComp\Peernet\
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\pdf\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=0, ulReturn=0
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\tiff\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=0, ulReturn=0
-----------------------------
from Vista:
-----------
Custom Function: PeerNetSetupProps: 0|M:\MyComp\PeerNet\|\\Mylab7112\My_test|
Custom Function: PeernetSetupProps: LogClass
m_szRemove = 0
m_szPeerNet = M:\MyComp\PeerNet\
m_szMapDriveUNCPath = \\Mylab7112\My_test
Custom Function: ManagePeernet: sPeerNet = \\Mylab7112\My_test\MyComp\Peernet\
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\pdf\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=-1, ulReturn=0
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\tiff\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=-1, ulReturn=0
------------------------------------------------
I am confused that in both cases, the CreateProcess() call failed (ulReturn=0), why is it to W2K (since it succeeded to install peernet)? How can I know what's wrong with Vista (I bet something wrong on CreateProcess() call on Vista?)?
I saw MichaelU suggested to use LaunchApplication on Vista instead of LaunchAppAndWait, how can I do it in my c/c++ code (I have the functions above), can you give some samples?
Thanks,
Peter
I got problem calling LaunchAppAndWait() on Vista, but it sounds different from the one posted here.
In a Basic MSI project (IS 2008), we call our CA by a dll function, the (C++) function itself calls (c) LaunchAppAndWait(), which I posted the function code here:
/////////////////////////////////////////////////////////////////////////////
int LaunchAppAndWait
(
const char* szProgram, // Executable to be launched with command-line
// parameters.
BOOL bWait, // TRUE = Launch exe and wait until it's done.
// FALSE = Launch exe and continue.
int iShow, // SW_SHOWNORMAL = Normal console window (if applicable).
// SW_HIDE = Launch the program invisibly.
// Other ShowWindow() switches can be used.
int iTimeOut, // Time-out interval, in milliseconds. The function
// returns if the interval elapses, even if the
// launched process is not finished (only if WAIT
// was specified in the third parameter).
// Use INFINITE to wait indefinitely.
ULONG& ulReturn // Returns the result code of the launched program
// (only if bWait = TRUE). If the function returns
// before the launched process is finished (because
// the time-out interval has elapsed) STILL_ACTIVE
// is returned in this parameter.
)
{
STARTUPINFO stStartupInfo;
PROCESS_INFORMATION stProcessInfo;
// Initialize the process structures.
ZeroMemory(&stStartupInfo,sizeof(stStartupInfo));
stStartupInfo.cb = sizeof(stStartupInfo);
stStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
stStartupInfo.wShowWindow = iShow;
ZeroMemory(&stProcessInfo,sizeof(stProcessInfo));
// CreateProcess has difficulties with its first and second arguments. So,
// combine everything and pass it all into the second parameter.
int iLen = strlen(szProgram) + 1;
char* szExe = new char[iLen];
strcpy_s(szExe,iLen,szProgram);
// Start the process.
if (!CreateProcess(0,szExe,0,0,FALSE,0,0,0,&stStartupInfo,&stProcessInfo)) {
// Process didn't start.
if (szExe) delete []szExe;
return -1;
}
// Not waiting for process to end. Set the return codes.
if (!bWait) {
ulReturn = 1;
return 0;
}
// Wait until the process is done, then get the return code.
WaitForSingleObject(stProcessInfo.hProcess,iTimeOut);
GetExitCodeProcess(stProcessInfo.hProcess,&ulReturn);
CloseHandle(stProcessInfo.hProcess);
CloseHandle(stProcessInfo.hThread);
if (szExe) delete []szExe;
return 0;
}
/////////////////////////////////////////////////////////////
And the CA function is:
//////////////////////////////////////////
UINT WINAPI ManagePeernet
(
MSIHANDLE hMSI // Handle to the MSI database.
)
{
int iErr = 0;
ULONG ulReturn = 0;
CString sDestUNCPath(""),sExe(""),sKey(""),sPeerNet(""),sRemove("");
PeernetSetupProps* pPnProps = new PeernetSetupProps(hMSI);
sRemove = pPnProps->m_szRemove;
sPeerNet = pPnProps->m_szPeerNet;
sDestUNCPath = pPnProps->m_szMapDriveUNCPath;
// Check if the Target Directory is a map drive or not.
if (sDestUNCPath != "0") {
// Mapped Drive.
CStrPathAppend(sDestUNCPath,"MyProd\\Peernet\\");
sPeerNet = sDestUNCPath;
}
CString sLog("");
sLog.Format("sPeerNet = %s ",sPeerNet);
LogStr(hMSI,"ManagePeernet",sLog);
// Install Peernet.
// PDF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"pdf\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
//debug
CString sDbg("");
sDbg.Format("iErr=%d, ulReturn=%d", iErr, ulReturn);
LogStr(hMSI, "LaunchAppAndWait return for PDF", sDbg);
// TIFF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"tiff\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
//debug
sDbg.Format("iErr=%d, ulReturn=%d", iErr, ulReturn);
LogStr(hMSI, "LaunchAppAndWait return for tiff", sDbg);
return ERROR_SUCCESS;
}
////////////////////////////////////////////////
The installation worked fine on systems except Vista, here are the installation log results from the above (ManagePeernet) function from a W2K (succeeded to install Peernet) and a Vista (failed to install Peernet):
//////////////////////////////////////////////////////////
from W2K:
----------
Custom Function: PeerNetSetupProps: 0|M:\MyComp\PeerNet\|\\Mylab7112\My_test|
Custom Function: PeernetSetupProps: LogClass
m_szRemove = 0
m_szPeerNet = M:\MyComp\PeerNet\
m_szMapDriveUNCPath = \\Mylab7112\My_test
Custom Function: ManagePeernet: sPeerNet = \\Mylab7112\My_test\MyComp\Peernet\
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\pdf\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=0, ulReturn=0
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\tiff\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=0, ulReturn=0
-----------------------------
from Vista:
-----------
Custom Function: PeerNetSetupProps: 0|M:\MyComp\PeerNet\|\\Mylab7112\My_test|
Custom Function: PeernetSetupProps: LogClass
m_szRemove = 0
m_szPeerNet = M:\MyComp\PeerNet\
m_szMapDriveUNCPath = \\Mylab7112\My_test
Custom Function: ManagePeernet: sPeerNet = \\Mylab7112\My_test\MyComp\Peernet\
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\pdf\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=-1, ulReturn=0
Custom Function: ManagePeernet: \\Mylab7112\My_test\MyComp\Peernet\tiff\PNSetup.exe
Custom Function: LaunchAppAndWait return for PDF: iErr=-1, ulReturn=0
------------------------------------------------
I am confused that in both cases, the CreateProcess() call failed (ulReturn=0), why is it to W2K (since it succeeded to install peernet)? How can I know what's wrong with Vista (I bet something wrong on CreateProcess() call on Vista?)?
I saw MichaelU suggested to use LaunchApplication on Vista instead of LaunchAppAndWait, how can I do it in my c/c++ code (I have the functions above), can you give some samples?
Thanks,
Peter
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Apr 03, 2008
06:30 PM
Some updates -
First of all, I think I forgot to mention that our installation environment might be different from others: we run installation on one a mapped drive (say 'M', the drive mapps to a shared folder created on the system) of a system as server, and under the installation there is a 'setup' folder contains another installer to allow clients' installation, the only requirement is that a client needs to create the same mapped drive ('M') to point to the server's shared folder (eg. \\server_system\shared_folder).
My problem (failed on Vista) only happens when: a Vista has different domain/workgroup from the other system(s) AND the Vista is a client (i.e. running setup will try to execute files from drive that is mapped to other machine in different domain/workgroup). The opposite works - if the Vista is installed as server, other non Vista systems (W2K, XP, W2K3, in different domain/workgroup) can install as client without problems.
Now I used 'ShellExecute' instead of LaunchAppAndWait (for Vista only) in my code as following:
////////////////////////////////////////
UINT WINAPI ManagePeernet
(
MSIHANDLE hMSI // Handle to the MSI database.
)
{
int iErr = 0;
ULONG ulReturn = 0;
CString sDestUNCPath(""),sExe(""),sKey(""),sPeerNet(""),sRemove("");
PeernetSetupProps* pPnProps = new PeernetSetupProps(hMSI);
sRemove = pPnProps->m_szRemove;
sPeerNet = pPnProps->m_szPeerNet;
sDestUNCPath = pPnProps->m_szMapDriveUNCPath;
// Check if the Target Directory is a map drive or not.
if (sDestUNCPath != "0") {
// Mapped Drive.
CStrPathAppend(sDestUNCPath,"MyComp\\Peernet\\");
sPeerNet = sDestUNCPath;
}
CString sLog("");
sLog.Format("sPeerNet = %s ",sPeerNet);
LogStr(hMSI,"ManagePeernet",sLog);
CString sOS(""),sSP("");
int iVersion = GetOSInfo(hMSI,sOS,sSP);
//For Vista
SHELLEXECUTEINFO shExecInfo;
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
CString sRunAs("runas");
shExecInfo.fMask = NULL;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = sRunAs;
shExecInfo.lpParameters = NULL;
shExecInfo.lpDirectory = NULL;
shExecInfo.nShow = SW_MAXIMIZE;
shExecInfo.hInstApp = NULL;
if (sRemove != "ALL") {
// Install Peernet.
// PDF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"pdf\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
if (iVersion >= IOsWinVista)
{
shExecInfo.lpFile = sExe;
ShellExecuteEx(&shExecInfo);
}
else
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
// TIFF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"tiff\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
if (iVersion >= IOsWinVista)
{
shExecInfo.lpFile = sExe;
ShellExecuteEx(&shExecInfo);
}
else
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
return ERROR_SUCCESS;
}
/////////////////////////////////////////////////////
Installation on Vista resulted in the attached error messages, which is for authority or credentials, and Peernet drivers are not installed. Anybody knows how to overcome the problems?
I hope somebody there knows what I am saying and doing, and gets clues on the issue(s) I am facing - I am really frustrated to it!
Thanks,
Peter
First of all, I think I forgot to mention that our installation environment might be different from others: we run installation on one a mapped drive (say 'M', the drive mapps to a shared folder created on the system) of a system as server, and under the installation there is a 'setup' folder contains another installer to allow clients' installation, the only requirement is that a client needs to create the same mapped drive ('M') to point to the server's shared folder (eg. \\server_system\shared_folder).
My problem (failed on Vista) only happens when: a Vista has different domain/workgroup from the other system(s) AND the Vista is a client (i.e. running setup will try to execute files from drive that is mapped to other machine in different domain/workgroup). The opposite works - if the Vista is installed as server, other non Vista systems (W2K, XP, W2K3, in different domain/workgroup) can install as client without problems.
Now I used 'ShellExecute' instead of LaunchAppAndWait (for Vista only) in my code as following:
////////////////////////////////////////
UINT WINAPI ManagePeernet
(
MSIHANDLE hMSI // Handle to the MSI database.
)
{
int iErr = 0;
ULONG ulReturn = 0;
CString sDestUNCPath(""),sExe(""),sKey(""),sPeerNet(""),sRemove("");
PeernetSetupProps* pPnProps = new PeernetSetupProps(hMSI);
sRemove = pPnProps->m_szRemove;
sPeerNet = pPnProps->m_szPeerNet;
sDestUNCPath = pPnProps->m_szMapDriveUNCPath;
// Check if the Target Directory is a map drive or not.
if (sDestUNCPath != "0") {
// Mapped Drive.
CStrPathAppend(sDestUNCPath,"MyComp\\Peernet\\");
sPeerNet = sDestUNCPath;
}
CString sLog("");
sLog.Format("sPeerNet = %s ",sPeerNet);
LogStr(hMSI,"ManagePeernet",sLog);
CString sOS(""),sSP("");
int iVersion = GetOSInfo(hMSI,sOS,sSP);
//For Vista
SHELLEXECUTEINFO shExecInfo;
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
CString sRunAs("runas");
shExecInfo.fMask = NULL;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = sRunAs;
shExecInfo.lpParameters = NULL;
shExecInfo.lpDirectory = NULL;
shExecInfo.nShow = SW_MAXIMIZE;
shExecInfo.hInstApp = NULL;
if (sRemove != "ALL") {
// Install Peernet.
// PDF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"pdf\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
if (iVersion >= IOsWinVista)
{
shExecInfo.lpFile = sExe;
ShellExecuteEx(&shExecInfo);
}
else
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
// TIFF driver.
sExe = sPeerNet;
CStrPathAppend(sExe,"tiff\\PNSetup.exe");
LogStr(hMSI,"ManagePeernet",sExe);
if (iVersion >= IOsWinVista)
{
shExecInfo.lpFile = sExe;
ShellExecuteEx(&shExecInfo);
}
else
iErr = LaunchAppAndWait(sExe,TRUE,SW_SHOWNORMAL,INFINITE,ulReturn);
return ERROR_SUCCESS;
}
/////////////////////////////////////////////////////
Installation on Vista resulted in the attached error messages, which is for authority or credentials, and Peernet drivers are not installed. Anybody knows how to overcome the problems?
I hope somebody there knows what I am saying and doing, and gets clues on the issue(s) I am facing - I am really frustrated to it!
Thanks,
Peter
![](/skins/images/A5EADE085F77DE82FB3B14D6B307AE6A/responsive_peak/images/icon_anonymous_message.png)