mirror of https://github.com/python/cpython
#2581: Vista UAC/elevation support for bdist_wininst
This commit is contained in:
parent
f8cc64017c
commit
7c5c8e6823
|
@ -426,6 +426,13 @@ built-in functions in the installation script.
|
||||||
also the configuration. For details refer to Microsoft's documentation of the
|
also the configuration. For details refer to Microsoft's documentation of the
|
||||||
:cfunc:`SHGetSpecialFolderPath` function.
|
:cfunc:`SHGetSpecialFolderPath` function.
|
||||||
|
|
||||||
|
Vista User Access Control (UAC)
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Starting with Python 2.6, bdist_wininst supports a :option:`--user-access-control`
|
||||||
|
option. The default is 'none' (meaning no UAC handling is done), and other
|
||||||
|
valid values are 'auto' (meaning prompt for UAC elevation if Python was
|
||||||
|
installed for all users) and 'force' (meaning always prompt for elevation)
|
||||||
|
|
||||||
.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])
|
.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])
|
||||||
|
|
||||||
|
@ -437,5 +444,3 @@ built-in functions in the installation script.
|
||||||
and *iconindex* is the index of the icon in the file *iconpath*. Again, for
|
and *iconindex* is the index of the icon in the file *iconpath*. Again, for
|
||||||
details consult the Microsoft documentation for the :class:`IShellLink`
|
details consult the Microsoft documentation for the :class:`IShellLink`
|
||||||
interface.
|
interface.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,10 @@ class bdist_wininst (Command):
|
||||||
"Fully qualified filename of a script to be run before "
|
"Fully qualified filename of a script to be run before "
|
||||||
"any files are installed. This script need not be in the "
|
"any files are installed. This script need not be in the "
|
||||||
"distribution"),
|
"distribution"),
|
||||||
|
('user-access-control=', None,
|
||||||
|
"specify Vista's UAC handling - 'none'/default=no "
|
||||||
|
"handling, 'auto'=use UAC if target Python installed for "
|
||||||
|
"all users, 'force'=always use UAC"),
|
||||||
]
|
]
|
||||||
|
|
||||||
boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
|
boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
|
||||||
|
@ -68,6 +72,7 @@ class bdist_wininst (Command):
|
||||||
self.skip_build = 0
|
self.skip_build = 0
|
||||||
self.install_script = None
|
self.install_script = None
|
||||||
self.pre_install_script = None
|
self.pre_install_script = None
|
||||||
|
self.user_access_control = None
|
||||||
|
|
||||||
# initialize_options()
|
# initialize_options()
|
||||||
|
|
||||||
|
@ -220,6 +225,8 @@ class bdist_wininst (Command):
|
||||||
lines.append("target_optimize=%d" % (not self.no_target_optimize))
|
lines.append("target_optimize=%d" % (not self.no_target_optimize))
|
||||||
if self.target_version:
|
if self.target_version:
|
||||||
lines.append("target_version=%s" % self.target_version)
|
lines.append("target_version=%s" % self.target_version)
|
||||||
|
if self.user_access_control:
|
||||||
|
lines.append("user_access_control=%s" % self.user_access_control)
|
||||||
|
|
||||||
title = self.title or self.distribution.get_fullname()
|
title = self.title or self.distribution.get_fullname()
|
||||||
lines.append("title=%s" % escape(title))
|
lines.append("title=%s" % escape(title))
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -594,14 +594,25 @@ class MSVCCompiler(CCompiler) :
|
||||||
# needed! Make sure they are generated in the temporary build
|
# needed! Make sure they are generated in the temporary build
|
||||||
# directory. Since they have different names for debug and release
|
# directory. Since they have different names for debug and release
|
||||||
# builds, they can go into the same directory.
|
# builds, they can go into the same directory.
|
||||||
|
build_temp = os.path.dirname(objects[0])
|
||||||
if export_symbols is not None:
|
if export_symbols is not None:
|
||||||
(dll_name, dll_ext) = os.path.splitext(
|
(dll_name, dll_ext) = os.path.splitext(
|
||||||
os.path.basename(output_filename))
|
os.path.basename(output_filename))
|
||||||
implib_file = os.path.join(
|
implib_file = os.path.join(
|
||||||
os.path.dirname(objects[0]),
|
build_temp,
|
||||||
self.library_filename(dll_name))
|
self.library_filename(dll_name))
|
||||||
ld_args.append ('/IMPLIB:' + implib_file)
|
ld_args.append ('/IMPLIB:' + implib_file)
|
||||||
|
|
||||||
|
# Embedded manifests are recommended - see MSDN article titled
|
||||||
|
# "How to: Embed a Manifest Inside a C/C++ Application"
|
||||||
|
# (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
|
||||||
|
# Ask the linker to generate the manifest in the temp dir, so
|
||||||
|
# we can embed it later.
|
||||||
|
temp_manifest = os.path.join(
|
||||||
|
build_temp,
|
||||||
|
os.path.basename(output_filename) + ".manifest")
|
||||||
|
ld_args.append('/MANIFESTFILE:' + temp_manifest)
|
||||||
|
|
||||||
if extra_preargs:
|
if extra_preargs:
|
||||||
ld_args[:0] = extra_preargs
|
ld_args[:0] = extra_preargs
|
||||||
if extra_postargs:
|
if extra_postargs:
|
||||||
|
@ -613,6 +624,18 @@ class MSVCCompiler(CCompiler) :
|
||||||
except DistutilsExecError as msg:
|
except DistutilsExecError as msg:
|
||||||
raise LinkError(msg)
|
raise LinkError(msg)
|
||||||
|
|
||||||
|
# embed the manifest
|
||||||
|
# XXX - this is somewhat fragile - if mt.exe fails, distutils
|
||||||
|
# will still consider the DLL up-to-date, but it will not have a
|
||||||
|
# manifest. Maybe we should link to a temp file? OTOH, that
|
||||||
|
# implies a build environment error that shouldn't go undetected.
|
||||||
|
mfid = 1 if target_desc == CCompiler.EXECUTABLE else 2
|
||||||
|
out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
|
||||||
|
try:
|
||||||
|
self.spawn(['mt.exe', '-nologo', '-manifest',
|
||||||
|
temp_manifest, out_arg])
|
||||||
|
except DistutilsExecError as msg:
|
||||||
|
raise LinkError(msg)
|
||||||
else:
|
else:
|
||||||
log.debug("skipping %s (up-to-date)", output_filename)
|
log.debug("skipping %s (up-to-date)", output_filename)
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ Extension Modules
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #2581: distutils: Vista UAC/elevation support for bdist_wininst
|
||||||
|
|
||||||
- Issue #2635: Fix bug in 'fix_sentence_endings' textwrap.fill option,
|
- Issue #2635: Fix bug in 'fix_sentence_endings' textwrap.fill option,
|
||||||
where an extra space was added after a word containing (but not
|
where an extra space was added after a word containing (but not
|
||||||
ending in) '.', '!' or '?'.
|
ending in) '.', '!' or '?'.
|
||||||
|
|
|
@ -133,6 +133,7 @@ char meta_name[80]; /* package name without version like
|
||||||
char install_script[MAX_PATH];
|
char install_script[MAX_PATH];
|
||||||
char *pre_install_script; /* run before we install a single file */
|
char *pre_install_script; /* run before we install a single file */
|
||||||
|
|
||||||
|
char user_access_control[10]; // one of 'auto', 'force', otherwise none.
|
||||||
|
|
||||||
int py_major, py_minor; /* Python version selected for installation */
|
int py_major, py_minor; /* Python version selected for installation */
|
||||||
|
|
||||||
|
@ -344,8 +345,15 @@ struct PyMethodDef {
|
||||||
};
|
};
|
||||||
typedef struct PyMethodDef PyMethodDef;
|
typedef struct PyMethodDef PyMethodDef;
|
||||||
|
|
||||||
|
// XXX - all of these are potentially fragile! We load and unload
|
||||||
|
// the Python DLL multiple times - so storing functions pointers
|
||||||
|
// is dangerous (although things *look* OK at present)
|
||||||
|
// Better might be to roll prepare_script_environment() into
|
||||||
|
// LoadPythonDll(), and create a new UnloadPythonDLL() which also
|
||||||
|
// clears the global pointers.
|
||||||
void *(*g_Py_BuildValue)(char *, ...);
|
void *(*g_Py_BuildValue)(char *, ...);
|
||||||
int (*g_PyArg_ParseTuple)(PyObject *, char *, ...);
|
int (*g_PyArg_ParseTuple)(PyObject *, char *, ...);
|
||||||
|
PyObject * (*g_PyLong_FromVoidPtr)(void *);
|
||||||
|
|
||||||
PyObject *g_PyExc_ValueError;
|
PyObject *g_PyExc_ValueError;
|
||||||
PyObject *g_PyExc_OSError;
|
PyObject *g_PyExc_OSError;
|
||||||
|
@ -597,7 +605,7 @@ static PyObject *PyMessageBox(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
static PyObject *GetRootHKey(PyObject *self)
|
static PyObject *GetRootHKey(PyObject *self)
|
||||||
{
|
{
|
||||||
return g_Py_BuildValue("l", hkey_root);
|
return g_PyLong_FromVoidPtr(hkey_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define METH_VARARGS 0x0001
|
#define METH_VARARGS 0x0001
|
||||||
|
@ -631,6 +639,8 @@ static HINSTANCE LoadPythonDll(char *fname)
|
||||||
"SOFTWARE\\Python\\PythonCore\\%d.%d\\InstallPath",
|
"SOFTWARE\\Python\\PythonCore\\%d.%d\\InstallPath",
|
||||||
py_major, py_minor);
|
py_major, py_minor);
|
||||||
if (ERROR_SUCCESS != RegQueryValue(HKEY_CURRENT_USER, subkey_name,
|
if (ERROR_SUCCESS != RegQueryValue(HKEY_CURRENT_USER, subkey_name,
|
||||||
|
fullpath, &size) &&
|
||||||
|
ERROR_SUCCESS != RegQueryValue(HKEY_LOCAL_MACHINE, subkey_name,
|
||||||
fullpath, &size))
|
fullpath, &size))
|
||||||
return NULL;
|
return NULL;
|
||||||
strcat(fullpath, "\\");
|
strcat(fullpath, "\\");
|
||||||
|
@ -648,6 +658,7 @@ static int prepare_script_environment(HINSTANCE hPython)
|
||||||
DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
|
DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
|
||||||
DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
|
DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
|
||||||
DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
|
DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
|
||||||
|
DECLPROC(hPython, PyObject *, PyLong_FromVoidPtr, (void *));
|
||||||
if (!PyImport_ImportModule || !PyObject_GetAttrString ||
|
if (!PyImport_ImportModule || !PyObject_GetAttrString ||
|
||||||
!PyObject_SetAttrString || !PyCFunction_New)
|
!PyObject_SetAttrString || !PyCFunction_New)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -667,6 +678,7 @@ static int prepare_script_environment(HINSTANCE hPython)
|
||||||
g_Py_BuildValue = Py_BuildValue;
|
g_Py_BuildValue = Py_BuildValue;
|
||||||
g_PyArg_ParseTuple = PyArg_ParseTuple;
|
g_PyArg_ParseTuple = PyArg_ParseTuple;
|
||||||
g_PyErr_Format = PyErr_Format;
|
g_PyErr_Format = PyErr_Format;
|
||||||
|
g_PyLong_FromVoidPtr = PyLong_FromVoidPtr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -777,7 +789,9 @@ static int run_simple_script(char *script)
|
||||||
|
|
||||||
hPython = LoadPythonDll(pythondll);
|
hPython = LoadPythonDll(pythondll);
|
||||||
if (!hPython) {
|
if (!hPython) {
|
||||||
set_failure_reason("Can't load Python for pre-install script");
|
char reason[128];
|
||||||
|
wsprintf(reason, "Can't load Python for pre-install script (%d)", GetLastError());
|
||||||
|
set_failure_reason(reason);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rc = do_run_simple_script(hPython, script);
|
rc = do_run_simple_script(hPython, script);
|
||||||
|
@ -2073,6 +2087,71 @@ void RunWizard(HWND hwnd)
|
||||||
PropertySheet(&psh);
|
PropertySheet(&psh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subtly different from HasLocalMachinePrivs(), in that after executing
|
||||||
|
// an 'elevated' process, we expect this to return TRUE - but there is no
|
||||||
|
// such implication for HasLocalMachinePrivs
|
||||||
|
BOOL MyIsUserAnAdmin()
|
||||||
|
{
|
||||||
|
typedef BOOL (WINAPI *PFNIsUserAnAdmin)();
|
||||||
|
static PFNIsUserAnAdmin pfnIsUserAnAdmin = NULL;
|
||||||
|
HMODULE shell32;
|
||||||
|
// This function isn't guaranteed to be available (and it can't hurt
|
||||||
|
// to leave the library loaded)
|
||||||
|
if (0 == (shell32=LoadLibrary("shell32.dll")))
|
||||||
|
return FALSE;
|
||||||
|
if (0 == (pfnIsUserAnAdmin=(PFNIsUserAnAdmin)GetProcAddress(shell32, "IsUserAnAdmin")))
|
||||||
|
return FALSE;
|
||||||
|
return (*pfnIsUserAnAdmin)();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some magic for Vista's UAC. If there is a target_version, and
|
||||||
|
// if that target version is installed in the registry under
|
||||||
|
// HKLM, and we are not current administrator, then
|
||||||
|
// re-execute ourselves requesting elevation.
|
||||||
|
// Split into 2 functions - "should we elevate" and "spawn elevated"
|
||||||
|
|
||||||
|
// Returns TRUE if we should spawn an elevated child
|
||||||
|
BOOL NeedAutoUAC()
|
||||||
|
{
|
||||||
|
HKEY hk;
|
||||||
|
char key_name[80];
|
||||||
|
OSVERSIONINFO winverinfo;
|
||||||
|
winverinfo.dwOSVersionInfoSize = sizeof(winverinfo);
|
||||||
|
// If less than XP, then we can't do it (and its not necessary).
|
||||||
|
if (!GetVersionEx(&winverinfo) || winverinfo.dwMajorVersion < 5)
|
||||||
|
return FALSE;
|
||||||
|
// no Python version info == we can't know yet.
|
||||||
|
if (target_version[0] == '\0')
|
||||||
|
return FALSE;
|
||||||
|
// see how python is current installed
|
||||||
|
wsprintf(key_name,
|
||||||
|
"Software\\Python\\PythonCore\\%s\\InstallPath",
|
||||||
|
target_version);
|
||||||
|
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||||
|
key_name, 0, KEY_READ, &hk))
|
||||||
|
return FALSE;
|
||||||
|
RegCloseKey(hk);
|
||||||
|
// Python is installed in HKLM - we must elevate.
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn ourself as an elevated application. On failure, a message is
|
||||||
|
// displayed to the user - but this app will always terminate, even
|
||||||
|
// on error.
|
||||||
|
void SpawnUAC()
|
||||||
|
{
|
||||||
|
// interesting failure scenario that has been seen: initial executable
|
||||||
|
// runs from a network drive - but once elevated, that network share
|
||||||
|
// isn't seen, and ShellExecute fails with SE_ERR_ACCESSDENIED.
|
||||||
|
int ret = (int)ShellExecute(0, "runas", modulename, "", NULL,
|
||||||
|
SW_SHOWNORMAL);
|
||||||
|
if (ret <= 32) {
|
||||||
|
char msg[128];
|
||||||
|
wsprintf(msg, "Failed to start elevated process (ShellExecute returned %d)", ret);
|
||||||
|
MessageBox(0, msg, "Setup", MB_OK | MB_ICONERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int DoInstall(void)
|
int DoInstall(void)
|
||||||
{
|
{
|
||||||
char ini_buffer[4096];
|
char ini_buffer[4096];
|
||||||
|
@ -2106,6 +2185,31 @@ int DoInstall(void)
|
||||||
install_script, sizeof(install_script),
|
install_script, sizeof(install_script),
|
||||||
ini_file);
|
ini_file);
|
||||||
|
|
||||||
|
GetPrivateProfileString("Setup", "user_access_control", "",
|
||||||
|
user_access_control, sizeof(user_access_control), ini_file);
|
||||||
|
|
||||||
|
// See if we need to do the Vista UAC magic.
|
||||||
|
if (strcmp(user_access_control, "force")==0) {
|
||||||
|
if (!MyIsUserAnAdmin()) {
|
||||||
|
SpawnUAC();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// already admin - keep going
|
||||||
|
} else if (strcmp(user_access_control, "auto")==0) {
|
||||||
|
// Check if it looks like we need UAC control, based
|
||||||
|
// on how Python itself was installed.
|
||||||
|
if (!MyIsUserAnAdmin() && NeedAutoUAC()) {
|
||||||
|
SpawnUAC();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// display a warning about unknown values - only the developer
|
||||||
|
// of the extension will see it (until they fix it!)
|
||||||
|
if (user_access_control[0] && strcmp(user_access_control, "none") != 0) {
|
||||||
|
MessageBox(GetFocus(), "Bad user_access_control value", "oops", MB_OK);
|
||||||
|
// nothing to do.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hwndMain = CreateBackground(title);
|
hwndMain = CreateBackground(title);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="1"
|
Optimization="1"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\Include,..\..\..\zlib-1.2.1"
|
AdditionalIncludeDirectories="..\..\Include,..\..\..\zlib-1.2.3"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||||
StringPooling="TRUE"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comctl32.lib"
|
AdditionalDependencies="..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comctl32.lib"
|
||||||
OutputFile="..\..\lib\distutils\command/wininst-7.1.exe"
|
OutputFile="..\..\lib\distutils\command/wininst-7.1.exe"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
|
|
|
@ -43,7 +43,7 @@ RSC=rc.exe
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /O1 /I "..\..\Include" /I "..\..\..\zlib-1.2.1" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /O1 /I "..\..\Include" /I "..\..\..\zlib-1.2.3" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x407 /d "NDEBUG"
|
# ADD BASE RSC /l 0x407 /d "NDEBUG"
|
||||||
|
@ -53,7 +53,7 @@ BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||||
# ADD LINK32 ..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.exe"
|
# ADD LINK32 ..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.0.exe"
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "wininst - Win32 Debug"
|
!ELSEIF "$(CFG)" == "wininst - Win32 Debug"
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 ..\..\..\zlib-1.2.1\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6_d.exe"
|
# ADD LINK32 ..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.0_d.exe"
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue