summaryrefslogtreecommitdiffstats
BranchCommit messageAuthorAge
8_5_with_8_6_regexpMinor clean-ups (e.g. turn back const -> CONST, as common in 8.5 branch)jan.nijtmans9 years
Coverity_CID_1251203Fix the documentation comment.dkf9 years
ISC_peepholemerge trunkmig12 years
activestate_nre_excised_variant_1_roll_forwardwhile 'info' is destroyed and becoms inaccessible after TclEvalObjEx.andreask14 years
activestate_nre_excised_variant_2_subtractedThe re-creation of this branch should have deleted a few NRE specific testsui...andreask14 years
adjust_fixPatch to the original line continuation commit to fix up TclCompileTokens.dgp11 years
ajuba_ajuba2_2_0_syntheticCreated branch ajuba-ajuba2-2-0-syntheticcvs2fossil24 years
ajuba_ajuba2_2_1_base_syntheticCreated branch ajuba-ajuba2-2-1-base-syntheticcvs2fossil24 years
aku_mem_debug_allow_regularMinor compilation issue fix, make sure variable declaration (via macro) is fi...Joe Mistachkin9 years
aku_reviewDocs for Tcl_CreateChannelHandler() state that the registered handler procdgp10 years
aku_tip_280_cl_perf_trialMerge to feature branchdkf13 years
aku_tkt_6141c15186Update to trunk workaku9 years
amg_array_enum_c_apiCheck in stash. This code probably does not compile as-is. Changes intended...andy7 years
amg_string_insertSimplify implementation of non-bytecoded [string replace]andy7 years
androwishmerge zipfsjan.nijtmans7 years
apn_hash_optSome cleanup of style issues.dkf10 years
array_search_unsetReference ticket number in tests var-13.2 and var-13.3andy8 years
aspect_async_pipedon't panic when EAGAIN - if the pipe is full, we have to drop the messageaspect8 years
aspect_bug_391bc0fd2cglob for hidden files on unix should not require stat()aspect7 years
aspect_lreplace_cleanup[47ac84309b] Import of aspect's branch from his personal repository on chisel...dkf8 years
aspect_lreplace_fixundo erroneous change in [1fa2e32e07]aspect10 years
aspect_lreplace_refixlreplace: more tests, doc improvementaspect9 years
aspect_shimmer_singleton_listsadd some tests for singleton list optimisation [738900]aspect8 years
aspect_string_matchfix advancement of snext: could not cook up a test for this, but the error i...aspect7 years
aspect_tip288Taking a stab at TIP#288 implementation.aspect7 years
avl_strcat_fixStop trimming on first non empty-string.avl7 years
avl_tip_282restrictions on array index confined to lhs.avl8 years
backout_memaccounting(just an experiment, don't look ....) Backout the contributed patch memaccoun...jan.nijtmans9 years
bch_coveritymerge [e11d223695c5468b1bfb3db35ebf54856501fdf0], specifically for ./generic/...bch10 years
better_deprecationmerge trunkjan.nijtmans12 years
better_deprecation_85merge core-8-5-branch.jan.nijtmans12 years
bg_tip_282merge trunkdgp8 years
bsg_0d_radix_prefixMerge core-8-6-branchjan.nijtmans7 years
bug3036566Corrected args -> arg arg ... in msgcat docoehhar11 years
bug_010f4162efAdd test and improve errorInfo.dgp11 years
bug_0520d17284fix chan leak with http keepalive vs close (bug [0520d17284])aspect8 years
bug_05489ce335Backout failed attempt to fix [32ae34e63a].dgp9 years
bug_0b874c344dmerge trunkdgp11 years
bug_0b874c344d_ak_info_frame_coroModified info frame's coro handling to allow for a caller coro without cmdFra...andreask11 years
bug_0b8c387cf7Merge trunk. jan.nijtmans9 years
bug_0c043a175test and fix (thx dgp)Miguel Sofer10 years
bug_0e4d88b650merge 8.5dgp7 years
bug_0f42ff7871Added contributed tests from aspectdgp9 years
bug_11892931189293 Make '<<' redirects binary safe. Don't use strlen() (or equivalent)dgp12 years
bug_1224888Added better way to find executable name on OSX.dkf10 years
bug_12b0997ce7[12b0997ce7] Plug memleak in iocmd.tf-32.0 .dgp10 years
bug_13d3af3ad5 * Give clearer names to some of the state flags and sync them with Windows...max10 years
bug_13d3af3ad5_forkRemove writable shortcut and errorneous workaround to get [connect -async] fa...oehhar11 years
bug_1493a43044Expose the AVOID_RESOLVERS flag to [namespace upvar] implementations, which s...dkf8 years
bug_1536227Cygwin network pathname supportjan.nijtmans12 years
bug_16828b3744Merge tip of core-8-6-branchdgp8 years
bug_1712098rebasejan.nijtmans11 years
bug_1758a0b603merge 8.5dgp10 years
bug_1a25fdfec6Simple change gets most of the effect. Fails to handle backslash. anyone care?dgp9 years
bug_1b0266d8bbSome more cleaning updkf10 years
bug_2152292ChangeLog entrydkf11 years
bug_219866c1e9proposed fix for [219866c1e9]: platform::identify: regexp doesn't match platformjan.nijtmans9 years
bug_2413550Changed position of flag evaluation as proposed by Phil Hoffmanoehhar11 years
bug_2502002New internal eval flag value so that all TclNREvalObjv() callers thatdgp11 years
bug_25842c161fMight as well number tests more conventionally.dkf8 years
bug_272e866f1eremove some dead codedkf11 years
bug_2902268Backport 2902268 fix.dgp13 years
bug_2911139Now really fix test-case http-4.14jan.nijtmans12 years
bug_2992970[2992970] Restore the safety of Tcl_AppendObjToObj(x, x) for bytearrays.dgp11 years
bug_2a94652ee1http state 100 continue handling broken [2a94652ee1]oehhar7 years
bug_2f7cbd01c3Proposed fix for [2f7cbd01c3].jan.nijtmans11 years
bug_2f9df4c4faprevious commit was not quite right, this one should be betterjan.nijtmans10 years
bug_3024359Simplify bug fix so that active claims on the FilesystemRecord list of a threaddgp12 years
bug_3033307very minor style tweaksdkf12 years
bug_3092089new attempt for better fixjan.nijtmans12 years
bug_3154ea2759Bug fix. Have to arrange to only close a catch once. After the spacedgp8 years
bug_31661d2135[31661d2135] Plug memory leak.dgp11 years
bug_3173086Completed patch with mucho comments. Merge 8.5.dgp13 years
bug_3185407Merge from 8.5 branch tipdkf13 years
bug_3202171 * generic/tclNamesp.c: Tighten the detector of nested [namespace code] dgp14 years
bug_3216070bug-3216070jan.nijtmans14 years
bug_3288345[bug-3288345] Wrong Tcl_StatBuf used on Cygwinjan.nijtmans13 years
bug_3293874Rewind from a refactoring that veered into the weeds.dgp13 years
bug_32ae34e63aUpdate tests to account for changed ReflectWatch behavior.dgp9 years
bug_3362446remove some unused codejan.nijtmans12 years
bug_336441ed59Try not to loose FD_CONNECT by switching monitoring off.oehhar10 years
bug_3365156Remove stray refcount bump that caused a memory leak.dkf13 years
bug_3389764Proposed fix for 3389764. Have "path" dup routine duplicate the pattern dgp13 years
bug_33920703392070 More complete prevention of Tcl_Obj reference cycles dgp13 years
bug_3397515Prevent segfaults attempting to use thread maps after they've been deleted.dgp13 years
bug_3401704Use better 'isalnum' predicate ; add test case.ferrieux13 years
bug_3413857Test harness for Tcl_ParseArgsObjvdkf13 years
bug_3414754Purge the old, buggy implementation.dgp13 years
bug_3418547merge trunkdgp8 years
bug_3466099Added source test with utf-8 (without -encoding param), remove too many same ...sebres13 years
bug_3475569yank back debugging codedgp13 years
bug_34805993480599 Make [source] and [load] order of multi-file package happen in sorteddgp13 years
bug_34844023484402 Correct Off-By-One error appending unicode. Thanks to Poor Yorick.dgp13 years
bug_3485833Style guide and tidying up.dgp13 years
bug_3493120*nix segfault cleared: we should reset a thread key after freeing of alloc ca...sebres10 years
bug_3496014[Bug 3496014]: Unecessary memset() in Tcl_SetByteArrayObj()jan.nijtmans12 years
bug_3508771first working version of Cygwin notifierjan.nijtmans12 years
bug_3511806now ready for further field testsjan.nijtmans12 years
bug_3514475[Bug 3514475]: remove TclpGetTimeZone and TclpGetTZNamejan.nijtmans12 years
bug_3519357Do filesystem tests needing /tmp access in a subdir less likely to conflict.dgp12 years
bug_3522560Explicitly declare a channel nonblocking before throwing EAGAIN on write.ferrieux12 years
bug_3525762explicitely specify encoding in DdeCreateStringHandlejan.nijtmans12 years
bug_3525907Use zero-delays instead of finite ones when posting fileevents, because (1) t...ferrieux12 years
bug_3530536two more testcases, showing that only the "deflate" and "inflate" streams don...jan.nijtmans12 years
bug_3532959Revised so that we avoid hashing twice.dgp12 years
bug_3536888translate script parameters for msgcatjan.nijtmans12 years
bug_3544685Fix for 3544685: Threaded build failures on OpenBSD-currentjan.nijtmans12 years
bug_3545363merge trunkdkf12 years
bug_3555001Safer stale config fix for review.dgp12 years
bug_3562640merge core-8-4-branchjan.nijtmans11 years
bug_3562640_altAlternative fix for bug-3562640jan.nijtmans12 years
bug_35647353564735 Protection against namespace var resolvers that unexpectedly returndgp12 years
bug_3566106contributed patch for Solaris 9/x86 supportdgp12 years
bug_3567063merge 8.4dgp12 years
bug_3588687merge trunkdgp12 years
bug_3592747Fix [tailcall] and [yieldto] to not panic in dying namespaces: [Bug 3592747]mig12 years
bug_3598300Proposed solution for Bug 3598300 on MacOSXjan.nijtmans12 years
bug_3598580For Tcl9, do a real Tcl_DecrRefCountjan.nijtmans12 years
bug_3599789Bug 3599789: Proposed fix by Serg G. Bresterjan.nijtmans12 years
bug_3600057merge markdkf11 years
bug_3600057_85*BACKPORT* [3600057]: Filled out missing parts of implementation of [string i...dkf11 years
bug_3600058_tdMerge to fix accidental fork in branch bug-3600058-tdtwylite10 years
bug_3600328merge trunkdkf12 years
bug_3601260merge core-8-5-branchjan.nijtmans12 years
bug_3602706Cherrypick again. Add test.dgp12 years
bug_3603434Fix for Bug 3603434.dgp12 years
bug_3603553Correction to comment in re key buffer size.dkf12 years
bug_3603695Apply a fix for the bug. Passes the test suite now.dkf12 years
bug_3604074New branch bug-3604074 with improved patch to correct fixempties() failuredgp12 years
bug_3604576Finer granulated catchoehhar12 years
bug_3605401[Bug 3605401]: Compiler error with latest mingw-w64 headers.jan.nijtmans12 years
bug_3605447added testdgp12 years
bug_3606121Fixes to namespace-old.testdkf8 years
bug_3606683merge trunkdgp12 years
bug_3606683_84merge 8.4dgp12 years
bug_3606683_85merge 8.5dgp12 years
bug_3607246Correct unbalanced effect of TclInvalidateCmdLiteral() on the refcountsdgp12 years
bug_36073723607372 Correct literal refcounting.dgp12 years
bug_3608360Check for wildcards if we've used FindFirstFile inside NativeAccess.dkf12 years
bug_3608714merge trunkdgp9 years
bug_3609693[3609693] Must strip the internal representation of procedure-like methods indkf11 years
bug_3610026Demand the error message indicating the purpose of the test.dgp11 years
bug_3610383First simple-minded attempt at fix. Fixes the demo script.dgp11 years
bug_3610404merge trunkdgp11 years
bug_3611974minor bug: Don't TclpInitUnlock() here, because the following TclFinalizeLock...jan.nijtmans11 years
bug_3613609Fixed the weird edge case.dkf11 years
bug_3613671unwrapping some of the complexitydkf11 years
bug_3614342Repair TCL_COMPILE_DEBUG guardsdgp11 years
bug_39f6304c2emerge trunkjan.nijtmans8 years
bug_46f801ea5aTry to make good stack trace. Fallback to making not-so-good stack trace.dgp7 years
bug_473946Increase version to 1.2.5jan.nijtmans12 years
bug_47d66253c9Possible fix for [47d66253c92197d30bff280b02e0a9e62f07cee2|47d66253c9]: "lsea...jan.nijtmans10 years
bug_4a0c163d24New test for clock scan, test numbering correctedoehhar9 years
bug_4b61afd660Improve fix and add test.dgp8 years
bug_4dbdd9af14Improve the comments and add a test.dgp8 years
bug_50750c735a[50750c735a] Fix for uninit memory handling issue in zlib transforms.dkf7 years
bug_510001better solution for bug-510001jan.nijtmans12 years
bug_547989[547989] Proposed implementation of the change described in the comments of t...dkf11 years
bug_57945b574aFurther cleanup and enhancements.Joe Mistachkin9 years
bug_57945b574a_without_stubmerge trunkjan.nijtmans9 years
bug_581937ab1eFix bug [581937ab1e]: fire readable event on async socket connect failureoehhar10 years
bug_58b96f6744make [info commands] follow the namespace path from :: (bug [58b96f6744])aspect8 years
bug_593baa032cmerge trunkdgp9 years
bug_5adc350683Also test transfroms that delay.dgp10 years
bug_5adc350683_86merge iogt fixes.dgp10 years
bug_5d170b5ca5merge trunkjan.nijtmans9 years
bug_5f71353740merge trunkgahr@gahr.ch9 years
bug_67aa9a2070merge core-8-6-branchjan.nijtmans7 years
bug_6ca52aec14fix chan leak with http keepalive vs close (bug [6ca52aec14])aspect8 years
bug_716b427f76A few more tweaks to streamline and clarify.dgp7 years
bug_734138ded8Backout checkin 84f992ce50. This fixes test socket-14.11.1 and createsdgp10 years
bug_75b8433707[75b8433707] Plug a subtle memory leak in TclOO. dkf10 years
bug_7a87a9bc5bProposed fix for invalid write, found by valgrind.dkf9 years
bug_7f02ff1efaNew test trace-18.5 for the bug. Updated trace-18.1 which was tuned to it.dgp8 years
bug_80304238acExtra safety against cyclesdgp9 years
bug_85ce4bf928[85ce4bf928] Fix for problems with storing Inf with [binary format R].dkf9 years
bug_86ceb4e2b6merge trunkdgp11 years
bug_879a0747beProposed fix for bug 879a0747bedgp9 years
bug_894da183c8[894da183c8] Fix and test for bug at the point it was introduced.dgp9 years
bug_8bd13f07bdPatch for [8bd13f07bde6fb0631f27927e36461fdefe8ca95|8bd13f07bd]: Closing tcl ...jan.nijtmans7 years
bug_900cb0284bcTweak to make tests a little clearer.dkf7 years
bug_96c3f3b47d1Tcl_GetWideIntFromObj must fail for values between WIDE_MAX+1 and UWIDE_MAX (...aspect8 years
bug_97069ea11aRevert the tests for bug#97069ea11a from socket.test, because it is hard to t...max10 years
bug_9b47029467631832Add test-case which demonstrates the problem. This test-case fails in trunk (...jan.nijtmans9 years
bug_a3309d01dbAdd the missing cleanup bits in INST_UNSET_ARRAY.dgp9 years
bug_adb198c256Pull out of the loop a block of code that can only run in first iteration.dgp7 years
bug_af08e89777Rework the *FinalizeThread*() routines so that the quick exit preferencedgp10 years
bug_b26e38a3e4Fix the bug. Make use of zlib API in this area more like a Tcl API with wrapp...dkf8 years
bug_b5ced5865bProposed workaround for [b5ced5865b]: newer MinGW compilers can link director...jan.nijtmans10 years
bug_b87ad7e914Fix for [b87ad7e9146832d505f9a430d779c5313c440256|b87ad7e914], rebased to cor...jan.nijtmans8 years
bug_b9b2079e6dNew test compile-5.3 for the bug.dgp9 years
bug_ba44e415a0Proposed fix for [ba44e415a0]: "Use of mutexLock causes problem with reactive...jan.nijtmans9 years
bug_bbc304f61a[bbc304f61a] Proposed fix for reflected watch race condition.dgp9 years
bug_bc1a96407atest casesdgp10 years
bug_bd7f17bce8Enable TCL_EVAL_INVOKE support in the Tcl*Eval(Ex)* family.dgp8 years
bug_bdd91c7e43Suggested fix for [bdd91c7e43]: tclsh crashes in [interp delete]jan.nijtmans11 years
bug_c4e230f29brebase against trunkjan.nijtmans11 years
bug_c7d0bc9a549714e0Proposed fix for [c7d0bc9a549714e0]. Thanks to mr_calvinjan.nijtmans8 years
bug_d2ffcca163Limit isalpha(.) calls in the expr parser to only apply to known ASCIIdgp10 years
bug_d3071887dbc7aeac.... oops ....jan.nijtmans9 years
bug_d4e464ae48First attempt to fix bug [d4e464ae48]: tcl 8.5.15/8.61 breaks python make che...jan.nijtmans11 years
bug_d4e7780ca1Additiona patch/suggestion from Gustaf. This indeed fixes the crash in oo.tes...jan.nijtmans8 years
bug_d5ddbc7f49merge trunkdkf10 years
bug_db0a5f6417Make a few tests more resilient to differences in the semantics of pipes betw...dkf8 years
bug_dcc03414f5Revert bug-fix for [2413550], in order to be able to investigate whether it c...jan.nijtmans10 years
bug_dfc08326e3merge trunkjan.nijtmans11 years
bug_e0a7b3e5f8merge 8.5dgp9 years
bug_e21fc32c2aaProposed fix for [e21fc32c2aa]: auto_execok does not check executability on W...jan.nijtmans9 years
bug_e711ffb458New utility routine GetLocalScalarIndex() reduces common caller boilerplatedgp10 years
bug_f1253530cdMerged trunkfvogel9 years
bug_f1253530cd_altAlternative solution for [f1253530cd]jan.nijtmans9 years
bug_f4f44174emove pthread_sigmask() calls to Tcl_WaitForEvent() where they belongaspect8 years
bug_f97d4ee020Make the tests pass.dkf8 years
bug_f9fe90d0fa[f9fe90d0fa]: more path normalization in TclNewFSPathObjaspect7 years
bug_io_32_11merge 8.5dgp10 years
bug_itcl_1b2865Slightly more efficient version as this is Hot Path code.dkf8 years
bug_unknown_no_errorcodePotential fix for issues relating to lack of errorCode setting with unknown c...dkf11 years
bugfix_832a1994c7_for_precompiled_bcFixed bug in parent revision [832a1994c7] unpredictably breaking theandreask11 years
cjo_hydramerge tip-445dgp7 years
compile_ensemble(experiment): Always compile ensembles. Result: 2 test failures in the "histo...jan.nijtmans7 years
contrib_patrick_fradin_code_cleanupmerge trunkdgp12 years
core_8_0_2_syntheticCreated branch core-8-0-2-syntheticcvs2fossil26 years
core_8_0_3_prPost-release revisions to restore building on later platforms.dgp12 years
core_8_0_4_syntheticCreated branch core-8-0-4-syntheticcvs2fossil26 years
core_8_0_5_base_syntheticCreated branch core-8-0-5-base-syntheticcvs2fossil26 years
core_8_0_5_branchApplied patch to fix sockets when the FD_CONNECT never happens redman25 years
core_8_0_5_syntheticCreated branch core-8-0-5-syntheticcvs2fossil26 years
core_8_0_6_branchCreating branch core-8-0-6-branchcvs25 years
core_8_1_0_syntheticCreated branch core-8-1-0-syntheticcvs2fossil25 years
core_8_1_b1_syntheticCreated branch core-8-1-b1-syntheticcvs2fossil26 years
core_8_1_b2_syntheticCreated branch core-8-1-b2-syntheticcvs2fossil26 years
core_8_1_b3_syntheticCreated branch core-8-1-b3-syntheticcvs2fossil25 years
core_8_1_branch_oldFixed problem with LD_SEARCH_FLAGS on Solaris. It's different rjohnson25 years
core_8_2_1_branchFix sh quoting error reported in bash-3.1+ [Bug 1377619] nijtmans15 years
core_8_2_b1_syntheticCreated branch core-8-2-b1-syntheticcvs2fossil25 years
core_8_2_b3_branchRemoved patch to change prototype of Tcl_ListObjGetElements. redman25 years
core_8_3_1_branch[Bug 3030870] make itcl 3.x built with pre-8.6 work in 8.6: nijtmans14 years
core_8_3_1_io_rewrite * generic/tclStubInit.c: hobbs24 years
core_8_3_1_syntheticCreated branch core-8-3-1-syntheticcvs2fossil24 years
core_8_4_20_rcTag for release.dgp11 years
core_8_4_a2_syntheticCreated branch core-8-4-a2-syntheticcvs2fossil24 years
core_8_4_branchmerge releasedgp11 years
core_8_5_10_rcmerge to RCdgp13 years
core_8_5_11_rctag&bag another 8.5.11 RC.dgp13 years
core_8_5_12_rcmerge 8.5dgp12 years
core_8_5_13_rcChangeLog release markdgp12 years
core_8_5_14rcRedate. Retag RC1.dgp11 years
core_8_5_15_rcAdded note to ChangeLog pointing to the fossil timeline for better logging.dgp11 years
core_8_5_16_rc`make dist` allowed README-* fossil droppings to leak into the distribution.dgp10 years
core_8_5_17_rcupdate changesdgp10 years
core_8_5_18_rcrepair nroff breakagedgp10 years
core_8_5_19_rcupdate release datedgp9 years
core_8_5_a5_syntheticCreated branch core-8-5-a5-syntheticcvs2fossil18 years
core_8_5_branch[0e4d88b650] Allow command overwrite when deletion callback deletes namespace.dgp7 years
core_8_5_branch_fix_1997007code review: restore missing "break" to step out from internal cycle "while (...sebres7 years
core_8_6_0_rcmerge trunk, update changes and re-tagdgp12 years
core_8_6_1_rcmerge trunkdgp11 years
core_8_6_2_rcmerge trunk; update changesdgp10 years
core_8_6_3_rcLikely fix for channel mem leaks.dgp10 years
core_8_6_4_rcupdate changesdgp10 years
core_8_6_5_rcmerge trunkdgp9 years
core_8_6_6_rca few test & docs fixesdgp8 years
core_8_6_7_rcbump release datedgp7 years
core_8_6_b2_rcmerge from trunk to rc all but the AI_ADDRCONFIG experimentdgp13 years
core_8_6_b3_rcTag Tcl 8.6b3 for release.dgp12 years
core_8_6_branchRFE [566a999189] - better error message for 32/64 bit mismatch on load.apnadkarni7 years
core_8_6_branch_forkFixup the ensemble rewrite conversions.dgp8 years
core_8_7_a1_rcmerge trunk; rc1dgp7 years
core_stabilizer_branchmerge updates from 8.5 branch dgp16 years
core_stabilizer_merge_syntheticCreated branch core-stabilizer-merge-syntheticcvs2fossil16 years
core_zip_vfsImprovements to Tip#430 based on community input. Added a forward declaration...hypnotoad7 years
core_zip_vfs_c_encoderTweaks to buildhypnotoad10 years
core_zip_vfs_staticAdd Static library link instructions to tclConfig.shhypnotoad10 years
cpuid_on_unixcpuid-on-unixjan.nijtmans12 years
cygwin_environment_changescygwin should use SetEnvironmentVariable for windows envjan.nijtmans12 years
dah_proc_arg_upvarMore comments, fix bug where numArgs should be argCtdah8 years
damkerngt_file_utimeAdd new sub-command: file utime ?ATIME? MTIMEdamkerngt11 years
daves_chop_branchCreating branch daves-chop-branchcvs23 years
daves_mk_branchworks! I feel like a sculpter. Not done, by far. davygrvy23 years
dev_8_1_stubs_branchMerged 8.0 stub changes stanton26 years
dev_hobbs_branchrefactored varname pushing code and some of the bytecode instructions hobbs23 years
dev_stubs_branch* tools/genStubs.tcl: Reorganized code to support mixed generic stanton26 years
dgp_3401704Tidiness, comments, and tests.dgp13 years
dgp_async_socketThese edits make all tests outside of socket-14.* pass on OSX Mavericks.dgp10 years
dgp_bug_findNow fix the bug.dgp8 years
dgp_bye_ctx_eval_flagConsolidate some helper routines.dgp11 years
dgp_bye_location_eval_listDrop TCL_LOCATION_EVAL_LIST now that it is unused.dgp11 years
dgp_channel_flag_repairSimplify the inputProc of [testchannel transform].dgp10 years
dgp_cmd_epochRemove dup line.dgp8 years
dgp_compile_list_shimmerUnless I'm missing something, this patch to TclCompileListCmd() shoulddgp11 years
dgp_defer_string_repTidier version.dkf9 years
dgp_demoFixup restacking tests to expect the right results.dgp10 years
dgp_dup_encoding_fixmerge trunkdgp8 years
dgp_ecrMissed a cleanup line, which created a memleak.dgp8 years
dgp_encoding_flagsSupport TCL_ENCODING_CHAR_LIMIT in TableToUtfProc and EscapeToUtfProc drivers.dgp10 years
dgp_ensemble_rewritemerge 8.6dgp8 years
dgp_eofCorrect some faulty assumptions in the zlib transformation input driver. dgp11 years
dgp_experimentSimplify ReadBytes based on new constraints.dgp11 years
dgp_flush_channelUpdate comment to explain assumptions.dgp10 years
dgp_hoehrmann_decoderFeature branch to explore making use of the Hoehrmann UTF-8 decoder.dgp12 years
dgp_init_bytecodeParameterize TclInitByteCodeObj to callers sense of typePtr.dgp8 years
dgp_list_simplifyRemove the old implementation.dgp13 years
dgp_literal_reformmerge trunkdgp8 years
dgp_may_be_pointlessRevised ReadChars to restore an attempt to make sure we do not short readdgp11 years
dgp_move_buffersmerge trunkdgp10 years
dgp_no_buffer_recycleRevise the logic for setting TCL_ENCODING_END in the outputEncodingFlagsdgp10 years
dgp_optimize_output_stageBe sure to finalize the identity encoding.dgp11 years
dgp_pkg_migrationmerge trunkdgp10 years
dgp_properbytearraymerge novemdgp7 years
dgp_purge_NRRunObjProcTidy the code and add a test.dgp11 years
dgp_read_bytesMerge 8.5.dgp10 years
dgp_read_bytes_detourmissing declarationdgp11 years
dgp_read_charstidy up.dgp11 years
dgp_refactorRefactor code common to merge and insert.dgp7 years
dgp_refactor_merge_syntheticCreated branch dgp-refactor-merge-syntheticcvs2fossil14 years
dgp_remove_string_resultrevert mistaken commitdgp12 years
dgp_reviewequivalentjan.nijtmans11 years
dgp_revise_parsedvarnametypeThere's a "parsedVarName" Tcl_ObjType that remembers how a variable namedgp8 years
dgp_scan_elementmerge trunkjan.nijtmans13 years
dgp_slow_readSame results; simpler logic.dgp10 years
dgp_sprintfStart branch reducing use of sprintf().dgp11 years
dgp_stack_depth_testerReport pc value when VERIFY fails.dgp11 years
dgp_stackedstdchanFix for core bug yet to be named/numbered.dgp12 years
dgp_stop_regexp_test_crashBackout the contributed patch memaccounting from Postgres since it changesdgp@users.sourceforge.net9 years
dgp_string_catReplace indexing with pointer increments.dgp8 years
dgp_string_findOptimize case of all single-byte chars.dgp8 years
dgp_stringcat_delaystringrepDon't test the impossible.dgp7 years
dgp_switch_compileDrop old code.dgp13 years
dgp_tailcall_errorinfoSuppress additions to the -errorinfo from a tailcall-invoked command.dgp9 years
dgp_tailcall_errorinfo_altDifferent solution to the tailcall impact on -errorinfo.dgp9 years
dgp_tcs_rewrite[assemble] compile syntax error into bytecode reporting syntax error message.dgp11 years
dgp_thread_leaksUse the Thread package instead of the [testthread] command to do dgp13 years
dgp_trunk_flag_repairSame improvements to the zlib transform operations.dgp10 years
dgp_trunk_readmerge trunkdgp10 years
dgp_win_specific_strictUpon further review, due the order of #include of headers, we do not havedgp10 years
dgp_writebytes_optimizeMake simplificiations possible when we know just bytes are getting copieddgp10 years
dkf_64bit_support_branchAdded test for meaning of tcl_platform(wordSize) dkf23 years
dkf_alias_encodingmerge trunkdkf12 years
dkf_asm_crash_20131022merge trunkdgp11 years
dkf_bcc_optimizemerge trunkdkf11 years
dkf_better_try_compilationFix the problems with code generation; behavior now appears correct.dkf11 years
dkf_bytecode_8_6compilation of [string is]dkf11 years
dkf_bytecode_8_6_evalmerge main working branchdkf11 years
dkf_bytecode_8_6_joinmerge main working branchdkf11 years
dkf_bytecode_8_6_nextmerge main working branch; made opcode work by getting callback ordering rightdkf11 years
dkf_bytecode_8_6_string_isimprove the disassemblydkf11 years
dkf_bytecode_8_6_string_replaceprecondition was wrong, and needed to flush part of the string/internal repdkf11 years
dkf_bytecode_8_6_yieldfix INST_YIELD so that it worksmig12 years
dkf_bytecode_optimizermerge trunkdkf11 years
dkf_command_typemerge trunkdkf11 years
dkf_compile_improvementsmerge trunkdkf11 years
dkf_dict_with_compiledAdd the other instructions to the assembler's nous.dkf13 years
dkf_documentation_figuresmerge trunkdkf12 years
dkf_expose_ptrgetvarmerge trunkdkf7 years
dkf_expose_ptrgetvar_8_6Expose some of the core variable access APIs. dkf7 years
dkf_http_cookiesmerge trunkdkf10 years
dkf_improved_disassemblerTidy things up a bit more.dkf10 years
dkf_loop_exception_range_workAnd the last bits that need fixing; the code is still less efficient than des...dkf11 years
dkf_namespace_as_ensembleAdd ChangeLog entry.dkf14 years
dkf_notifier_pollmerge trunkdkf12 years
dkf_oo_override_definition_namespacesThink-o fix...dkf7 years
dkf_quieter_compilesmore quieting of excessively-noisy messagesdkf11 years
dkf_reviewremove uninitialized variable and the code that used it mig11 years
dkf_utf16_branchmerge trunkdkf12 years
dkf_wait_with_pollExperimental branch on whether to use poll() instead of select().dkf8 years
dogeen_assembler_branchmerge trunkKevin B Kenny14 years
dogeen_assembler_merge_syntheticCreated branch dogeen-assembler-merge-syntheticcvs2fossil14 years
drh_micro_optimizationMerge trunkjan.nijtmans8 years
editorconfigEditorconfig support (experimental)jan.nijtmans8 years
empty_bodiesmerge trunkMiguel Sofer9 years
experimentmerge 8.5dgp10 years
experimentalFix typo in previous check-in.Joe Mistachkin9 years
ferrieux_naclAdd a local copy of reference JS demo at same fps. Add an interactive tclsh p...ferrieux13 years
fix_1997007merge core-8-6-branchjan.nijtmans7 years
fix_42202ba1e5ff566ebug fix for [42202ba1e5ff566e0f9abb9f890e460fbc6c1c5c]: segfault by coro injectsebres7 years
fix_8_5_578155d5a19b348dstability fix: try to avoid segfault using released object, in error case of ...sebres7 years
fix_win_native_accessmerge to bugfix branchdgp13 years
fix_windows_zlibFix for the cases where a dynamic build is usedhypnotoad10 years
forgiving_pkgconfigoopsjan.nijtmans12 years
freq_3010352_implFRQ 3010352 implementationjan.nijtmans13 years
frq_3527238merge trunkjan.nijtmans12 years
frq_3544967same fore Makefile.injan.nijtmans12 years
frq_3579001merge trunkjan.nijtmans12 years
frq_3599786Experimental: categories added to man pages; enhance tcltk-man2html to use ca...twylite12 years
gahr_split_installCreate new branch named "gahr-split-install"gahr9 years
gahr_ticket_dee3d66bc7[dee3d66bc7] Remove 'any' afgahr9 years
gahr_ticket_e6f27aa56fmerge trunkjan.nijtmans8 years
gahr_tip_447Merge trunkgahr8 years
griffin_numlevelsmerge 8.5dgp12 years
htmlCopyrightsFixFix the generated copyright sections in the HTML help file.Joe Mistachkin8 years
htmlhelpFixSet the default topic, enable full-text search, and put all help output files...Joe Mistachkin8 years
http3Checkpoint of work in progress.dkf7 years
hypnotoadUpdating hypnotoad branchtne10 years
hypnotoad_bug_3598385Merging in changes from trunkseandeelywoods12 years
hypnotoad_prefer_native_8_6Bringing patch up to date with the latest trunkhypnotoad11 years
hypnotoad_vexprBringing vexpr up to date with the latest trunk.hypnotoad11 years
info_linkednameAdd [info linkedname] introspection commandmlafon7 years
initsubsystemsmerge trunkjan.nijtmans7 years
initsubsystems2revert previous 2 commits: Setting argv0 as well is not a good idea. Needs to...jan.nijtmans11 years
initsubsystems2_splitHow would it look like, if the various initializations were split in separate...jan.nijtmans11 years
iocmd_leaksConstrain test iocmd.tf-32.1 to be skipped during valgrinding. It contains a dgp13 years
iosTesting patches for iOS supportKevin Walzer10 years
irontclThe 'clean' target should delete the generated 'nmhlp-out.txt' file as well.Joe Mistachkin7 years
jcr_notifier_pollMerge from trunkevilotto10 years
je_tty_cleanupCreate new branch named "je-tty-cleanup"joe12 years
jenglish_termios_cleanup... which means struct TtyState can be replaced with struct FileState.joe12 years
jn_0d_radix_prefixmerge trunkjan.nijtmans7 years
jn_Tcl_requirementLet Tcl 8.7 allow Tk 8.7 to be used by defaultjan.nijtmans9 years
jn_emptystringMerge trunk. Don't use ListObjLength() in tclStrToD.cjan.nijtmans8 years
jn_frq_3257396merge latest trunkjan.nijtmans13 years
jn_no_struct_namesunnecessary hook struct definitionsjan.nijtmans12 years
jn_unc_vfsintegrate QNX special path handling better with TIP #402jan.nijtmans12 years
jn_wide_printfImplement all possible TCL_LL_MODIFIER formats in Tcl_ObjPrintf(), can be "ll...jan.nijtmans8 years
kbk_clock_encoding_ensemblesMake 'clock' and 'encoding' into compilable ensembles that play with safe int...Kevin B Kenny8 years
kennykb_numerics_branchmerge updates from HEAD dgp19 years
kennykb_tip_22_33 * Typo correction. dgp23 years
kennykb_tip_22_33_botchedDevelopment branch for TIPs 22 and 33 Kevin B Kenny23 years
lanam_array_for_implMerge trunkandy8 years
libtommath'const'ify all libtommath functions, will appear in next libtommath version. ...jan.nijtmans7 years
libtommath_1_0Restore bn_mp_radix_size.c to exact copy of libtommath-1.0 version: Since the...jan.nijtmans8 years
libtommath_1_0_1Merge libtommath 1.0.1 finaljan.nijtmans7 years
libtommath_tcl_fixes_75(experiment) See: [https://github.com/libtom/libtommath/pull/75] proposal by ...jan.nijtmans7 years
littleMerge 8.6.5dgp8 years
macosx_8_4_branchadded macosx-8-4-branch ChangeLog entries das22 years
masterMerge latest 'const'ification changes from libtommath (develop branch, will b...jan.nijtmans7 years
merge_tzdata_to_trunkMerge Forkvenkat8 years
micro_optMerge tip-444gahr8 years
mig_alloc_reformmerge trunkmig12 years
mig_catch_compilerallow simple optimization of the OK case, at the cost of some code duplicationmig11 years
mig_errstill no goodmig12 years
mig_no280merge trunkmig11 years
mig_nre_modscode reordering, no func changesMiguel Sofer9 years
mig_opt2replace indirect with direct jumps where possible; little effect for now, pen...Miguel Sofer9 years
mig_opt2_tmp(NON_PORTABLE) insure good cache alignment of NRE_callbackMiguel Sofer9 years
mig_opt_foreachchange NULL to INT2PTR(0), for claritymig11 years
mig_optimize*** ABANDONED - see branch mig-opt2 *** Miguel Sofer9 years
mig_review[010f4162ef] Repair effect of trace errors on -errorinfo and -errorstack.dgp11 years
mig_stacklevelsstop looking at the C-stack depthmig11 years
mig_strip_brutalmerge no280, emptymig12 years
mig_tailcall_cleanupmore commentsMiguel Sofer10 years
mig_tmpupdate the range data for code that was moved to the endMiguel Sofer9 years
mig_tmp_optimizeMaking the optimizer pluggable by extensions; please review for committing to...mig11 years
minimal_fix_for_3598300_problemsAs minimal a fix for the issues with [3598300] as I can make.dkf12 years
miniz*** NON WORKING BUILD *** hypnotoad10 years
mistachkin_review**TIP #285 untested by the testsuite if the thread extension is not available...mig11 years
mistakeCheck in reference implementation of TIP 452.gerald7 years
mistake_20110314Revert previous commit: I was not aware that we have a fork of libtommathjan.nijtmans14 years
mistake_20110314aRevert previous commit: I was not aware that we have a fork of libtommathjan.nijtmans14 years
mistkae[50750c735a] Possible fix for uninit memory handling issue in [zlib].dkf7 years
mod_8_3_4_branch * generic/tclProc.c (TclCloneProc): Fixed leaking of 'procNew', andreas_kupries21 years
more_macrosmerge trunkjan.nijtmans11 years
msgcat_dyn_localeAdded tests for mcforgetpackage, mcpackagelocale and mcpackageconfigoehhar9 years
msofer_bcEngineupdated some comments Miguel Sofer23 years
msofer_wcodes_branch * generic/tclExecute.c: fixing an error in INST_LNOT and Miguel Sofer19 years
msvc_with_64bit_zlib1_dllExperiment: MSVC build now links with 64-bit zlib1.dlljan.nijtmans12 years
no_shimmer_string_lengthfix broken lset tests, now all test-cases pass!jan.nijtmans12 years
no_smartrefAttempt to get new clock code working without the need for smartref.jan.nijtmans7 years
nonmonotonic_obj_allocZap outdated comment.ferrieux10 years
notifierIntroduce new function TclInitThreadAlloc(), symmetric with TclFinalizeThread...jan.nijtmans8 years
novemMerge trunkjan.nijtmans7 years
novem_64bit_sizesmerge novemdkf11 years
novem_ak_iframe_directCleaning up some of the internals of TIP #280.andreask12 years
novem_ak_preserve_experimentsThis branch explores the performance implications of relacing the andreask12 years
novem_bighashMerge novemjan.nijtmans8 years
novem_bug_3598300merge novemjan.nijtmans10 years
novem_demo_bug_3588687now change magic value, to demonstrate better solutionjan.nijtmans12 years
novem_freeifrefcountzeroFix correct cleanup in more situations, using a new macro TclFreeIfRefCountZerojan.nijtmans12 years
novem_more_memory_APImerge novemjan.nijtmans7 years
novem_no_register_objtypesuse longValue as internal repr in stead of wideValue. jan.nijtmans12 years
novem_no_shimmer_string_lengthNew experiment (ended), regarding non-shimmering "string length"jan.nijtmans12 years
novem_no_startcmdmerge changes from trunkdkf12 years
novem_numbers_eiasWIP getting rid of the ::tcl_precision variabledgp12 years
novem_purge_literalsBranch to investigate what happens when we no longer maintain shareddgp12 years
novem_reduced_bytecodesmerge main novem branchdkf12 years
novem_reduced_symbol_exportimprove compatibility with initsubsystems branchjan.nijtmans11 years
novem_remove_string_resultNo string result -> no more need for TCL_RESULT_SIZEdgp12 years
novem_remove_vamerge novemjan.nijtmans12 years
novem_rename_memory_APIRename the memory routines so that Tcl_Alloc/Tcl_Free/etc become the recommendeddgp12 years
novem_reviewProposed rollback of the TCL_STUB_MAGIC change on novem branch.dgp12 years
novem_saveresult_as_macroImplement Tcl_SaveResult/Tcl_DiscardResult/Tcl_RestoreResult as macrojan.nijtmans12 years
novem_supportdo some Tcl_EvalEx, for test-purposes, demonstrating a crashjan.nijtmans12 years
novem_two_layer_listFirst sketches of a two-layer data structure for storing Tcl lists.dgp12 years
novem_unversioned_stubmerge novem. Some more fixes.jan.nijtmans12 years
off_8_4_branchWrap test-case over multiple lines.jan.nijtmans12 years
off_trunkAdded tooltip generation to contents and keywords pages.dkf12 years
on_hold_84<i>On-hold at Don Porter's request.</i> jan.nijtmans12 years
on_hold_85<i>On hold at Don Porter's request</i> jan.nijtmans12 years
on_hold_trunk<i>on-hold at Don Porter's request</i> jan.nijtmans12 years
oo_copy_nsImprove docs, add tests, fix a corner case in the implementation.dkf7 years
other_64bit_candidatesThis doesn't compile! Just a reminder to myself which other API's/fields/what...jan.nijtmans12 years
package_filesFlightAware feedback: "Aside: Any way to find out what the pkgIndex.tcl file ...jan.nijtmans8 years
panic_noreturnDecorate Tcl_Panic and Tcl_PanicVA with the noreturn option, alowing further ...jan.nijtmans9 years
prevent_inlinePrevent inlining of StackGrowsDown(), in case of cross-compilingjan.nijtmans11 years
privatexjan.nijtmans13 years
pseudotrunk_2011_03_08More gcc warnings: variable set but not usedjan.nijtmans14 years
pyk_emptystringmerge trunkjan.nijtmans8 years
pyk_expr_numericHarmonize tests with expr implementation.pooryorick8 years
pyk_listdictstringrepAdd back constraint that direct dict->list conversion is only done when no st...pooryorick8 years
pyk_pkgrequirenreNRE-enable [package ifneeded] scripts.pooryorick8 years
pyk_trunkmerge pyk-listdictstringreppooryorick8 years
remove_pathappend_intrepmerge trunkdgp13 years
remove_trim_headerRevert Makefile.in changes and remove added tclStringTrim.h header. jan.nijtmans11 years
revert_3396731Repaired the lost performance in the copy loop hotspots. Now meets or dgp13 years
rfe_1711975Tcl_MainEx() (like Tk_MainEx())jan.nijtmans13 years
rfe_3216010Merge to feature branchdkf13 years
rfe_3389978More efficient/robust implementation of function TclNativeCreateNativeRep(). jan.nijtmans10 years
rfe_3432962Submitted patch on interactive use of the rc file.dgp12 years
rfe_3464401merge to feature branchjan.nijtmans13 years
rfe_3473670merge trunkjan.nijtmans13 years
rfe_6c0d7aec67merge core-8-6-branchjan.nijtmans7 years
rfe_854941Minor simplification and correct TCL_NORETURN decorationjan.nijtmans9 years
rfe_b42b208ba4Only write back file attributes if any of them really changed.jan.nijtmans11 years
rfe_dfc08326e3The Tcl 9.0 way of how [dfc08326e3] should be fixed: Real integration of TclO...jan.nijtmans11 years
rfe_notifier_forkFixed test case variable clash with 'folder'oehhar11 years
rmax_ipv6_branchcomplete a comment in socket.testmax13 years
rmax_ipv6_merge_syntheticCreated branch rmax-ipv6-merge-syntheticcvs2fossil14 years
robust_async_connect_testsmerge trunkjan.nijtmans10 years
scriptics_sc_1_0_branchCreating branch scriptics-sc-1-0-branchcvs25 years
scriptics_sc_1_1_branchCreating branch scriptics-sc-1-1-branchcvs25 years
scriptics_sc_2_0_b2_syntheticCreated branch scriptics-sc-2-0-b2-syntheticcvs2fossil24 years
scriptics_sc_2_0_b5_syntheticCreated branch scriptics-sc-2-0-b5-syntheticcvs2fossil24 years
scriptics_sc_2_0_fixed_syntheticCreated branch scriptics-sc-2-0-fixed-syntheticcvs2fossil24 years
scriptics_tclpro_1_2added missing files, changed to handle CRLF translations stanton25 years
scriptics_tclpro_1_2_oldUpdated patchlevel for final release. rjohnson25 years
scriptics_tclpro_1_2_syntheticCreated branch scriptics-tclpro-1-2-syntheticcvs2fossil26 years
scriptics_tclpro_1_3_b2_branchFixed so patchlevel is included in installer strings. stanton25 years
scriptics_tclpro_1_3_b3_syntheticCreated branch scriptics-tclpro-1-3-b3-syntheticcvs2fossil25 years
sebres_8_5_event_perf_branchmerge (integrate) sebres-event-perf-fix-busy-waitsebres7 years
sebres_8_5_timerate[win32] optimized calibration cycle (makes Tcl for windows "RTS" resp. NRT-ca...sebres7 years
sebres_8_6_clock_speedupsmall amend with forgetten static keyword by optionsebres7 years
sebres_8_6_clock_speedup_cr1fixed overflow of year (resp. julianday), closes ticket [16e4fc3096]; test ca...sebres7 years
sebres_8_6_event_perf_branchmerge sebres-event-perf-fix-busy-waitsebres7 years
sebres_8_6_timerateman for timerate (doc/timerate.n)sebres7 years
sebres_clean_core_8_5generic: reduced diffs to trunk, win: clean code after bug [f00009f7ce] was f...sebres9 years
sebres_clock_speedupCreate new branch named "sebres-clock-speedup"sebres8 years
sebres_clock_tz_fixclock - FreeScan (resp. Oldscan): repair scanning date/time with TZ using '+'...sebres9 years
sebres_event_perf_fix_busy_waitavoid busy wait if new short block-time will be set within service event-cycl...sebres7 years
sebres_optimized_8_5merge bugfixdkf13 years
sebres_trunk_clock_speedupmerge sebres-8-6-clock-speedupsebres7 years
sebres_trunk_timeratereintergrate (merge back) "sebres-8-6-timerate" into "sebres-trunk-timerate"sebres7 years
semverRe-base to trunk. Now versioned as 8.7.0-alpha.2jan.nijtmans7 years
stwo_dev86Change the return type of Tcl_RegisterChannel from void to Tcl_Channel and ha...stu7 years
tclPlatformEngineUpdate comment with TIP number.Joe Mistachkin9 years
tcl_nosize(Bad idea)jan.nijtmans12 years
tclchan_assertionsbackout backwards-incompatible experiment that was accidentally committedbch10 years
tclpro_1_5_0_syntheticCreated branch tclpro-1-5-0-syntheticcvs2fossil24 years
tcltest_verbose_descGeneralization: desc is now appended to most events.ferrieux10 years
tgl_pg_reAdapted new tests contributed from Tom Lane @postgres.dgp9 years
thread_leaksstop segfaultdgp13 years
ticket_9b2e636361Allocate encoding name, so caller of Tcl_RegisterConfig() doesn't need to kee...jan.nijtmans11 years
ticket_e770d92d6Patch to add support for higher baud rates under Unix Ticket [e770d92d76]]hypnotoad9 years
tip280_test_coverageRevert the revised macros used in developing the new tests.dgp11 years
tip404_tcl8_5Correct build version and backported 973091ef75oehhar12 years
tip429_only_idRecognize that "id" is the K combinator in disguise. Rename it as "K" and ext...ferrieux10 years
tip_106_implfix handling of closing '\0' for -binary datajan.nijtmans12 years
tip_162_branchread() errors or EOF shall not prevent write(). This allows for proper grace...davygrvy16 years
tip_257_implementation_branchRenamed functions to reduce confusion and added to header file. dkf18 years
tip_257_implementation_branch_root_syntheticCreated branch tip-257-implementation-branch-root-syntheticcvs2fossil18 years
tip_257_merge1_branch_20061020T1300add tclOO* files das18 years
tip_278_branch * tests/namespace-old.test (5.4 6.12,14,15): Miguel Sofer18 years
tip_282merge trunkdgp7 years
tip_302Added patch for win/configure.in into win/configure.acoehhar8 years
tip_312merge trunkjan.nijtmans7 years
tip_318_updatemerge trunkjan.nijtmans12 years
tip_388_implmerge trunk to feature branchjan.nijtmans13 years
tip_389_implmerge trunkjan.nijtmans7 years
tip_395_with_alt_namealternative TIP 395 implementation:jan.nijtmans13 years
tip_398_implCompat flag, test, and doc update.ferrieux12 years
tip_400_implmerge trunkdkf12 years
tip_401merge trunkdgp12 years
tip_404ChangeLog entry addedoehhar12 years
tip_405_impl_tdmerge trunkdkf12 years
tip_427Documented "fconfigure $h -connecting" on socket man pageoehhar10 years
tip_428Merge trunkoehhar10 years
tip_429merge trunkferrieux10 years
tip_436Added tests.dkf9 years
tip_440_altRedo TIP #440 alternative again, now using "info runtime".jan.nijtmans9 years
tip_440_backportBackport of TIP #440.Joe Mistachkin9 years
tip_444merge trunkgahr8 years
tip_445More TIP 445 conversion of the "path" Tcl_ObjType.dgp7 years
tip_445_forkmerge trunkdgp8 years
tip_445_rejectConvert the "bytearray" Tcl_ObjType to use the proposed Tcl_ObjIntRepdgp8 years
tip_452Tests for ::http::Write done.gerald7 years
tip_456Further experimental follow-up: Add internal function TclOpenTcpClientEx(), a...jan.nijtmans8 years
tip_456_forkmerge forkjan.nijtmans8 years
tip_457TIP#457: Update named group endingmlafon7 years
tip_458merge trunkdgp7 years
tip_458_experimentExperiment, does this work? Still to be tested: Eliminate variable triggerPip...jan.nijtmans7 years
tip_463merge trunkdgp7 years
tip_465Deal with backslashes in ${...}, change "char" to "character" in error, fix t...avl8 years
tip_468merge (minor style issues from) trunkjan.nijtmans7 years
tip_468_bisMerge "tip-468" branch. Add new function Tcl_OpenTcpClientEx() with same chan...jan.nijtmans7 years
tip_469Make it work again with new epoll Notifieravl427 years
tip_470merge trunkdkf7 years
tip_473Documentation correction; issue pointed out by DGP.dkf7 years
tip_59_implementation2002-04-05 Daniel Steffen <das@users.sourceforge.net> das22 years
tip_improve_execFirst part of upcoming TIP - Improving [exec]'s syntax : the syntax extension...ferrieux11 years
tk_bug_9eb55debc5Was handling the flushing at the end of the stream wrongly.dkf8 years
tkt3328635_posix_monotonic_clockMerge trunkjan.nijtmans7 years
tkt_04e26c02c0Make sure not to miss bignumsgahr7 years
tkt_414d10346bAnother attempt to cleanup stale remnants of the notifier subsystem.Joe Mistachkin11 years
tkt_4d5ae7d88a[4d5ae7d88a] Restore default-to-error logic in TcpConnectgahr8 years
unbreak_tclcompilerPartial revert of [a16752c252] bug fix to stop crashes in buggy tclcompiler.dgp11 years
unknown_rewritemerge trunkdgp12 years
unprovenwipdgp13 years
unsetThreadDataAlso finalize the condition variables for each notifier thread.Joe Mistachkin11 years
unwantedmerge trunkdgp7 years
updateextended* added some docco for [update] changes.colin8 years
vc_reformAdd default-* targetsapnadkarni7 years
vs_ide_compilemerge core-8-5-branchjan.nijtmans8 years
werner_utf_max_6Patches by Christian Werner, supporting TCL_UTF_MAX=6 on Windows. Doesn't wor...jan.nijtmans9 years
win32_armSupport compiling Tcl for Win32 on ARM.Joe Mistachkin11 years
winFixesmerge core-8-6-branch. Undo changes to coffbase.txt (they cause overlap with Tk)jan.nijtmans8 years
win_console_panicRebase to trunkjan.nijtmans7 years
win_sock_async_connect_race_fixsocket -async and gets/puts stall on windows (Ticket [336441ed59]) andreask11 years
z_modifierMerge trunkjan.nijtmans7 years
zipfsMerge core-8-6-branch, fallback for MAP_FILEjan.nijtmans7 years
zippy_fifoReduce the list walking by keeping lastPtr fields.dgp9 years
zlib_1_2_6[Frq 3483854] zlib-1.2.6jan.nijtmans13 years
 
TagDownloadAuthorAge
core-bug-e38dce74e2core-bug-e38dce74e2.zip  core-bug-e38dce74e2.tar.gz  core-bug-e38dce74e2.tar.bz2  jan.nijtmans2 days
core-bug-02d5d65d70adab97core-bug-02d5d65d70adab97.zip  core-bug-02d5d65d70adab97.tar.gz  core-bug-02d5d65d70adab97.tar.bz2  sebres9 days
core-8-6-15core-8-6-15.zip  core-8-6-15.tar.gz  core-8-6-15.tar.bz2  dgp12 days
core-bug-945d2387d7core-bug-945d2387d7.zip  core-bug-945d2387d7.tar.gz  core-bug-945d2387d7.tar.bz2  apnadkarni4 weeks
core-bug-a82f8b15d1core-bug-a82f8b15d1.zip  core-bug-a82f8b15d1.tar.gz  core-bug-a82f8b15d1.tar.bz2  jan.nijtmans4 weeks
core-bug-304d30677acore-bug-304d30677a.zip  core-bug-304d30677a.tar.gz  core-bug-304d30677a.tar.bz2  apnadkarni5 weeks
core-apn-encoding-testscore-apn-encoding-tests.zip  core-apn-encoding-tests.tar.gz  core-apn-encoding-tests.tar.bz2  apnadkarni5 weeks
core-bug-3968086595core-bug-3968086595.zip  core-bug-3968086595.tar.gz  core-bug-3968086595.tar.bz2  pooryorick6 weeks
core-zipfs-consolidationcore-zipfs-consolidation.zip  core-zipfs-consolidation.tar.gz  core-zipfs-consolidation.tar.bz2  apnadkarni6 weeks
core-bug-fccb9f322fcore-bug-fccb9f322f.zip  core-bug-fccb9f322f.tar.gz  core-bug-fccb9f322f.tar.bz2  apnadkarni7 weeks
core-9-0-b3core-9-0-b3.zip  core-9-0-b3.tar.gz  core-9-0-b3.tar.bz2  dgp8 weeks
core-bug-0439e1e1a3core-bug-0439e1e1a3.zip  core-bug-0439e1e1a3.tar.gz  core-bug-0439e1e1a3.tar.bz2  jan.nijtmans3 months
core-apn-info-framecore-apn-info-frame.zip  core-apn-info-frame.tar.gz  core-apn-info-frame.tar.bz2  apnadkarni3 months
core-tip-699core-tip-699.zip  core-tip-699.tar.gz  core-tip-699.tar.bz2  jan.nijtmans3 months
core-apn-icucore-apn-icu.zip  core-apn-icu.tar.gz  core-apn-icu.tar.bz2  apnadkarni3 months
core-apn-no-injectcore-apn-no-inject.zip  core-apn-no-inject.tar.gz  core-apn-no-inject.tar.bz2  apnadkarni3 months
core-bug-1d26e580cfcore-bug-1d26e580cf.zip  core-bug-1d26e580cf.tar.gz  core-bug-1d26e580cf.tar.bz2  jan.nijtmans3 months
core-bug-407b70361ccore-bug-407b70361c.zip  core-bug-407b70361c.tar.gz  core-bug-407b70361c.tar.bz2  jan.nijtmans4 months
core-9-0-b2core-9-0-b2.zip  core-9-0-b2.tar.gz  core-9-0-b2.tar.bz2  dgp4 months
core-fix-79474c58800cdf94core-fix-79474c58800cdf94.zip  core-fix-79474c58800cdf94.tar.gz  core-fix-79474c58800cdf94.tar.bz2  sebres4 months
dkf/to-redodkf/to-redo.zip  dkf/to-redo.tar.gz  dkf/to-redo.tar.bz2  dkf4 months
core-bug-9a8ce8af3dcore-bug-9a8ce8af3d.zip  core-bug-9a8ce8af3d.tar.gz  core-bug-9a8ce8af3d.tar.bz2  apnadkarni5 months
core-bug-ef23a85ac6core-bug-ef23a85ac6.zip  core-bug-ef23a85ac6.tar.gz  core-bug-ef23a85ac6.tar.bz2  jan.nijtmans5 months
core-tip-626core-tip-626.zip  core-tip-626.tar.gz  core-tip-626.tar.bz2  jan.nijtmans5 months
core-bug-18f4a94d03core-bug-18f4a94d03.zip  core-bug-18f4a94d03.tar.gz  core-bug-18f4a94d03.tar.bz2  jan.nijtmans5 months
core-bug-e155cedf33core-bug-e155cedf33.zip  core-bug-e155cedf33.tar.gz  core-bug-e155cedf33.tar.bz2  jan.nijtmans5 months
core-bug-ac7592e73c10d04bcore-bug-ac7592e73c10d04b.zip  core-bug-ac7592e73c10d04b.tar.gz  core-bug-ac7592e73c10d04b.tar.bz2  jan.nijtmans6 months
core-libtommath-1.3core-libtommath-1.3.zip  core-libtommath-1.3.tar.gz  core-libtommath-1.3.tar.bz2  jan.nijtmans6 months
core-clock-speedup-cr2core-clock-speedup-cr2.zip  core-clock-speedup-cr2.tar.gz  core-clock-speedup-cr2.tar.bz2  sebres6 months
core-tip-688-candidatecore-tip-688-candidate.zip  core-tip-688-candidate.tar.gz  core-tip-688-candidate.tar.bz2  jan.nijtmans6 months
core-bug-910d67a229fe7f65core-bug-910d67a229fe7f65.zip  core-bug-910d67a229fe7f65.tar.gz  core-bug-910d67a229fe7f65.tar.bz2  sebres7 months
core-8-6-14core-8-6-14.zip  core-8-6-14.tar.gz  core-8-6-14.tar.bz2  dgp7 months
core-tip-652core-tip-652.zip  core-tip-652.tar.gz  core-tip-652.tar.bz2  pooryorick7 months
core-9-0-b1core-9-0-b1.zip  core-9-0-b1.tar.gz  core-9-0-b1.tar.bz2  dgp9 months
core-9-0-b1-rc4core-9-0-b1-rc4.zip  core-9-0-b1-rc4.tar.gz  core-9-0-b1-rc4.tar.bz2  dgp9 months
core-tip-661-candidatecore-tip-661-candidate.zip  core-tip-661-candidate.tar.gz  core-tip-661-candidate.tar.bz2  jan.nijtmans10 months
closedclosed.zip  closed.tar.gz  closed.tar.bz2  jan.nijtmans13 months
core-tip-657-candidatecore-tip-657-candidate.zip  core-tip-657-candidate.tar.gz  core-tip-657-candidate.tar.bz2  jan.nijtmans14 months
core-tip-558-candidatecore-tip-558-candidate.zip  core-tip-558-candidate.tar.gz  core-tip-558-candidate.tar.bz2  jan.nijtmans16 months
core-tip-626-candidatecore-tip-626-candidate.zip  core-tip-626-candidate.tar.gz  core-tip-626-candidate.tar.bz2  jan.nijtmans17 months
tip-656-pre-capitip-656-pre-capi.zip  tip-656-pre-capi.tar.gz  tip-656-pre-capi.tar.bz2  apnadkarni19 months
jan-b8f575aa23jan-b8f575aa23.zip  jan-b8f575aa23.tar.gz  jan-b8f575aa23.tar.bz2  jan.nijtmans21 months
core-8-6-13core-8-6-13.zip  core-8-6-13.tar.gz  core-8-6-13.tar.bz2  dgp22 months
tip607-encoding-failindextip607-encoding-failindex.zip  tip607-encoding-failindex.tar.gz  tip607-encoding-failindex.tar.bz2  oehhar3 years
tip601-encoding-failindextip601-encoding-failindex.zip  tip601-encoding-failindex.tar.gz  tip601-encoding-failindex.tar.bz2  oehhar3 years
core-8-6-12core-8-6-12.zip  core-8-6-12.tar.gz  core-8-6-12.tar.bz2  dgp3 years
core-9-0-a3core-9-0-a3.zip  core-9-0-a3.tar.gz  core-9-0-a3.tar.bz2  dgp3 years
core-8-7-a5core-8-7-a5.zip  core-8-7-a5.tar.gz  core-8-7-a5.tar.bz2  dgp3 years
core-8-6-11core-8-6-11.zip  core-8-6-11.tar.gz  core-8-6-11.tar.bz2  dgp4 years
core-8-7a3core-8-7a3.zip  core-8-7a3.tar.gz  core-8-7a3.tar.bz2  dgp5 years
core-9-0-a1core-9-0-a1.zip  core-9-0-a1.tar.gz  core-9-0-a1.tar.bz2  dgp5 years
core-8-7-a3core-8-7-a3.zip  core-8-7-a3.tar.gz  core-8-7-a3.tar.bz2  dgp5 years
core-8-6-10core-8-6-10.zip  core-8-6-10.tar.gz  core-8-6-10.tar.bz2  dgp5 years
please_don't_mess_with_branches_just_for_debugging!please_don't_mess_with_branches_just_for_debugging!.zip  please_don't_mess_with_branches_just_for_debugging!.tar.gz  please_don't_mess_with_branches_just_for_debugging!.tar.bz2  jan.nijtmans5 years
core-8-6-9core-8-6-9.zip  core-8-6-9.tar.gz  core-8-6-9.tar.bz2  dgp6 years
rc4rc4.zip  rc4.tar.gz  rc4.tar.bz2  dgp6 years
core-8-6-8core-8-6-8.zip  core-8-6-8.tar.gz  core-8-6-8.tar.bz2  dgp7 years
vc_reform_tests_passvc_reform_tests_pass.zip  vc_reform_tests_pass.tar.gz  vc_reform_tests_pass.tar.bz2  7 years
vc-reform-tests-passvc-reform-tests-pass.zip  vc-reform-tests-pass.tar.gz  vc-reform-tests-pass.tar.bz2  apnadkarni7 years
releaserelease.zip  release.tar.gz  release.tar.bz2  7 years
core_8_7_a1core_8_7_a1.zip  core_8_7_a1.tar.gz  core_8_7_a1.tar.bz2  7 years
rc1rc1.zip  rc1.tar.gz  rc1.tar.bz2  7 years
core-8-7-a1core-8-7-a1.zip  core-8-7-a1.tar.gz  core-8-7-a1.tar.bz2  dgp7 years
rc0rc0.zip  rc0.tar.gz  rc0.tar.bz2  7 years
core_8_6_7core_8_6_7.zip  core_8_6_7.tar.gz  core_8_6_7.tar.bz2  7 years
core-8-6-7core-8-6-7.zip  core-8-6-7.tar.gz  core-8-6-7.tar.bz2  dgp7 years
bg-tip-282bg-tip-282.zip  bg-tip-282.tar.gz  bg-tip-282.tar.bz2  ferrieux8 years
bg_tip_282bg_tip_282.zip  bg_tip_282.tar.gz  bg_tip_282.tar.bz2  8 years
mistakemistake.zip  mistake.tar.gz  mistake.tar.bz2  8 years
tip_456tip_456.zip  tip_456.tar.gz  tip_456.tar.bz2  8 years
tip-456tip-456.zip  tip-456.tar.gz  tip-456.tar.bz2  jan.nijtmans8 years
core_8_6_6core_8_6_6.zip  core_8_6_6.tar.gz  core_8_6_6.tar.bz2  8 years
core-8-6-6core-8-6-6.zip  core-8-6-6.tar.gz  core-8-6-6.tar.bz2  dgp8 years
minor_changeminor_change.zip  minor_change.tar.gz  minor_change.tar.bz2  8 years
bug-3154ea2759bug-3154ea2759.zip  bug-3154ea2759.tar.gz  bug-3154ea2759.tar.bz2  kbk8 years
bug_3154ea2759bug_3154ea2759.zip  bug_3154ea2759.tar.gz  bug_3154ea2759.tar.bz2  8 years
potential_incompatibilitypotential_incompatibility.zip  potential_incompatibility.tar.gz  potential_incompatibility.tar.bz2  8 years
core_8_6_5core_8_6_5.zip  core_8_6_5.tar.gz  core_8_6_5.tar.bz2  9 years
core-8-6-5core-8-6-5.zip  core-8-6-5.tar.gz  core-8-6-5.tar.bz2  dgp9 years
gahr_bug_5f71353740gahr_bug_5f71353740.zip  gahr_bug_5f71353740.tar.gz  gahr_bug_5f71353740.tar.bz2  9 years
core_8_5_19core_8_5_19.zip  core_8_5_19.tar.gz  core_8_5_19.tar.bz2  9 years
core-8-5-19core-8-5-19.zip  core-8-5-19.tar.gz  core-8-5-19.tar.bz2  dgp9 years
tip_412tip_412.zip  tip_412.tar.gz  tip_412.tar.bz2  9 years
tip-412tip-412.zip  tip-412.tar.gz  tip-412.tar.bz2  oehhar9 years
testedtested.zip  tested.tar.gz  tested.tar.bz2  9 years
core_8_6_4core_8_6_4.zip  core_8_6_4.tar.gz  core_8_6_4.tar.bz2  10 years
core-8-6-4core-8-6-4.zip  core-8-6-4.tar.gz  core-8-6-4.tar.bz2  dgp10 years
core_8_5_18core_8_5_18.zip  core_8_5_18.tar.gz  core_8_5_18.tar.bz2  10 years
core-8-5-18core-8-5-18.zip  core-8-5-18.tar.gz  core-8-5-18.tar.bz2  dgp10 years
core_8_6_3core_8_6_3.zip  core_8_6_3.tar.gz  core_8_6_3.tar.bz2  10 years
core-8-6-3core-8-6-3.zip  core-8-6-3.tar.gz  core-8-6-3.tar.bz2  dgp10 years
core_8_5_17core_8_5_17.zip  core_8_5_17.tar.gz  core_8_5_17.tar.bz2  10 years
core-8-5-17core-8-5-17.zip  core-8-5-17.tar.gz  core-8-5-17.tar.bz2  dgp10 years
core_8_6_2core_8_6_2.zip  core_8_6_2.tar.gz  core_8_6_2.tar.bz2  10 years
rc3rc3.zip  rc3.tar.gz  rc3.tar.bz2  10 years
core-8-6-2core-8-6-2.zip  core-8-6-2.tar.gz  core-8-6-2.tar.bz2  dgp10 years
core_8_5_16core_8_5_16.zip  core_8_5_16.tar.gz  core_8_5_16.tar.bz2  10 years
core-8-5-16core-8-5-16.zip  core-8-5-16.tar.gz  core-8-5-16.tar.bz2  dgp10 years
tip_99tip_99.zip  tip_99.tar.gz  tip_99.tar.bz2  11 years
core_8_6_1core_8_6_1.zip  core_8_6_1.tar.gz  core_8_6_1.tar.bz2  11 years
core-8-6-1core-8-6-1.zip  core-8-6-1.tar.gz  core-8-6-1.tar.bz2  dgp11 years
core_8_5_15core_8_5_15.zip  core_8_5_15.tar.gz  core_8_5_15.tar.bz2  11 years
core-8-5-15core-8-5-15.zip  core-8-5-15.tar.gz  core-8-5-15.tar.bz2  dgp11 years
mig_reviewmig_review.zip  mig_review.tar.gz  mig_review.tar.bz2  11 years
mig-reviewmig-review.zip  mig-review.tar.gz  mig-review.tar.bz2  dgp11 years
core-8-4-20core-8-4-20.zip  core-8-4-20.tar.gz  core-8-4-20.tar.bz2  dgp11 years
core_8_4_20core_8_4_20.zip  core_8_4_20.tar.gz  core_8_4_20.tar.bz2  11 years
rc2rc2.zip  rc2.tar.gz  rc2.tar.bz2  11 years
core-8-5-14core-8-5-14.zip  core-8-5-14.tar.gz  core-8-5-14.tar.bz2  dgp11 years
core_8_5_14core_8_5_14.zip  core_8_5_14.tar.gz  core_8_5_14.tar.bz2  11 years
mig_retestmig_retest.zip  mig_retest.tar.gz  mig_retest.tar.bz2  12 years
mig-retestmig-retest.zip  mig-retest.tar.gz  mig-retest.tar.bz2  mig12 years
mig_no280_mistakemig_no280_mistake.zip  mig_no280_mistake.tar.gz  mig_no280_mistake.tar.bz2  12 years
mig-no280-mistakemig-no280-mistake.zip  mig-no280-mistake.tar.gz  mig-no280-mistake.tar.bz2  mig12 years
mig_alloc_reform_Z2mig_alloc_reform_Z2.zip  mig_alloc_reform_Z2.tar.gz  mig_alloc_reform_Z2.tar.bz2  12 years
mig-alloc-reform-Z2mig-alloc-reform-Z2.zip  mig-alloc-reform-Z2.tar.gz  mig-alloc-reform-Z2.tar.bz2  mig12 years
bug_3598385bug_3598385.zip  bug_3598385.tar.gz  bug_3598385.tar.bz2  12 years
bug-3598385bug-3598385.zip  bug-3598385.tar.gz  bug-3598385.tar.bz2  hypnotoad12 years
core_8_6_0core_8_6_0.zip  core_8_6_0.tar.gz  core_8_6_0.tar.bz2  12 years
core-8-6-0core-8-6-0.zip  core-8-6-0.tar.gz  core-8-6-0.tar.bz2  dgp12 years
core_8_5_13core_8_5_13.zip  core_8_5_13.tar.gz  core_8_5_13.tar.bz2  12 years
core-8-5-13core-8-5-13.zip  core-8-5-13.tar.gz  core-8-5-13.tar.bz2  dgp12 years
merge_to_trunkmerge_to_trunk.zip  merge_to_trunk.tar.gz  merge_to_trunk.tar.bz2  12 years
merge-to-trunkmerge-to-trunk.zip  merge-to-trunk.tar.gz  merge-to-trunk.tar.bz2  dkf12 years
tip_votetip_vote.zip  tip_vote.tar.gz  tip_vote.tar.bz2  12 years
tip-votetip-vote.zip  tip-vote.tar.gz  tip-vote.tar.bz2  dkf12 years
core_8_6_b3core_8_6_b3.zip  core_8_6_b3.tar.gz  core_8_6_b3.tar.bz2  12 years
core-8-6-b3core-8-6-b3.zip  core-8-6-b3.tar.gz  core-8-6-b3.tar.bz2  dgp12 years
core_8_5_12core_8_5_12.zip  core_8_5_12.tar.gz  core_8_5_12.tar.bz2  12 years
core-8-5-12core-8-5-12.zip  core-8-5-12.tar.gz  core-8-5-12.tar.bz2  dgp12 years
core_8_5_11core_8_5_11.zip  core_8_5_11.tar.gz  core_8_5_11.tar.bz2  13 years
core-8-5-11core-8-5-11.zip  core-8-5-11.tar.gz  core-8-5-11.tar.bz2  dgp13 years
core_8_6_b2core_8_6_b2.zip  core_8_6_b2.tar.gz  core_8_6_b2.tar.bz2  13 years
core-8-6-b2core-8-6-b2.zip  core-8-6-b2.tar.gz  core-8-6-b2.tar.bz2  dgp13 years
core_8_5_10core_8_5_10.zip  core_8_5_10.tar.gz  core_8_5_10.tar.bz2  13 years
core-8-5-10core-8-5-10.zip  core-8-5-10.tar.gz  core-8-5-10.tar.bz2  dgp13 years
corresponds_to_TclOO_0_6_3corresponds_to_TclOO_0_6_3.zip  corresponds_to_TclOO_0_6_3.tar.gz  corresponds_to_TclOO_0_6_3.tar.bz2  13 years
corresponds-to-TclOO-0-6-3corresponds-to-TclOO-0-6-3.zip  corresponds-to-TclOO-0-6-3.tar.gz  corresponds-to-TclOO-0-6-3.tar.bz2  dkf13 years
libtommath_merge_0_42_0libtommath_merge_0_42_0.zip  libtommath_merge_0_42_0.tar.gz  libtommath_merge_0_42_0.tar.bz2  14 years
libtommath-merge-0-42-0libtommath-merge-0-42-0.zip  libtommath-merge-0-42-0.tar.gz  libtommath-merge-0-42-0.tar.bz2  dkf14 years
Bug_3185009Bug_3185009.zip  Bug_3185009.tar.gz  Bug_3185009.tar.bz2  14 years
core_8_1_0core_8_1_0.zip  core_8_1_0.tar.gz  core_8_1_0.tar.bz2  14 years
core_8_1_1core_8_1_1.zip  core_8_1_1.tar.gz  core_8_1_1.tar.bz2  14 years
core_8_1_b3core_8_1_b3.zip  core_8_1_b3.tar.gz  core_8_1_b3.tar.bz2  14 years
core_8_4_a1core_8_4_a1.zip  core_8_4_a1.tar.gz  core_8_4_a1.tar.bz2  14 years
core_8_4_a2core_8_4_a2.zip  core_8_4_a2.tar.gz  core_8_4_a2.tar.bz2  14 years
core_8_4_a3core_8_4_a3.zip  core_8_4_a3.tar.gz  core_8_4_a3.tar.bz2  14 years
core_8_4_a4core_8_4_a4.zip  core_8_4_a4.tar.gz  core_8_4_a4.tar.bz2  14 years
core_8_4_b1core_8_4_b1.zip  core_8_4_b1.tar.gz  core_8_4_b1.tar.bz2  14 years
core_8_5_0core_8_5_0.zip  core_8_5_0.tar.gz  core_8_5_0.tar.bz2  14 years
core_8_5_1core_8_5_1.zip  core_8_5_1.tar.gz  core_8_5_1.tar.bz2  14 years
core_8_5_2core_8_5_2.zip  core_8_5_2.tar.gz  core_8_5_2.tar.bz2  14 years
core_stabilizer_mergecore_stabilizer_merge.zip  core_stabilizer_merge.tar.gz  core_stabilizer_merge.tar.bz2  14 years
dogeen_assembler_splitdogeen_assembler_split.zip  dogeen_assembler_split.tar.gz  dogeen_assembler_split.tar.bz2  14 years
macosx_8_4_premerge_2002_08_31_branchmacosx_8_4_premerge_2002_08_31_branch.zip  macosx_8_4_premerge_2002_08_31_branch.tar.gz  macosx_8_4_premerge_2002_08_31_branch.tar.bz2  14 years
macosx_premerge_6_9_02macosx_premerge_6_9_02.zip  macosx_premerge_6_9_02.tar.gz  macosx_premerge_6_9_02.tar.bz2  14 years
merge_8_3_1_io_rewrite_07_26_00merge_8_3_1_io_rewrite_07_26_00.zip  merge_8_3_1_io_rewrite_07_26_00.tar.gz  merge_8_3_1_io_rewrite_07_26_00.tar.bz2  14 years
tclpro_1_5_0tclpro_1_5_0.zip  tclpro_1_5_0.tar.gz  tclpro_1_5_0.tar.bz2  14 years
tip_257_implementation_branch_roottip_257_implementation_branch_root.zip  tip_257_implementation_branch_root.tar.gz  tip_257_implementation_branch_root.tar.bz2  14 years
tip_278_branch_roottip_278_branch_root.zip  tip_278_branch_root.tar.gz  tip_278_branch_root.tar.bz2  14 years
core_8_0_2core_8_0_2.zip  core_8_0_2.tar.gz  core_8_0_2.tar.bz2  14 years
core_8_0_3core_8_0_3.zip  core_8_0_3.tar.gz  core_8_0_3.tar.bz2  14 years
core_8_0_4core_8_0_4.zip  core_8_0_4.tar.gz  core_8_0_4.tar.bz2  14 years
core_8_0_5core_8_0_5.zip  core_8_0_5.tar.gz  core_8_0_5.tar.bz2  14 years
core_8_0_5_basecore_8_0_5_base.zip  core_8_0_5_base.tar.gz  core_8_0_5_base.tar.bz2  14 years
core_8_1_b1core_8_1_b1.zip  core_8_1_b1.tar.gz  core_8_1_b1.tar.bz2  14 years
core_8_1_b2core_8_1_b2.zip  core_8_1_b2.tar.gz  core_8_1_b2.tar.bz2  14 years
core_8_4_0core_8_4_0.zip  core_8_4_0.tar.gz  core_8_4_0.tar.bz2  14 years
core_8_4_1core_8_4_1.zip  core_8_4_1.tar.gz  core_8_4_1.tar.bz2  14 years
core_8_4_2core_8_4_2.zip  core_8_4_2.tar.gz  core_8_4_2.tar.bz2  14 years
core_8_4_3core_8_4_3.zip  core_8_4_3.tar.gz  core_8_4_3.tar.bz2  14 years
core_8_4_4core_8_4_4.zip  core_8_4_4.tar.gz  core_8_4_4.tar.bz2  14 years
core_8_4_5core_8_4_5.zip  core_8_4_5.tar.gz  core_8_4_5.tar.bz2  14 years
core_8_4_6core_8_4_6.zip  core_8_4_6.tar.gz  core_8_4_6.tar.bz2  14 years
core_8_4_7core_8_4_7.zip  core_8_4_7.tar.gz  core_8_4_7.tar.bz2  14 years
core_8_4_8core_8_4_8.zip  core_8_4_8.tar.gz  core_8_4_8.tar.bz2  14 years
core_8_4_9core_8_4_9.zip  core_8_4_9.tar.gz  core_8_4_9.tar.bz2  14 years
core_8_6_b1core_8_6_b1.zip  core_8_6_b1.tar.gz  core_8_6_b1.tar.bz2  14 years
rmax_ipv6_mergermax_ipv6_merge.zip  rmax_ipv6_merge.tar.gz  rmax_ipv6_merge.tar.bz2  14 years
scriptics_sc_1_0_basescriptics_sc_1_0_base.zip  scriptics_sc_1_0_base.tar.gz  scriptics_sc_1_0_base.tar.bz2  14 years
scriptics_tclpro_1_2_b1scriptics_tclpro_1_2_b1.zip  scriptics_tclpro_1_2_b1.tar.gz  scriptics_tclpro_1_2_b1.tar.bz2  14 years
scriptics_tclpro_1_2_b2scriptics_tclpro_1_2_b2.zip  scriptics_tclpro_1_2_b2.tar.gz  scriptics_tclpro_1_2_b2.tar.bz2  14 years
tip_278_20061009tip_278_20061009.zip  tip_278_20061009.tar.gz  tip_278_20061009.tar.bz2  14 years
ajuba_ajuba2_2_1_baseajuba_ajuba2_2_1_base.zip  ajuba_ajuba2_2_1_base.tar.gz  ajuba_ajuba2_2_1_base.tar.bz2  14 years
core_8_0_6_basecore_8_0_6_base.zip  core_8_0_6_base.tar.gz  core_8_0_6_base.tar.bz2  14 years
core_8_1_merge_3_9_99core_8_1_merge_3_9_99.zip  core_8_1_merge_3_9_99.tar.gz  core_8_1_merge_3_9_99.tar.bz2  14 years
core_8_2_b3_basecore_8_2_b3_base.zip  core_8_2_b3_base.tar.gz  core_8_2_b3_base.tar.bz2  14 years
core_8_3_1core_8_3_1.zip  core_8_3_1.tar.gz  core_8_3_1.tar.bz2  14 years
core_8_3_2core_8_3_2.zip  core_8_3_2.tar.gz  core_8_3_2.tar.bz2  14 years
core_8_3_3core_8_3_3.zip  core_8_3_3.tar.gz  core_8_3_3.tar.bz2  14 years
core_8_3_4core_8_3_4.zip  core_8_3_4.tar.gz  core_8_3_4.tar.bz2  14 years
core_8_3_5core_8_3_5.zip  core_8_3_5.tar.gz  core_8_3_5.tar.bz2  14 years
core_8_3_b1core_8_3_b1.zip  core_8_3_b1.tar.gz  core_8_3_b1.tar.bz2  14 years
core_8_3_b2core_8_3_b2.zip  core_8_3_b2.tar.gz  core_8_3_b2.tar.bz2  14 years
core_8_6_a1core_8_6_a1.zip  core_8_6_a1.tar.gz  core_8_6_a1.tar.bz2  14 years
core_8_6_a2core_8_6_a2.zip  core_8_6_a2.tar.gz  core_8_6_a2.tar.bz2  14 years
core_8_6_a3core_8_6_a3.zip  core_8_6_a3.tar.gz  core_8_6_a3.tar.bz2  14 years
dev_stubs_merge_8_1_3_9_99dev_stubs_merge_8_1_3_9_99.zip  dev_stubs_merge_8_1_3_9_99.tar.gz  dev_stubs_merge_8_1_3_9_99.tar.bz2  14 years
dogeen_assembler_mergedogeen_assembler_merge.zip  dogeen_assembler_merge.tar.gz  dogeen_assembler_merge.tar.bz2  14 years
macosx_8_4_branchpointmacosx_8_4_branchpoint.zip  macosx_8_4_branchpoint.tar.gz  macosx_8_4_branchpoint.tar.bz2  14 years
macosx_8_4_merge_2002_08_20_trunkmacosx_8_4_merge_2002_08_20_trunk.zip  macosx_8_4_merge_2002_08_20_trunk.tar.gz  macosx_8_4_merge_2002_08_20_trunk.tar.bz2  14 years
macosx_8_4_merge_2002_08_30_trunkmacosx_8_4_merge_2002_08_30_trunk.zip  macosx_8_4_merge_2002_08_30_trunk.tar.gz  macosx_8_4_merge_2002_08_30_trunk.tar.bz2  14 years
scriptics_bc_1_0_b1scriptics_bc_1_0_b1.zip  scriptics_bc_1_0_b1.tar.gz  scriptics_bc_1_0_b1.tar.bz2  14 years
scriptics_sc_1_0scriptics_sc_1_0.zip  scriptics_sc_1_0.tar.gz  scriptics_sc_1_0.tar.bz2  14 years
scriptics_sc_1_1scriptics_sc_1_1.zip  scriptics_sc_1_1.tar.gz  scriptics_sc_1_1.tar.bz2  14 years
scriptics_sc_2_0_b2scriptics_sc_2_0_b2.zip  scriptics_sc_2_0_b2.tar.gz  scriptics_sc_2_0_b2.tar.bz2  14 years
scriptics_sc_2_0_b5scriptics_sc_2_0_b5.zip  scriptics_sc_2_0_b5.tar.gz  scriptics_sc_2_0_b5.tar.bz2  14 years
scriptics_tclpro_1_2_a1scriptics_tclpro_1_2_a1.zip  scriptics_tclpro_1_2_a1.tar.gz  scriptics_tclpro_1_2_a1.tar.bz2  14 years
tclpro_1_4_0tclpro_1_4_0.zip  tclpro_1_4_0.tar.gz  tclpro_1_4_0.tar.bz2  14 years
tclpro_1_4_1tclpro_1_4_1.zip  tclpro_1_4_1.tar.gz  tclpro_1_4_1.tar.bz2  14 years
tip_257_implementation_branch_patchpoint_20061020T1300tip_257_implementation_branch_patchpoint_20061020T1300.zip  tip_257_implementation_branch_patchpoint_20061020T1300.tar.gz  tip_257_implementation_branch_patchpoint_20061020T1300.tar.bz2  14 years
ajuba_ajuba2_2_0ajuba_ajuba2_2_0.zip  ajuba_ajuba2_2_0.tar.gz  ajuba_ajuba2_2_0.tar.bz2  14 years
core_8_1_merge_latestcore_8_1_merge_latest.zip  core_8_1_merge_latest.tar.gz  core_8_1_merge_latest.tar.bz2  14 years
core_8_2_b1core_8_2_b1.zip  core_8_2_b1.tar.gz  core_8_2_b1.tar.bz2  14 years
core_8_2_b2core_8_2_b2.zip  core_8_2_b2.tar.gz  core_8_2_b2.tar.bz2  14 years
core_8_3_0core_8_3_0.zip  core_8_3_0.tar.gz  core_8_3_0.tar.bz2  14 years
core_8_4_18core_8_4_18.zip  core_8_4_18.tar.gz  core_8_4_18.tar.bz2  14 years
core_8_4_19core_8_4_19.zip  core_8_4_19.tar.gz  core_8_4_19.tar.bz2  14 years
core_8_5_a1core_8_5_a1.zip  core_8_5_a1.tar.gz  core_8_5_a1.tar.bz2  14 years
core_8_5_a2core_8_5_a2.zip  core_8_5_a2.tar.gz  core_8_5_a2.tar.bz2  14 years
core_8_5_a3core_8_5_a3.zip  core_8_5_a3.tar.gz  core_8_5_a3.tar.bz2  14 years
core_8_5_a4core_8_5_a4.zip  core_8_5_a4.tar.gz  core_8_5_a4.tar.bz2  14 years
core_8_5_a5core_8_5_a5.zip  core_8_5_a5.tar.gz  core_8_5_a5.tar.bz2  14 years
core_8_5_a6core_8_5_a6.zip  core_8_5_a6.tar.gz  core_8_5_a6.tar.bz2  14 years
core_8_5_b1core_8_5_b1.zip  core_8_5_b1.tar.gz  core_8_5_b1.tar.bz2  14 years
core_8_5_b2core_8_5_b2.zip  core_8_5_b2.tar.gz  core_8_5_b2.tar.bz2  14 years
core_8_5_b3core_8_5_b3.zip  core_8_5_b3.tar.gz  core_8_5_b3.tar.bz2  14 years
dgp_refactor_mergedgp_refactor_merge.zip  dgp_refactor_merge.tar.gz  dgp_refactor_merge.tar.bz2  14 years
kennykb_numerics_branch_20050915kennykb_numerics_branch_20050915.zip  kennykb_numerics_branch_20050915.tar.gz  kennykb_numerics_branch_20050915.tar.bz2  14 years
kennykb_numerics_branch_20051008kennykb_numerics_branch_20051008.zip  kennykb_numerics_branch_20051008.tar.gz  kennykb_numerics_branch_20051008.tar.bz2  14 years
macosx_8_4_merge_2002_08_20_branchmacosx_8_4_merge_2002_08_20_branch.zip  macosx_8_4_merge_2002_08_20_branch.tar.gz  macosx_8_4_merge_2002_08_20_branch.tar.bz2  14 years
macosx_8_4_merge_2002_08_30_branchmacosx_8_4_merge_2002_08_30_branch.zip  macosx_8_4_merge_2002_08_30_branch.tar.gz  macosx_8_4_merge_2002_08_30_branch.tar.bz2  14 years
macosx_8_4_merge_2002_08_31_trunkmacosx_8_4_merge_2002_08_31_trunk.zip  macosx_8_4_merge_2002_08_31_trunk.tar.gz  macosx_8_4_merge_2002_08_31_trunk.tar.bz2  14 years
merge_to_mainline_5_21_99merge_to_mainline_5_21_99.zip  merge_to_mainline_5_21_99.tar.gz  merge_to_mainline_5_21_99.tar.bz2  14 years
msofer_wcodes_20050611msofer_wcodes_20050611.zip  msofer_wcodes_20050611.tar.gz  msofer_wcodes_20050611.tar.bz2  14 years
msofer_wcodes_branch_20051007msofer_wcodes_branch_20051007.zip  msofer_wcodes_branch_20051007.tar.gz  msofer_wcodes_branch_20051007.tar.bz2  14 years
scriptics_sc_1_1_basescriptics_sc_1_1_base.zip  scriptics_sc_1_1_base.tar.gz  scriptics_sc_1_1_base.tar.bz2  14 years
scriptics_sc_2_0_b1scriptics_sc_2_0_b1.zip  scriptics_sc_2_0_b1.tar.gz  scriptics_sc_2_0_b1.tar.bz2  14 years
scriptics_tclpro_1_2scriptics_tclpro_1_2.zip  scriptics_tclpro_1_2.tar.gz  scriptics_tclpro_1_2.tar.bz2  14 years
scriptics_tclpro_1_3_0scriptics_tclpro_1_3_0.zip  scriptics_tclpro_1_3_0.tar.gz  scriptics_tclpro_1_3_0.tar.bz2  14 years
core_8_1_1_basecore_8_1_1_base.zip  core_8_1_1_base.tar.gz  core_8_1_1_base.tar.bz2  14 years
core_8_2_0core_8_2_0.zip  core_8_2_0.tar.gz  core_8_2_0.tar.bz2  14 years
core_8_2_1core_8_2_1.zip  core_8_2_1.tar.gz  core_8_2_1.tar.bz2  14 years
core_8_2_2core_8_2_2.zip  core_8_2_2.tar.gz  core_8_2_2.tar.bz2  14 years
core_8_2_3core_8_2_3.zip  core_8_2_3.tar.gz  core_8_2_3.tar.bz2  14 years
core_8_4_10core_8_4_10.zip  core_8_4_10.tar.gz  core_8_4_10.tar.bz2  14 years
core_8_4_11core_8_4_11.zip  core_8_4_11.tar.gz  core_8_4_11.tar.bz2  14 years
core_8_4_12core_8_4_12.zip  core_8_4_12.tar.gz  core_8_4_12.tar.bz2  14 years
core_8_4_13core_8_4_13.zip  core_8_4_13.tar.gz  core_8_4_13.tar.bz2  14 years
core_8_4_14core_8_4_14.zip  core_8_4_14.tar.gz  core_8_4_14.tar.bz2  14 years
core_8_4_15core_8_4_15.zip  core_8_4_15.tar.gz  core_8_4_15.tar.bz2  14 years
core_8_4_16core_8_4_16.zip  core_8_4_16.tar.gz  core_8_4_16.tar.bz2  14 years
core_8_4_17core_8_4_17.zip  core_8_4_17.tar.gz  core_8_4_17.tar.bz2  14 years
core_8_5_8core_8_5_8.zip  core_8_5_8.tar.gz  core_8_5_8.tar.bz2  14 years
core_8_5_9core_8_5_9.zip  core_8_5_9.tar.gz  core_8_5_9.tar.bz2  14 years
macosx_8_4_premerge_2002_08_31_trunkmacosx_8_4_premerge_2002_08_31_trunk.zip  macosx_8_4_premerge_2002_08_31_trunk.tar.gz  macosx_8_4_premerge_2002_08_31_trunk.tar.bz2  14 years
scriptics_sc_1_1_b1scriptics_sc_1_1_b1.zip  scriptics_sc_1_1_b1.tar.gz  scriptics_sc_1_1_b1.tar.bz2  14 years
scriptics_sc_2_0_fixedscriptics_sc_2_0_fixed.zip  scriptics_sc_2_0_fixed.tar.gz  scriptics_sc_2_0_fixed.tar.bz2  14 years
scriptics_tclpro_1_3_b3scriptics_tclpro_1_3_b3.zip  scriptics_tclpro_1_3_b3.tar.gz  scriptics_tclpro_1_3_b3.tar.bz2  14 years
scriptics_tclpro_1_3_b4scriptics_tclpro_1_3_b4.zip  scriptics_tclpro_1_3_b4.tar.gz  scriptics_tclpro_1_3_b4.tar.bz2  14 years
core_8_4_b2core_8_4_b2.zip  core_8_4_b2.tar.gz  core_8_4_b2.tar.bz2  14 years
core_8_5_3core_8_5_3.zip  core_8_5_3.tar.gz  core_8_5_3.tar.bz2  14 years
core_8_5_4core_8_5_4.zip  core_8_5_4.tar.gz  core_8_5_4.tar.bz2  14 years
core_8_5_5core_8_5_5.zip  core_8_5_5.tar.gz  core_8_5_5.tar.bz2  14 years
core_8_5_6core_8_5_6.zip  core_8_5_6.tar.gz  core_8_5_6.tar.bz2  14 years
core_8_5_7core_8_5_7.zip  core_8_5_7.tar.gz  core_8_5_7.tar.bz2  14 years
scriptics_tclpro_1_3_b1scriptics_tclpro_1_3_b1.zip  scriptics_tclpro_1_3_b1.tar.gz  scriptics_tclpro_1_3_b1.tar.bz2  14 years
scriptics_tclpro_1_3_b2scriptics_tclpro_1_3_b2.zip  scriptics_tclpro_1_3_b2.tar.gz  scriptics_tclpro_1_3_b2.tar.bz2  14 years
dgp-refactor-mergedgp-refactor-merge.zip  dgp-refactor-merge.tar.gz  dgp-refactor-merge.tar.bz2  cvs2fossil14 years
dogeen-assembler-mergedogeen-assembler-merge.zip  dogeen-assembler-merge.tar.gz  dogeen-assembler-merge.tar.bz2  cvs2fossil14 years
rmax-ipv6-mergermax-ipv6-merge.zip  rmax-ipv6-merge.tar.gz  rmax-ipv6-merge.tar.bz2  cvs2fossil14 years
dogeen-assembler-splitdogeen-assembler-split.zip  dogeen-assembler-split.tar.gz  dogeen-assembler-split.tar.bz2  nijtmans14 years
core-8-5-9core-8-5-9.zip  core-8-5-9.tar.gz  core-8-5-9.tar.bz2  dgp14 years
core-8-5-8core-8-5-8.zip  core-8-5-8.tar.gz  core-8-5-8.tar.bz2  dgp15 years
core-8-5-7core-8-5-7.zip  core-8-5-7.tar.gz  core-8-5-7.tar.bz2  dgp15 years
core-8-6-b1core-8-6-b1.zip  core-8-6-b1.tar.gz  core-8-6-b1.tar.bz2  dgp16 years
core-8-5-6core-8-5-6.zip  core-8-5-6.tar.gz  core-8-5-6.tar.bz2  dgp16 years
core-8-5-5core-8-5-5.zip  core-8-5-5.tar.gz  core-8-5-5.tar.bz2  dgp16 years
core-8-6-a3core-8-6-a3.zip  core-8-6-a3.tar.gz  core-8-6-a3.tar.bz2  dgp16 years
core-8-6-a2core-8-6-a2.zip  core-8-6-a2.tar.gz  core-8-6-a2.tar.bz2  dgp16 years
core-8-5-4core-8-5-4.zip  core-8-5-4.tar.gz  core-8-5-4.tar.bz2  dgp16 years
core-stabilizer-mergecore-stabilizer-merge.zip  core-stabilizer-merge.tar.gz  core-stabilizer-merge.tar.bz2  cvs2fossil16 years
core-8-5-3core-8-5-3.zip  core-8-5-3.tar.gz  core-8-5-3.tar.bz2  dgp16 years
core-8-6-a1core-8-6-a1.zip  core-8-6-a1.tar.gz  core-8-6-a1.tar.bz2  dgp16 years
core-8-4-19core-8-4-19.zip  core-8-4-19.tar.gz  core-8-4-19.tar.bz2  dgp16 years
core-8-5-2core-8-5-2.zip  core-8-5-2.tar.gz  core-8-5-2.tar.bz2  dgp16 years
core-8-4-18core-8-4-18.zip  core-8-4-18.tar.gz  core-8-4-18.tar.bz2  dgp17 years
core-8-5-1core-8-5-1.zip  core-8-5-1.tar.gz  core-8-5-1.tar.bz2  dgp17 years
core-8-4-17core-8-4-17.zip  core-8-4-17.tar.gz  core-8-4-17.tar.bz2  dgp17 years
core-8-5-0core-8-5-0.zip  core-8-5-0.tar.gz  core-8-5-0.tar.bz2  dgp17 years
core-8-5-b3core-8-5-b3.zip  core-8-5-b3.tar.gz  core-8-5-b3.tar.bz2  dgp17 years
core-8-5-b2core-8-5-b2.zip  core-8-5-b2.tar.gz  core-8-5-b2.tar.bz2  dgp17 years
core-8-5-b1core-8-5-b1.zip  core-8-5-b1.tar.gz  core-8-5-b1.tar.bz2  das17 years
core-8-4-16core-8-4-16.zip  core-8-4-16.tar.gz  core-8-4-16.tar.bz2  das17 years
core-8-4-15core-8-4-15.zip  core-8-4-15.tar.gz  core-8-4-15.tar.bz2  dgp17 years
core-8-5-a6core-8-5-a6.zip  core-8-5-a6.tar.gz  core-8-5-a6.tar.bz2  hobbs17 years
core-8-5-a5core-8-5-a5.zip  core-8-5-a5.tar.gz  core-8-5-a5.tar.bz2  cvs2fossil18 years
tip-257-implementation-branch-patchpoint-20061020T1300tip-257-implementation-branch-patchpoint-20061020T1300.zip  tip-257-implementation-branch-patchpoint-20061020T1300.tar.gz  tip-257-implementation-branch-patchpoint-20061020T1300.tar.bz2  dkf18 years
core-8-4-14core-8-4-14.zip  core-8-4-14.tar.gz  core-8-4-14.tar.bz2  dgp18 years
tip-278-20061009tip-278-20061009.zip  tip-278-20061009.tar.gz  tip-278-20061009.tar.bz2  msofer18 years
tip-278-branch-roottip-278-branch-root.zip  tip-278-branch-root.tar.gz  tip-278-branch-root.tar.bz2  patthoyts18 years
tip-257-implementation-branch-roottip-257-implementation-branch-root.zip  tip-257-implementation-branch-root.tar.gz  tip-257-implementation-branch-root.tar.bz2  cvs2fossil18 years
core-8-5-a4core-8-5-a4.zip  core-8-5-a4.tar.gz  core-8-5-a4.tar.bz2  dgp18 years
core-8-4-13core-8-4-13.zip  core-8-4-13.tar.gz  core-8-4-13.tar.bz2  dgp18 years
core-8-4-12core-8-4-12.zip  core-8-4-12.tar.gz  core-8-4-12.tar.bz2  dgp19 years
kennykb-numerics-branch-20051008kennykb-numerics-branch-20051008.zip  kennykb-numerics-branch-20051008.tar.gz  kennykb-numerics-branch-20051008.tar.bz2  hobbs19 years
msofer-wcodes-branch-20051007msofer-wcodes-branch-20051007.zip  msofer-wcodes-branch-20051007.tar.gz  msofer-wcodes-branch-20051007.tar.bz2  hobbs19 years
kennykb-numerics-branch-20050915kennykb-numerics-branch-20050915.zip  kennykb-numerics-branch-20050915.tar.gz  kennykb-numerics-branch-20050915.tar.bz2  dgp19 years
core-8-4-11core-8-4-11.zip  core-8-4-11.tar.gz  core-8-4-11.tar.bz2  dgp19 years
msofer-wcodes-20050611msofer-wcodes-20050611.zip  msofer-wcodes-20050611.tar.gz  msofer-wcodes-20050611.tar.bz2  dkf19 years
core-8-5-a3core-8-5-a3.zip  core-8-5-a3.tar.gz  core-8-5-a3.tar.bz2  hobbs19 years
core-8-4-10core-8-4-10.zip  core-8-4-10.tar.gz  core-8-4-10.tar.bz2  das19 years
core-8-5-a2core-8-5-a2.zip  core-8-5-a2.tar.gz  core-8-5-a2.tar.bz2  hobbs20 years
core-8-4-9core-8-4-9.zip  core-8-4-9.tar.gz  core-8-4-9.tar.bz2  hobbs20 years
core-8-4-8core-8-4-8.zip  core-8-4-8.tar.gz  core-8-4-8.tar.bz2  rmax20 years
core-8-4-7core-8-4-7.zip  core-8-4-7.tar.gz  core-8-4-7.tar.bz2  hobbs20 years
core-8-5-a1core-8-5-a1.zip  core-8-5-a1.tar.gz  core-8-5-a1.tar.bz2  hobbs21 years
core-8-4-6core-8-4-6.zip  core-8-4-6.tar.gz  core-8-4-6.tar.bz2  dgp21 years
core-8-4-5core-8-4-5.zip  core-8-4-5.tar.gz  core-8-4-5.tar.bz2  hobbs21 years
core-8-4-4core-8-4-4.zip  core-8-4-4.tar.gz  core-8-4-4.tar.bz2  hobbs21 years
core-8-4-3core-8-4-3.zip  core-8-4-3.tar.gz  core-8-4-3.tar.bz2  hobbs21 years
core-8-4-2core-8-4-2.zip  core-8-4-2.tar.gz  core-8-4-2.tar.bz2  das22 years
core-8-4-1core-8-4-1.zip  core-8-4-1.tar.gz  core-8-4-1.tar.bz2  hobbs22 years
core-8-3-5core-8-3-5.zip  core-8-3-5.tar.gz  core-8-3-5.tar.bz2  hobbs22 years
core-8-4-0core-8-4-0.zip  core-8-4-0.tar.gz  core-8-4-0.tar.bz2  hobbs22 years
macosx-8-4-merge-2002-08-31-trunkmacosx-8-4-merge-2002-08-31-trunk.zip  macosx-8-4-merge-2002-08-31-trunk.tar.gz  macosx-8-4-merge-2002-08-31-trunk.tar.bz2  das22 years
macosx-8-4-premerge-2002-08-31-branchmacosx-8-4-premerge-2002-08-31-branch.zip  macosx-8-4-premerge-2002-08-31-branch.tar.gz  macosx-8-4-premerge-2002-08-31-branch.tar.bz2  das22 years
macosx-8-4-merge-2002-08-30-branchmacosx-8-4-merge-2002-08-30-branch.zip  macosx-8-4-merge-2002-08-30-branch.tar.gz  macosx-8-4-merge-2002-08-30-branch.tar.bz2  das22 years
macosx-8-4-merge-2002-08-30-trunkmacosx-8-4-merge-2002-08-30-trunk.zip  macosx-8-4-merge-2002-08-30-trunk.tar.gz  macosx-8-4-merge-2002-08-30-trunk.tar.bz2  andreas_kupries22 years
macosx-8-4-premerge-2002-08-31-trunkmacosx-8-4-premerge-2002-08-31-trunk.zip  macosx-8-4-premerge-2002-08-31-trunk.tar.gz  macosx-8-4-premerge-2002-08-31-trunk.tar.bz2  andreas_kupries22 years
macosx-8-4-merge-2002-08-20-branchmacosx-8-4-merge-2002-08-20-branch.zip  macosx-8-4-merge-2002-08-20-branch.tar.gz  macosx-8-4-merge-2002-08-20-branch.tar.bz2  das22 years
macosx-8-4-merge-2002-08-20-trunkmacosx-8-4-merge-2002-08-20-trunk.zip  macosx-8-4-merge-2002-08-20-trunk.tar.gz  macosx-8-4-merge-2002-08-20-trunk.tar.bz2  dgp22 years
core-8-4-b2core-8-4-b2.zip  core-8-4-b2.tar.gz  core-8-4-b2.tar.bz2  hobbs22 years
core-8-4-b1core-8-4-b1.zip  core-8-4-b1.tar.gz  core-8-4-b1.tar.bz2  hobbs22 years
tip-99tip-99.zip  tip-99.tar.gz  tip-99.tar.bz2  vincentdarley22 years
core-8-4-a4core-8-4-a4.zip  core-8-4-a4.tar.gz  core-8-4-a4.tar.bz2  hobbs23 years
macosx-premerge-6-9-02macosx-premerge-6-9-02.zip  macosx-premerge-6-9-02.tar.gz  macosx-premerge-6-9-02.tar.bz2  das23 years
core-8-3-4core-8-3-4.zip  core-8-3-4.tar.gz  core-8-3-4.tar.bz2  hobbs23 years
macosx-8-4-branchpointmacosx-8-4-branchpoint.zip  macosx-8-4-branchpoint.tar.gz  macosx-8-4-branchpoint.tar.bz2  dgp23 years
core-8-4-a3core-8-4-a3.zip  core-8-4-a3.tar.gz  core-8-4-a3.tar.bz2  hobbs23 years
core-8-3-3core-8-3-3.zip  core-8-3-3.tar.gz  core-8-3-3.tar.bz2  hobbs23 years
core-8-4-a2core-8-4-a2.zip  core-8-4-a2.tar.gz  core-8-4-a2.tar.bz2  cvs2fossil24 years
core-8-3-2core-8-3-2.zip  core-8-3-2.tar.gz  core-8-3-2.tar.bz2  hobbs24 years
tclpro-1-4-1tclpro-1-4-1.zip  tclpro-1-4-1.tar.gz  tclpro-1-4-1.tar.bz2  hobbs24 years
tclpro-1-5-0tclpro-1-5-0.zip  tclpro-1-5-0.tar.gz  tclpro-1-5-0.tar.bz2  cvs2fossil24 years
tclpro-1-4-0tclpro-1-4-0.zip  tclpro-1-4-0.tar.gz  tclpro-1-4-0.tar.bz2  hobbs24 years
ajuba-ajuba2-2-1-baseajuba-ajuba2-2-1-base.zip  ajuba-ajuba2-2-1-base.tar.gz  ajuba-ajuba2-2-1-base.tar.bz2  cvs2fossil24 years
merge-8-3-1-io-rewrite-07-26-00merge-8-3-1-io-rewrite-07-26-00.zip  merge-8-3-1-io-rewrite-07-26-00.tar.gz  merge-8-3-1-io-rewrite-07-26-00.tar.bz2  hobbs24 years
core-8-4-a1core-8-4-a1.zip  core-8-4-a1.tar.gz  core-8-4-a1.tar.bz2  hobbs24 years
ajuba-ajuba2-2-0ajuba-ajuba2-2-0.zip  ajuba-ajuba2-2-0.tar.gz  ajuba-ajuba2-2-0.tar.bz2  cvs2fossil24 years
core-8-3-1core-8-3-1.zip  core-8-3-1.tar.gz  core-8-3-1.tar.bz2  cvs2fossil24 years
scriptics-sc-2-0-b2scriptics-sc-2-0-b2.zip  scriptics-sc-2-0-b2.tar.gz  scriptics-sc-2-0-b2.tar.bz2  cvs2fossil24 years
scriptics-sc-2-0-b5scriptics-sc-2-0-b5.zip  scriptics-sc-2-0-b5.tar.gz  scriptics-sc-2-0-b5.tar.bz2  cvs2fossil24 years
scriptics-sc-2-0-fixedscriptics-sc-2-0-fixed.zip  scriptics-sc-2-0-fixed.tar.gz  scriptics-sc-2-0-fixed.tar.bz2  cvs2fossil24 years
scriptics-sc-2-0-b1scriptics-sc-2-0-b1.zip  scriptics-sc-2-0-b1.tar.gz  scriptics-sc-2-0-b1.tar.bz2  sandeep25 years
core-8-3-0core-8-3-0.zip  core-8-3-0.tar.gz  core-8-3-0.tar.bz2  hobbs25 years
core-8-3-b2core-8-3-b2.zip  core-8-3-b2.tar.gz  core-8-3-b2.tar.bz2  hobbs25 years
core-8-3-b1core-8-3-b1.zip  core-8-3-b1.tar.gz  core-8-3-b1.tar.bz2  hobbs25 years
core-8-2-3core-8-2-3.zip  core-8-2-3.tar.gz  core-8-2-3.tar.bz2  jenn25 years
scriptics-sc-1-1scriptics-sc-1-1.zip  scriptics-sc-1-1.tar.gz  scriptics-sc-1-1.tar.bz2  jenn25 years
scriptics-sc-1-1-b1scriptics-sc-1-1-b1.zip  scriptics-sc-1-1-b1.tar.gz  scriptics-sc-1-1-b1.tar.bz2  cvs25 years
scriptics-sc-1-1-basescriptics-sc-1-1-base.zip  scriptics-sc-1-1-base.tar.gz  scriptics-sc-1-1-base.tar.bz2  cvs25 years
core-8-2-2core-8-2-2.zip  core-8-2-2.tar.gz  core-8-2-2.tar.bz2  cvs25 years
scriptics-sc-1-0scriptics-sc-1-0.zip  scriptics-sc-1-0.tar.gz  scriptics-sc-1-0.tar.bz2  cvs25 years
scriptics-sc-1-0-basescriptics-sc-1-0-base.zip  scriptics-sc-1-0-base.tar.gz  scriptics-sc-1-0-base.tar.bz2  cvs25 years
core-8-2-1core-8-2-1.zip  core-8-2-1.tar.gz  core-8-2-1.tar.bz2  hobbs25 years
scriptics-bc-1-0-b1scriptics-bc-1-0-b1.zip  scriptics-bc-1-0-b1.tar.gz  scriptics-bc-1-0-b1.tar.bz2  hobbs25 years
core-8-2-0core-8-2-0.zip  core-8-2-0.tar.gz  core-8-2-0.tar.bz2  welch25 years
scriptics-tclpro-1-3-0scriptics-tclpro-1-3-0.zip  scriptics-tclpro-1-3-0.tar.gz  scriptics-tclpro-1-3-0.tar.bz2  welch25 years
core-8-2-b3-basecore-8-2-b3-base.zip  core-8-2-b3-base.tar.gz  core-8-2-b3-base.tar.bz2  redman25 years
core-8-2-b2core-8-2-b2.zip  core-8-2-b2.tar.gz  core-8-2-b2.tar.bz2  redman25 years
scriptics-tclpro-1-3-b4scriptics-tclpro-1-3-b4.zip  scriptics-tclpro-1-3-b4.tar.gz  scriptics-tclpro-1-3-b4.tar.bz2  redman25 years
core-8-2-b1core-8-2-b1.zip  core-8-2-b1.tar.gz  core-8-2-b1.tar.bz2  cvs2fossil25 years
scriptics-tclpro-1-3-b3scriptics-tclpro-1-3-b3.zip  scriptics-tclpro-1-3-b3.tar.gz  scriptics-tclpro-1-3-b3.tar.bz2  cvs2fossil25 years
core-8-1-1core-8-1-1.zip  core-8-1-1.tar.gz  core-8-1-1.tar.bz2  stanton25 years
merge-to-mainline-5/21/99merge-to-mainline-5/21/99.zip  merge-to-mainline-5/21/99.tar.gz  merge-to-mainline-5/21/99.tar.bz2  redman25 years
scriptics-tclpro-1-3-b2scriptics-tclpro-1-3-b2.zip  scriptics-tclpro-1-3-b2.tar.gz  scriptics-tclpro-1-3-b2.tar.bz2  redman25 years
core-8-1-1-basecore-8-1-1-base.zip  core-8-1-1-base.tar.gz  core-8-1-1-base.tar.bz2  redman25 years
scriptics-tclpro-1-3-b1scriptics-tclpro-1-3-b1.zip  scriptics-tclpro-1-3-b1.tar.gz  scriptics-tclpro-1-3-b1.tar.bz2  redman25 years
core-8-1-0core-8-1-0.zip  core-8-1-0.tar.gz  core-8-1-0.tar.bz2  cvs2fossil25 years
core-8-0-6-basecore-8-0-6-base.zip  core-8-0-6-base.tar.gz  core-8-0-6-base.tar.bz2  cvs25 years
core-8-1-b3core-8-1-b3.zip  core-8-1-b3.tar.gz  core-8-1-b3.tar.bz2  cvs2fossil25 years
core-8-0-5core-8-0-5.zip  core-8-0-5.tar.gz  core-8-0-5.tar.bz2  cvs2fossil26 years
core-8-1-b2core-8-1-b2.zip  core-8-1-b2.tar.gz  core-8-1-b2.tar.bz2  cvs2fossil26 years
core-8-1-merge-latestcore-8-1-merge-latest.zip  core-8-1-merge-latest.tar.gz  core-8-1-merge-latest.tar.bz2  stanton26 years
core-8-1-merge-3/9/99core-8-1-merge-3/9/99.zip  core-8-1-merge-3/9/99.tar.gz  core-8-1-merge-3/9/99.tar.bz2  stanton26 years
dev-stubs-merge-8-1-3/9/99dev-stubs-merge-8-1-3/9/99.zip  dev-stubs-merge-8-1-3/9/99.tar.gz  dev-stubs-merge-8-1-3/9/99.tar.bz2  stanton26 years
scriptics-tclpro-1-2scriptics-tclpro-1-2.zip  scriptics-tclpro-1-2.tar.gz  scriptics-tclpro-1-2.tar.bz2  cvs2fossil26 years
scriptics-tclpro-1-2-b2scriptics-tclpro-1-2-b2.zip  scriptics-tclpro-1-2-b2.tar.gz  scriptics-tclpro-1-2-b2.tar.bz2  stanton26 years
core-8-0-5-basecore-8-0-5-base.zip  core-8-0-5-base.tar.gz  core-8-0-5-base.tar.bz2  cvs2fossil26 years
scriptics-tclpro-1-2-b1scriptics-tclpro-1-2-b1.zip  scriptics-tclpro-1-2-b1.tar.gz  scriptics-tclpro-1-2-b1.tar.bz2  welch26 years
scriptics-tclpro-1-2-a1scriptics-tclpro-1-2-a1.zip  scriptics-tclpro-1-2-a1.tar.gz  scriptics-tclpro-1-2-a1.tar.bz2  surles26 years
core-8-1-b1core-8-1-b1.zip  core-8-1-b1.tar.gz  core-8-1-b1.tar.bz2  cvs2fossil26 years
core-8-0-4core-8-0-4.zip  core-8-0-4.tar.gz  core-8-0-4.tar.bz2  cvs2fossil26 years
core-8-0-3core-8-0-3.zip  core-8-0-3.tar.gz  core-8-0-3.tar.bz2  stanton26 years
core-8-0-2core-8-0-2.zip  core-8-0-2.tar.gz  core-8-0-2.tar.bz2  cvs2fossil26 years
iv>
+ SourceFile="pip.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ InstallCondition="not InstallAllUsers and Include_pip">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+
+ <MsiPackage Id="path_AllUsers"
+ SourceFile="path.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ InstallCondition="InstallAllUsers and PrependPath">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="path_JustForMe"
+ SourceFile="path.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ InstallCondition="not InstallAllUsers and PrependPath">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+
+ <?define CompileAllCommand=-$(var.ShortVersion)$(var.Suffix32) -Wi "[TargetDir]\Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py2_|lib2to3\\tests|venv\\scripts" "[TargetDir]\Lib"?>
+ <ExePackage Id="compileall_AllUsers"
+ SourceFile="py.exe"
+ Compressed="yes"
+ DisplayName="!(loc.CompileAllDescription)"
+ InstallCommand='$(var.CompileAllCommand)'
+ RepairCommand='$(var.CompileAllCommand)'
+ Permanent="yes"
+ PerMachine="yes"
+ Vital="no"
+ InstallCondition="InstallAllUsers and CompileAll" />
+ <ExePackage Id="compileall_JustForMe"
+ SourceFile="py.exe"
+ Compressed="yes"
+ DisplayName="!(loc.CompileAllDescription)"
+ InstallCommand='$(var.CompileAllCommand)'
+ RepairCommand='$(var.CompileAllCommand)'
+ Permanent="yes"
+ PerMachine="no"
+ Vital="no"
+ InstallCondition="not InstallAllUsers and CompileAll" />
+ </PackageGroup>
+ </Fragment>
+</Wix> \ No newline at end of file
diff --git a/Tools/msi/bundle/packagegroups/tcltk.wxs b/Tools/msi/bundle/packagegroups/tcltk.wxs
new file mode 100644
index 0000000..e0e3958
--- /dev/null
+++ b/Tools/msi/bundle/packagegroups/tcltk.wxs
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <PackageGroup Id="tcltk">
+ <MsiPackage Id="tcltk_AllUsers"
+ SourceFile="tcltk.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ EnableFeatureSelection="yes"
+ InstallCondition="InstallAllUsers and Include_tcltk">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="tcltk_AllUsers_pdb"
+ SourceFile="tcltk_pdb.msi"
+ Compressed="$(var.CompressPDB)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ EnableFeatureSelection="yes"
+ InstallCondition="InstallAllUsers and Include_tcltk and Include_symbols">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="tcltk_AllUsers_d"
+ SourceFile="tcltk_d.msi"
+ Compressed="$(var.CompressMSI_D)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ EnableFeatureSelection="yes"
+ InstallCondition="InstallAllUsers and Include_tcltk and Include_debug">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+
+ <MsiPackage Id="tcltk_JustForMe"
+ SourceFile="tcltk.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ EnableFeatureSelection="yes"
+ InstallCondition="not InstallAllUsers and Include_tcltk">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="tcltk_JustForMe_pdb"
+ SourceFile="tcltk_pdb.msi"
+ Compressed="$(var.CompressPDB)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ EnableFeatureSelection="yes"
+ InstallCondition="not InstallAllUsers and Include_tcltk and Include_symbols">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="tcltk_JustForMe_d"
+ SourceFile="tcltk_d.msi"
+ Compressed="$(var.CompressMSI_D)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ EnableFeatureSelection="yes"
+ InstallCondition="not InstallAllUsers and Include_tcltk and Include_debug">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ </PackageGroup>
+ </Fragment>
+</Wix> \ No newline at end of file
diff --git a/Tools/msi/bundle/packagegroups/test.wxs b/Tools/msi/bundle/packagegroups/test.wxs
new file mode 100644
index 0000000..b64e8ff
--- /dev/null
+++ b/Tools/msi/bundle/packagegroups/test.wxs
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <PackageGroup Id="test">
+ <MsiPackage Id="test_AllUsers"
+ SourceFile="test.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ InstallCondition="InstallAllUsers and Include_test">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="test_AllUsers_pdb"
+ SourceFile="test_pdb.msi"
+ Compressed="$(var.CompressPDB)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ InstallCondition="InstallAllUsers and Include_test and Include_symbols">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="test_AllUsers_d"
+ SourceFile="test_d.msi"
+ Compressed="$(var.CompressMSI_D)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ InstallCondition="InstallAllUsers and Include_test and Include_debug">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+
+ <MsiPackage Id="test_JustForMe"
+ SourceFile="test.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ InstallCondition="not InstallAllUsers and Include_test">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="test_JustForMe_pdb"
+ SourceFile="test_pdb.msi"
+ Compressed="$(var.CompressPDB)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ InstallCondition="not InstallAllUsers and Include_test and Include_symbols">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ <MsiPackage Id="test_JustForMe_d"
+ SourceFile="test_d.msi"
+ Compressed="$(var.CompressMSI_D)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ InstallCondition="not InstallAllUsers and Include_test and Include_debug">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ </PackageGroup>
+ </Fragment>
+</Wix> \ No newline at end of file
diff --git a/Tools/msi/bundle/packagegroups/tools.wxs b/Tools/msi/bundle/packagegroups/tools.wxs
new file mode 100644
index 0000000..06af5b5
--- /dev/null
+++ b/Tools/msi/bundle/packagegroups/tools.wxs
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <PackageGroup Id="tools">
+ <MsiPackage Id="tools_AllUsers"
+ SourceFile="tools.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="yes"
+ InstallCondition="InstallAllUsers and Include_tools">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+
+ <MsiPackage Id="tools_JustForMe"
+ SourceFile="tools.msi"
+ Compressed="$(var.CompressMSI)"
+ DownloadUrl="$(var.DownloadUrl)"
+ ForcePerMachine="no"
+ InstallCondition="not InstallAllUsers and Include_tools">
+ <MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
+ </MsiPackage>
+ </PackageGroup>
+ </Fragment>
+</Wix> \ No newline at end of file
diff --git a/Tools/msi/bundle/postinstall_en-US.wxl_template b/Tools/msi/bundle/postinstall_en-US.wxl_template
new file mode 100644
index 0000000..5f54aef
--- /dev/null
+++ b/Tools/msi/bundle/postinstall_en-US.wxl_template
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="CompileAllDescription">Precompiling standard library</String>
+</WixLocalization>
diff --git a/Tools/msi/bundle/releaselocal.wixproj b/Tools/msi/bundle/releaselocal.wixproj
new file mode 100644
index 0000000..0c3dee7
--- /dev/null
+++ b/Tools/msi/bundle/releaselocal.wixproj
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{FCD43AC9-969F-49A1-8AC5-EDC27599D1EB}</ProjectGuid>
+ <OutputName>python</OutputName>
+ <OutputSuffix></OutputSuffix>
+ </PropertyGroup>
+
+ <Import Project="..\msi.props" />
+
+ <PropertyGroup>
+ <DefineConstants>
+ $(DefineConstants);
+ CompressMSI=yes;
+ CompressPDB=no;
+ CompressMSI_D=no
+ </DefineConstants>
+ </PropertyGroup>
+
+ <Import Project="bundle.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/bundle/releaseweb.wixproj b/Tools/msi/bundle/releaseweb.wixproj
new file mode 100644
index 0000000..350c735
--- /dev/null
+++ b/Tools/msi/bundle/releaseweb.wixproj
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{71CDE213-CB39-4BD9-B89D-BBB878689144}</ProjectGuid>
+ <OutputName>python</OutputName>
+ <OutputSuffix>webinstall</OutputSuffix>
+ </PropertyGroup>
+
+ <Import Project="..\msi.props" />
+
+ <PropertyGroup>
+ <DefineConstants>
+ $(DefineConstants);
+ CompressMSI=no;
+ CompressPDB=no;
+ CompressMSI_D=no
+ </DefineConstants>
+ </PropertyGroup>
+
+ <Import Project="bundle.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/bundle/snapshot.wixproj b/Tools/msi/bundle/snapshot.wixproj
new file mode 100644
index 0000000..8fe95a8
--- /dev/null
+++ b/Tools/msi/bundle/snapshot.wixproj
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{8A4A1162-4BF9-4FF6-9A98-315F01E44932}</ProjectGuid>
+ <OutputName>python</OutputName>
+ <OutputSuffix></OutputSuffix>
+ </PropertyGroup>
+
+ <Import Project="..\msi.props" />
+
+ <PropertyGroup>
+ <DefineConstants>
+ $(DefineConstants);
+ CompressMSI=no;
+ CompressPDB=no;
+ CompressMSI_D=no;
+ </DefineConstants>
+ </PropertyGroup>
+
+ <Import Project="bundle.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs
new file mode 100644
index 0000000..2e50c12
--- /dev/null
+++ b/Tools/msi/common.wxs
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <Property Id="REGISTRYKEY" Value="Software\$(var.TestPrefix)Python\PythonCore\$(var.ShortVersion)$(var.Suffix32)" />
+ </Fragment>
+
+ <Fragment>
+ <Property Id="UpgradeTable" Value="1" />
+
+ <Upgrade Id="$(var.UpgradeCode)">
+ <UpgradeVersion Property="DOWNGRADE" Minimum="$(var.Version)" IncludeMinimum="no" OnlyDetect="yes" />
+ <UpgradeVersion Property="UPGRADE" Minimum="$(var.UpgradeMinimumVersion)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
+ </Upgrade>
+
+ <?if $(var.UpgradeCode)!=$(var.CoreUpgradeCode) ?>
+ <Upgrade Id="$(var.CoreUpgradeCode)">
+ <UpgradeVersion Property="MISSING_CORE" Minimum="$(var.Version)" Maximum="$(var.Version)" OnlyDetect="yes" />
+ </Upgrade>
+ <?endif ?>
+
+ <Condition Message="!(loc.NoDowngrade)">Installed OR NOT DOWNGRADE</Condition>
+ <Condition Message="!(loc.IncorrectCore)">Installed OR NOT MISSING_CORE</Condition>
+ <Condition Message="!(loc.NoTargetDir)">Installed OR TARGETDIR OR Suppress_TARGETDIR_Check</Condition>
+
+ <InstallExecuteSequence>
+ <RemoveExistingProducts After="InstallInitialize">UPGRADE</RemoveExistingProducts>
+ </InstallExecuteSequence>
+ </Fragment>
+
+ <Fragment>
+ <!-- Include an icon for the Programs and Features dialog -->
+ <Icon Id="ARPIcon" SourceFile="!(bindpath.src)PC\pycon.ico" />
+ <Property Id="ARPPRODUCTICON" Value="ARPIcon" />
+ <Property Id="ARPNOMODIFY" Value="1" />
+ <Property Id="DISABLEADVTSHORTCUTS" Value="1" />
+ </Fragment>
+
+ <Fragment>
+ <Directory Id="TARGETDIR" Name="SourceDir">
+ <Directory Id="InstallDirectory" ComponentGuidGenerationSeed="$(var.InstallDirectoryGuidSeed)" />
+ </Directory>
+ </Fragment>
+
+ <!-- Top-level directories -->
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="DLLs" Name="DLLs" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="Doc" Name="Doc" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="include" Name="include" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="Lib" Name="Lib" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="libs" Name="libs" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="Scripts" Name="Scripts" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="tcl" Name="tcl" />
+ </DirectoryRef>
+ </Fragment>
+
+ <Fragment>
+ <DirectoryRef Id="InstallDirectory">
+ <Directory Id="Tools" Name="Tools" />
+ </DirectoryRef>
+ </Fragment>
+
+ <!-- Start Menu folder -->
+ <Fragment>
+ <DirectoryRef Id="TARGETDIR">
+ <Directory Id="ProgramMenuFolder">
+ <Directory Id="MenuDir" Name="!(loc.ProductName)" />
+ </Directory>
+ </DirectoryRef>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/common_en-US.wxl_template b/Tools/msi/common_en-US.wxl_template
new file mode 100644
index 0000000..8d03526
--- /dev/null
+++ b/Tools/msi/common_en-US.wxl_template
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="LCID">1033</String>
+ <String Id="Culture">en-us</String>
+ <String Id="ProductName">Python {{ShortVersion}}</String>
+ <String Id="FullProductName">Python {{LongVersion}} ({{Bitness}})</String>
+ <String Id="Title">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}})</String>
+ <String Id="Description">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}})</String>
+ <String Id="TitlePdb">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols)</String>
+ <String Id="DescriptionPdb">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols)</String>
+ <String Id="Title_d">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug)</String>
+ <String Id="Description_d">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug)</String>
+ <String Id="Manufacturer">Python Software Foundation</String>
+ <String Id="NoDowngrade">A newer version of !(loc.ProductName) is already installed.</String>
+ <String Id="IncorrectCore">An incorrect version of a prerequisite package is installed. Please uninstall any other versions of !(loc.ProductName) and try installing this again.</String>
+ <String Id="NoTargetDir">The TARGETDIR variable must be provided when invoking this installer.</String>
+</WixLocalization>
diff --git a/Tools/msi/core/core.props b/Tools/msi/core/core.props
new file mode 100644
index 0000000..2320607
--- /dev/null
+++ b/Tools/msi/core/core.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/core/core.wixproj b/Tools/msi/core/core.wixproj
new file mode 100644
index 0000000..7265119
--- /dev/null
+++ b/Tools/msi/core/core.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{1B4502D5-B627-4F50-ABEA-4CC5A8E88265}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>core</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDefaultFeature=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="core.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/core/core.wxs b/Tools/msi/core/core.wxs
new file mode 100644
index 0000000..d354e37
--- /dev/null
+++ b/Tools/msi/core/core.wxs
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <PropertyRef Id="UpgradeTable" />
+
+ <?ifdef IncludeDefaultFeature ?>
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="core_dll" />
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeSymbols ?>
+ <Feature Id="Symbols" AllowAdvertise="no" Title="!(loc.TitlePdb)" Description="!(loc.DescriptionPdb)">
+ <ComponentGroupRef Id="core_symbols" />
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeDebugBinaries ?>
+ <Feature Id="DebugBinaries" AllowAdvertise="no" Title="!(loc.Title_d)" Description="!(loc.Description_d)">
+ <ComponentGroupRef Id="core_dll_d" />
+ </Feature>
+ <?endif ?>
+ </Product>
+</Wix>
diff --git a/Tools/msi/core/core_d.wixproj b/Tools/msi/core/core_d.wixproj
new file mode 100644
index 0000000..f1f60a9
--- /dev/null
+++ b/Tools/msi/core/core_d.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{D3677DCF-098A-4398-9FA5-8E74AC37E0DF}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>core_d</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDebugBinaries=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="core.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/core/core_en-US.wxl b/Tools/msi/core/core_en-US.wxl
new file mode 100644
index 0000000..7977470
--- /dev/null
+++ b/Tools/msi/core/core_en-US.wxl
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">Core Interpreter</String>
+ <String Id="ShortDescriptor">core</String>
+</WixLocalization>
diff --git a/Tools/msi/core/core_files.wxs b/Tools/msi/core/core_files.wxs
new file mode 100644
index 0000000..145e147
--- /dev/null
+++ b/Tools/msi/core/core_files.wxs
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <ComponentGroup Id="core_dll">
+ <Component Id="python_stable.dll" Directory="InstallDirectory" Guid="*">
+ <File Id="python_stable.dll" Name="python$(var.MajorVersionNumber).dll" KeyPath="yes" />
+ </Component>
+ <Component Id="python.dll" Directory="InstallDirectory" Guid="*">
+ <File Id="python.dll" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber).dll" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+ <Fragment>
+ <ComponentGroup Id="core_symbols">
+ <Component Id="python.pdb" Directory="InstallDirectory" Guid="*">
+ <File Id="python.pdb" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber).pdb" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+ <Fragment>
+ <ComponentGroup Id="core_dll_d">
+ <Component Id="python_stable_d.dll" Directory="InstallDirectory" Guid="*">
+ <File Id="python_stable_d.dll" Name="python$(var.MajorVersionNumber)_d.dll" KeyPath="yes" />
+ </Component>
+ <Component Id="python_d.dll" Directory="InstallDirectory" Guid="*">
+ <File Id="python_d.dll" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber)_d.dll" KeyPath="yes" />
+ <File Id="python_d.pdb" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber)_d.pdb" KeyPath="no" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/core/core_pdb.wixproj b/Tools/msi/core/core_pdb.wixproj
new file mode 100644
index 0000000..bbf9379
--- /dev/null
+++ b/Tools/msi/core/core_pdb.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{E98E7539-64E7-4DCE-AACD-01E3ADE40EFD}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>core_pdb</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeSymbols=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="core.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/crt/crt.wixproj b/Tools/msi/crt/crt.wixproj
new file mode 100644
index 0000000..8389b3a
--- /dev/null
+++ b/Tools/msi/crt/crt.wixproj
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{91C99298-8E2E-4422-A5AF-CC4FFF9A58D3}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>crt</OutputName>
+ <OutputType>Package</OutputType>
+ <SuppressIces>ICE71</SuppressIces>
+ </PropertyGroup>
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="crt.wxs" />
+ <Compile Include="crt_files.$(VisualStudioVersion).wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/crt/crt.wxs b/Tools/msi/crt/crt.wxs
new file mode 100644
index 0000000..5b10095
--- /dev/null
+++ b/Tools/msi/crt/crt.wxs
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <PropertyRef Id="UpgradeTable" />
+
+ <?if $(var.Platform)~=x64 ?>
+ <?define DirName=System64?>
+ <?else ?>
+ <?define DirName=System?>
+ <?endif ?>
+ <DirectoryRef Id="TARGETDIR">
+ <Directory Id="$(var.DirName)Folder" Name="$(var.DirName)">
+ <Directory Id="SystemInstallDirectory" Name="." />
+ </Directory>
+ </DirectoryRef>
+ <?undef DirName ?>
+
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="crt_files" />
+ </Feature>
+ </Product>
+</Wix>
+
diff --git a/Tools/msi/crt/crt_en-US.wxl b/Tools/msi/crt/crt_en-US.wxl
new file mode 100644
index 0000000..cee3c8a
--- /dev/null
+++ b/Tools/msi/crt/crt_en-US.wxl
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">C Runtime</String>
+ <String Id="ShortDescriptor">crt</String>
+</WixLocalization>
diff --git a/Tools/msi/crt/crt_files.12.0.wxs b/Tools/msi/crt/crt_files.12.0.wxs
new file mode 100644
index 0000000..f62593f
--- /dev/null
+++ b/Tools/msi/crt/crt_files.12.0.wxs
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <?if $(var.Platform)~=x64 ?>
+ <?define msvcr120Guid={0835C947-D6D2-4E52-AF14-0231D04E88EA}?>
+ <?else ?>
+ <?define msvcr120Guid={E5B92048-5859-4AF1-AEAD-B97EBF00B087} ?>
+ <?endif ?>
+ <ComponentGroup Id="crt_files">
+ <Component Id="msvcr120.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.msvcr120Guid)" Shared="yes" SharedDllRefCount="yes">
+ <Condition>ALLUSERS=1</Condition>
+ <File Id="msvcr120.dll_LM" Source="!(bindpath.crt)\msvcr120.dll" />
+ </Component>
+ <Component Id="msvcr120.dll_CU" Directory="InstallDirectory" Guid="*">
+ <Condition>NOT ALLUSERS=1</Condition>
+ <File Id="msvcr120.dll_CU" Source="!(bindpath.crt)\msvcr120.dll" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/crt/crt_files.14.0.wxs b/Tools/msi/crt/crt_files.14.0.wxs
new file mode 100644
index 0000000..be682c9
--- /dev/null
+++ b/Tools/msi/crt/crt_files.14.0.wxs
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <?if $(var.Platform)~=x64 ?>
+ <?define appcrt140Guid={CC160FA9-B519-38EC-B358-B4146E8506C8}?>
+ <?define desktopcrt140Guid={4DB78A79-8D7F-35DD-B0E8-736DE44D25F3}?>
+ <?define vcruntime140Guid={B33258FD-750C-3B42-8BE4-535B48E97DB4}?>
+ <?else ?>
+ <?define appcrt140Guid={E3854F9C-4CFB-3B85-90BD-86AA22D82DC8}?>
+ <?define desktopcrt140Guid={46EAB1CD-C362-3139-BD7E-D8782E65253A}?>
+ <?define vcruntime140Guid={E8E39D3B-4F35-36D8-B892-4B28336FE041}?>
+ <?endif ?>
+ <ComponentGroup Id="crt_files">
+ <Component Id="appcrt140.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.appcrt140Guid)" Shared="yes" SharedDllRefCount="yes">
+ <Condition>ALLUSERS=1</Condition>
+ <File Id="appcrt140.dll_LM" Source="!(bindpath.crt)\appcrt140.dll" />
+ </Component>
+ <Component Id="desktopcrt140.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.desktopcrt140Guid)" Shared="yes" SharedDllRefCount="yes">
+ <Condition>ALLUSERS=1</Condition>
+ <File Id="desktopcrt140.dll_LM" Source="!(bindpath.crt)\desktopcrt140.dll" />
+ </Component>
+ <Component Id="vcruntime140.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.vcruntime140Guid)" Shared="yes" SharedDllRefCount="yes">
+ <Condition>ALLUSERS=1</Condition>
+ <File Id="vcruntime140.dll_LM" Source="!(bindpath.crt)\vcruntime140.dll" />
+ </Component>
+ <Component Id="appcrt140.dll_CU" Directory="InstallDirectory" Guid="*">
+ <Condition>NOT ALLUSERS=1</Condition>
+ <File Id="appcrt140.dll_CU" Source="!(bindpath.crt)\appcrt140.dll" />
+ </Component>
+ <Component Id="desktopcrt140.dll_CU" Directory="InstallDirectory" Guid="*">
+ <Condition>NOT ALLUSERS=1</Condition>
+ <File Id="desktopcrt140.dll_CU" Source="!(bindpath.crt)\desktopcrt140.dll" />
+ </Component>
+ <Component Id="vcruntime140.dll_CU" Directory="InstallDirectory" Guid="*">
+ <Condition>NOT ALLUSERS=1</Condition>
+ <File Id="vcruntime140.dll_CU" Source="!(bindpath.crt)\vcruntime140.dll" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/crt/crtlicense.txt b/Tools/msi/crt/crtlicense.txt
new file mode 100644
index 0000000..1f0f1f9
--- /dev/null
+++ b/Tools/msi/crt/crtlicense.txt
@@ -0,0 +1,47 @@
+
+
+Additional Conditions for this Windows binary build
+---------------------------------------------------
+
+This program is linked with and uses Microsoft Distributable Code,
+copyrighted by Microsoft Corporation. The Microsoft Distributable Code
+includes the following files:
+
+appcrt140.dll
+desktopcrt140.dll
+vcruntime140.dll
+msvcp140.dll
+concrt140.dll
+vccorlib140.dll
+
+If you further distribute programs that include the Microsoft
+Distributable Code, you must comply with the restrictions on
+distribution specified by Microsoft. In particular, you must require
+distributors and external end users to agree to terms that protect the
+Microsoft Distributable Code at least as much as Microsoft's own
+requirements for the Distributable Code. See Microsoft's documentation
+(included in its developer tools and on its website at microsoft.com)
+for specific details.
+
+Redistribution of the Windows binary build of the Python interpreter
+complies with this agreement, provided that you do not:
+
+- alter any copyright, trademark or patent notice in Microsoft's
+Distributable Code;
+
+- use Microsoft's trademarks in your programs' names or in a way that
+suggests your programs come from or are endorsed by Microsoft;
+
+- distribute Microsoft's Distributable Code to run on a platform other
+than Microsoft operating systems, run-time technologies or application
+platforms; or
+
+- include Microsoft Distributable Code in malicious, deceptive or
+unlawful programs.
+
+These restrictions apply only to the Microsoft Distributable Code as
+defined above, not to Python itself or any programs running on the
+Python interpreter. The redistribution of the Python interpreter and
+libraries is governed by the Python Software License included with this
+file, or by other licenses as marked.
+
diff --git a/Tools/msi/csv_to_wxs.py b/Tools/msi/csv_to_wxs.py
new file mode 100644
index 0000000..235c8f8
--- /dev/null
+++ b/Tools/msi/csv_to_wxs.py
@@ -0,0 +1,127 @@
+'''
+Processes a CSV file containing a list of files into a WXS file with
+components for each listed file.
+
+The CSV columns are:
+ source of file, target for file, group name
+
+Usage::
+ py txt_to_wxs.py [path to file list .csv] [path to destination .wxs]
+
+This is necessary to handle structures where some directories only
+contain other directories. MSBuild is not able to generate the
+Directory entries in the WXS file correctly, as it operates on files.
+Python, however, can easily fill in the gap.
+'''
+
+__author__ = "Steve Dower <steve.dower@microsoft.com>"
+
+import csv
+import re
+import sys
+
+from collections import defaultdict
+from itertools import chain, zip_longest
+from pathlib import PureWindowsPath
+from uuid import uuid1
+
+ID_CHAR_SUBS = {
+ '-': '_',
+ '+': '_P',
+}
+
+def make_id(path):
+ return re.sub(
+ r'[^A-Za-z0-9_.]',
+ lambda m: ID_CHAR_SUBS.get(m.group(0), '_'),
+ str(path).rstrip('/\\'),
+ flags=re.I
+ )
+
+DIRECTORIES = set()
+
+def main(file_source, install_target):
+ with open(file_source, 'r', newline='') as f:
+ files = list(csv.reader(f))
+
+ assert len(files) == len(set(make_id(f[1]) for f in files)), "Duplicate file IDs exist"
+
+ directories = defaultdict(set)
+ cache_directories = defaultdict(set)
+ groups = defaultdict(list)
+ for source, target, group, disk_id, condition in files:
+ target = PureWindowsPath(target)
+ groups[group].append((source, target, disk_id, condition))
+
+ if target.suffix.lower() in {".py", ".pyw"}:
+ cache_directories[group].add(target.parent)
+
+ for dirname in target.parents:
+ parent = make_id(dirname.parent)
+ if parent and parent != '.':
+ directories[parent].add(dirname.name)
+
+ lines = [
+ '<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">',
+ ' <Fragment>',
+ ]
+ for dir_parent in sorted(directories):
+ lines.append(' <DirectoryRef Id="{}">'.format(dir_parent))
+ for dir_name in sorted(directories[dir_parent]):
+ lines.append(' <Directory Id="{}_{}" Name="{}" />'.format(dir_parent, make_id(dir_name), dir_name))
+ lines.append(' </DirectoryRef>')
+ for dir_parent in (make_id(d) for group in cache_directories.values() for d in group):
+ lines.append(' <DirectoryRef Id="{}">'.format(dir_parent))
+ lines.append(' <Directory Id="{}___pycache__" Name="__pycache__" />'.format(dir_parent))
+ lines.append(' </DirectoryRef>')
+ lines.append(' </Fragment>')
+
+ for group in sorted(groups):
+ lines.extend([
+ ' <Fragment>',
+ ' <ComponentGroup Id="{}">'.format(group),
+ ])
+ for source, target, disk_id, condition in groups[group]:
+ lines.append(' <Component Id="{}" Directory="{}" Guid="*">'.format(make_id(target), make_id(target.parent)))
+ if condition:
+ lines.append(' <Condition>{}</Condition>'.format(condition))
+
+ if disk_id:
+ lines.append(' <File Id="{}" Name="{}" Source="{}" DiskId="{}" />'.format(make_id(target), target.name, source, disk_id))
+ else:
+ lines.append(' <File Id="{}" Name="{}" Source="{}" />'.format(make_id(target), target.name, source))
+ lines.append(' </Component>')
+
+ create_folders = {make_id(p) + "___pycache__" for p in cache_directories[group]}
+ remove_folders = {make_id(p2) for p1 in cache_directories[group] for p2 in chain((p1,), p1.parents)}
+ create_folders.discard(".")
+ remove_folders.discard(".")
+ if create_folders or remove_folders:
+ lines.append(' <Component Id="{}__pycache__folders" Directory="TARGETDIR" Guid="{}">'.format(group, uuid1()))
+ lines.extend(' <CreateFolder Directory="{}" />'.format(p) for p in create_folders)
+ lines.extend(' <RemoveFile Id="Remove_{0}_files" Name="*" On="uninstall" Directory="{0}" />'.format(p) for p in create_folders)
+ lines.extend(' <RemoveFolder Id="Remove_{0}_folder" On="uninstall" Directory="{0}" />'.format(p) for p in create_folders | remove_folders)
+ lines.append(' </Component>')
+
+ lines.extend([
+ ' </ComponentGroup>',
+ ' </Fragment>',
+ ])
+ lines.append('</Wix>')
+
+ # Check if the file matches. If so, we don't want to touch it so
+ # that we can skip rebuilding.
+ try:
+ with open(install_target, 'r') as f:
+ if all(x.rstrip('\r\n') == y for x, y in zip_longest(f, lines)):
+ print('File is up to date')
+ return
+ except IOError:
+ pass
+
+ with open(install_target, 'w') as f:
+ f.writelines(line + '\n' for line in lines)
+ print('Wrote {} lines to {}'.format(len(lines), install_target))
+
+if __name__ == '__main__':
+ main(sys.argv[1], sys.argv[2])
diff --git a/Tools/msi/dev/dev.props b/Tools/msi/dev/dev.props
new file mode 100644
index 0000000..ca2549d
--- /dev/null
+++ b/Tools/msi/dev/dev.props
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\msi.props" />
+ <PropertyGroup>
+ <DefineConstants Condition="$(BuildForRelease)">
+ $(DefineConstants);
+ IncludeMinGWLib=1;
+ </DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+ <ItemGroup>
+ <InstallFiles Include="$(PySourcePath)include\*.h">
+ <SourceBase>$(PySourcePath)</SourceBase>
+ <Source>!(bindpath.src)</Source>
+ <TargetBase>$(PySourcePath)</TargetBase>
+ <Target_></Target_>
+ <Group>dev_include</Group>
+ </InstallFiles>
+ </ItemGroup>
+
+ <Target Name="BuildMinGWLib"
+ Inputs="$(BuildPath)$(PyDllName).dll"
+ Outputs="$(BuildPath)lib$(PyDllName).a"
+ AfterTargets="PrepareForBuild"
+ Condition="$(BuildForRelease)">
+ <!-- Build libpython##.a as part of this project. This requires gendef and dlltool on the path. -->
+ <PropertyGroup>
+ <_GenDefPlatform>i386</_GenDefPlatform>
+ <_GenDefPlatform Condition="$(Platform) == 'x64'">i386:x86-64</_GenDefPlatform>
+ </PropertyGroup>
+
+ <Exec Command='gendef - "$(BuildPath)$(PyDllName).dll" &gt; "$(IntermediateOutputPath)mingwlib.def"' ContinueOnError="false" />
+ <Exec Command='dlltool --dllname $(PyDllName).dll --def "$(IntermediateOutputPath)mingwlib.def" --output-lib "$(BuildPath)lib$(PyDllName).a" -m $(_GenDefPlatform)' />
+ </Target>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/dev/dev.wixproj b/Tools/msi/dev/dev.wixproj
new file mode 100644
index 0000000..8a2293f
--- /dev/null
+++ b/Tools/msi/dev/dev.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{5F23F608-D74B-4259-A0CE-8DC65CC7FE53}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName Condition="'$(OutputName)' == ''">dev</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDefaultFeature=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="dev.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs
new file mode 100644
index 0000000..48eba6b
--- /dev/null
+++ b/Tools/msi/dev/dev.wxs
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <PropertyRef Id="UpgradeTable" />
+
+ <?ifdef IncludeDefaultFeature ?>
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="dev_include" />
+ <ComponentGroupRef Id="dev_pyconfig" />
+ <ComponentGroupRef Id="dev_libs" />
+<?ifdef IncludeMinGWLib ?>
+ <ComponentGroupRef Id="dev_mingw" />
+<?endif ?>
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeDebugBinaries ?>
+ <Feature Id="DebugBinaries" AllowAdvertise="no" Title="!(loc.Title_d)" Description="!(loc.Description_d)">
+ <ComponentGroupRef Id="dev_libs_d" />
+ </Feature>
+ <?endif ?>
+ </Product>
+</Wix>
diff --git a/Tools/msi/dev/dev_d.wixproj b/Tools/msi/dev/dev_d.wixproj
new file mode 100644
index 0000000..2354d97
--- /dev/null
+++ b/Tools/msi/dev/dev_d.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{C11B4945-76BD-4137-B2E3-649460117A77}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>dev_d</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDebugBinaries=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="dev.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/dev/dev_en-US.wxl b/Tools/msi/dev/dev_en-US.wxl
new file mode 100644
index 0000000..2546e13
--- /dev/null
+++ b/Tools/msi/dev/dev_en-US.wxl
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">Development Libraries</String>
+ <String Id="ShortDescriptor">dev</String>
+</WixLocalization>
diff --git a/Tools/msi/dev/dev_files.wxs b/Tools/msi/dev/dev_files.wxs
new file mode 100644
index 0000000..9654d2e
--- /dev/null
+++ b/Tools/msi/dev/dev_files.wxs
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <ComponentGroup Id="dev_pyconfig">
+ <Component Id="include_pyconfig.h" Directory="include" Guid="*">
+ <File Id="include_pyconfig.h" Name="pyconfig.h" Source="!(bindpath.src)PC\pyconfig.h" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="dev_libs">
+ <Component Id="libs_python3.lib" Directory="libs" Guid="*">
+ <File Id="libs_python_stable.lib" Name="python$(var.MajorVersionNumber).lib" KeyPath="yes" />
+ </Component>
+ <Component Id="libs_python.lib" Directory="libs" Guid="*">
+ <File Id="libs_python.lib" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber).lib" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="dev_libs_d">
+ <Component Id="libs_python3_d.lib" Directory="libs" Guid="*">
+ <File Id="libs_python_stable_d.lib" Name="python$(var.MajorVersionNumber)_d.lib" />
+ </Component>
+ <Component Id="libs_python_d.lib" Directory="libs" Guid="*">
+ <File Id="libs_python_d.lib" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber)_d.lib" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <?ifdef IncludeMinGWLib ?>
+ <Fragment>
+ <ComponentGroup Id="dev_mingw">
+ <Component Id="libs_libpython.a" Directory="libs" Guid="*">
+ <File Id="libs_libpython.a" Name="libpython$(var.MajorVersionNumber)$(var.MinorVersionNumber).a" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+ <?endif ?>
+</Wix>
diff --git a/Tools/msi/doc/doc.wixproj b/Tools/msi/doc/doc.wixproj
new file mode 100644
index 0000000..ea9929a
--- /dev/null
+++ b/Tools/msi/doc/doc.wixproj
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{0D62A2BB-5F71-4447-8C8C-9708407B3674}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>doc</OutputName>
+ <OutputType>Package</OutputType>
+ <!-- Shortcut validation is not necessary -->
+ <SuppressICEs>ICE43</SuppressICEs>
+ </PropertyGroup>
+ <Import Project="..\msi.props" />
+ <PropertyGroup>
+ <DocFilename>python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm</DocFilename>
+ <IncludeDocFile>false</IncludeDocFile>
+ <IncludeDocFile Condition="$(BuildForRelease) or Exists('$(PySourcePath)Doc\build\htmlhelp\$(DocFilename)')">true</IncludeDocFile>
+ </PropertyGroup>
+ <PropertyGroup Condition="$(IncludeDocFile)">
+ <DefineConstants>$(DefineConstants);DocFilename=$(DocFilename);</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="doc.wxs" />
+ <Compile Include="doc_files.wxs" Condition="$(IncludeDocFile)" />
+ <Compile Include="doc_no_files.wxs" Condition="!$(IncludeDocFile)" />
+ </ItemGroup>
+ <ItemGroup>
+ <WxlTemplate Include="*.wxl_template" />
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs
new file mode 100644
index 0000000..6becaf6
--- /dev/null
+++ b/Tools/msi/doc/doc.wxs
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <PropertyRef Id="UpgradeTable" />
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="doc" />
+
+ <Component Id="doc_shortcut" Directory="MenuDir" Guid="*">
+ <RegistryKey Root="HKMU" Key="[REGISTRYKEY]">
+ <RegistryValue Key="Help\Main Python Documentation" Type="string" Value="[#python.chm]" KeyPath="yes" />
+ </RegistryKey>
+ <Shortcut Id="python.chm"
+ Target="[#python.chm]"
+ Name="!(loc.ShortcutName)"
+ Description="!(loc.ShortcutDescription)" />
+ <RemoveFolder Id="Remove_MenuDir" On="uninstall" />
+ </Component>
+
+ </Feature>
+ </Product>
+</Wix>
diff --git a/Tools/msi/doc/doc_en-US.wxl_template b/Tools/msi/doc/doc_en-US.wxl_template
new file mode 100644
index 0000000..09df582
--- /dev/null
+++ b/Tools/msi/doc/doc_en-US.wxl_template
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="ShortDescriptor">doc</String>
+ <String Id="Descriptor">Documentation</String>
+ <String Id="ShortcutName">Python {{ShortVersion}} {{Bitness}} Manuals</String>
+ <String Id="ShortcutDescription">View the !(loc.ProductName) documentation.</String>
+</WixLocalization>
diff --git a/Tools/msi/doc/doc_files.wxs b/Tools/msi/doc/doc_files.wxs
new file mode 100644
index 0000000..b2aabfb
--- /dev/null
+++ b/Tools/msi/doc/doc_files.wxs
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <ComponentGroup Id="doc">
+ <Component Id="python.chm" Directory="Doc" Guid="*">
+ <File Id="python.chm" Name="$(var.DocFilename)" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/doc/doc_no_files.wxs b/Tools/msi/doc/doc_no_files.wxs
new file mode 100644
index 0000000..7ab7c26
--- /dev/null
+++ b/Tools/msi/doc/doc_no_files.wxs
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <ComponentGroup Id="doc">
+ <!--
+ This file is included when the CHM is not available.
+
+ This way, snapshot builds can succeed without having to
+ build the docs.
+ -->
+ <Component Id="EmptyDocFolder" Directory="Doc" Guid="{22FD42DB-EC66-4B1C-B1FC-44E0CF7B2462}">
+ <CreateFolder />
+ <RemoveFolder Id="Remove_EmptyDocFolder" On="uninstall" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/crtlicense.txt b/Tools/msi/exe/crtlicense.txt
index 936bc5a..936bc5a 100644
--- a/Tools/msi/crtlicense.txt
+++ b/Tools/msi/exe/crtlicense.txt
diff --git a/Tools/msi/exe/exe.props b/Tools/msi/exe/exe.props
new file mode 100644
index 0000000..bb9b7d3
--- /dev/null
+++ b/Tools/msi/exe/exe.props
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <!-- Shortcut validation is not necessary -->
+ <SuppressICEs>ICE43</SuppressICEs>
+ </PropertyGroup>
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ <WxlTemplate Include="*.wxl_template" />
+ </ItemGroup>
+
+ <Target Name="_GenerateLicense" AfterTargets="PrepareForBuild">
+ <ItemGroup>
+ <LicenseFiles Include="$(PySourcePath)LICENSE;
+ crtlicense.txt;
+ $(bz2Dir)LICENSE;
+ $(opensslDir)LICENSE;
+ $(tclDir)license.terms;
+ $(tkDir)license.terms;
+ $(tixDir)license.terms" />
+ <_LicenseFiles Include="@(LicenseFiles)">
+ <Content>$([System.IO.File]::ReadAllText(%(FullPath)))</Content>
+ </_LicenseFiles>
+ </ItemGroup>
+
+ <WriteLinesToFile File="$(BuildPath)LICENSE"
+ Overwrite="true"
+ Lines="@(_LicenseFiles->'%(Content)')" />
+ </Target>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj
new file mode 100644
index 0000000..d3ed65a
--- /dev/null
+++ b/Tools/msi/exe/exe.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{6BD53305-B03E-49DC-85FB-5551B8CCC843}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>exe</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDefaultFeature=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="exe.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/exe/exe.wxs b/Tools/msi/exe/exe.wxs
new file mode 100644
index 0000000..7b35836
--- /dev/null
+++ b/Tools/msi/exe/exe.wxs
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <PropertyRef Id="UpgradeTable" />
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <?ifdef IncludeDefaultFeature ?>
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="exe_python" />
+ <ComponentGroupRef Id="exe_txt" />
+ <ComponentGroupRef Id="exe_icons" />
+
+ <Component Id="exe_shortcut" Directory="MenuDir" Guid="*">
+ <Shortcut Id="python.exe"
+ Target="[#python.exe]"
+ Name="!(loc.ShortcutName)"
+ Description="!(loc.ShortcutDescription)" />
+ <RemoveFolder Id="Remove_MenuDir" Directory="MenuDir" On="uninstall" />
+ <RegistryKey Root="HKMU" Key="[REGISTRYKEY]">
+ <RegistryValue Key="InstallPath" Type="string" Value="[InstallDirectory]" KeyPath="yes" />
+ <RegistryValue Key="InstallPath\InstallGroup" Type="string" Value="Python $(var.ShortVersion)" />
+ </RegistryKey>
+ </Component>
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeSymbols ?>
+ <Feature Id="Symbols" AllowAdvertise="no" Title="!(loc.TitlePdb)" Description="!(loc.DescriptionPdb)">
+ <ComponentGroupRef Id="exe_python_symbols" />
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeDebugBinaries ?>
+ <Feature Id="DebugBinaries" AllowAdvertise="no" Title="!(loc.Title_d)" Description="!(loc.Description_d)">
+ <ComponentGroupRef Id="exe_python_d" />
+ </Feature>
+ <?endif ?>
+ </Product>
+</Wix>
diff --git a/Tools/msi/exe/exe_d.wixproj b/Tools/msi/exe/exe_d.wixproj
new file mode 100644
index 0000000..9b57db8
--- /dev/null
+++ b/Tools/msi/exe/exe_d.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{B1CA739C-8DB0-403B-9010-D79507507CE9}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>exe_d</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDebugBinaries=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="exe.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/exe/exe_en-US.wxl_template b/Tools/msi/exe/exe_en-US.wxl_template
new file mode 100644
index 0000000..cc60ef6
--- /dev/null
+++ b/Tools/msi/exe/exe_en-US.wxl_template
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">Executables</String>
+ <String Id="ShortDescriptor">executable</String>
+ <String Id="ShortcutName">Python {{ShortVersion}} ({{Bitness}})</String>
+ <String Id="ShortcutDescription">Launches the !(loc.ProductName) interpreter.</String>
+ <String Id="PathTitle">Add to PATH</String>
+ <String Id="PathDescription">Adds the install directory to PATH and .py to PATHEXT.</String>
+</WixLocalization>
diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs
new file mode 100644
index 0000000..4091398
--- /dev/null
+++ b/Tools/msi/exe/exe_files.wxs
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <ComponentGroup Id="exe_txt">
+ <Component Id="LICENSE.txt" Directory="InstallDirectory" Guid="*">
+ <File Name="LICENSE.txt" Source="LICENSE" KeyPath="yes" />
+ </Component>
+ <Component Id="NEWS.txt" Directory="InstallDirectory" Guid="*">
+ <File Name="NEWS.txt" Source="!(bindpath.src)Misc\NEWS" KeyPath="yes" />
+ </Component>
+ <Component Id="README.txt" Directory="InstallDirectory" Guid="*">
+ <File Name="README.txt" Source="!(bindpath.src)README" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <ComponentGroup Id="exe_python">
+ <Component Id="python.exe" Directory="InstallDirectory" Guid="$(var.PythonExeComponentGuid)">
+ <File Name="python.exe" KeyPath="yes" />
+ </Component>
+ <Component Id="pythonw.exe" Directory="InstallDirectory" Guid="$(var.PythonwExeComponentGuid)">
+ <File Name="pythonw.exe" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="exe_python_symbols">
+ <Component Id="python.pdb" Directory="InstallDirectory" Guid="*">
+ <File Name="python.pdb" />
+ </Component>
+ <Component Id="pythonw.pdb" Directory="InstallDirectory" Guid="*">
+ <File Name="pythonw.pdb" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="exe_python_d">
+ <Component Id="python_d.exe" Directory="InstallDirectory" Guid="*">
+ <File Name="python_d.exe" />
+ </Component>
+ <Component Id="python_d.pdb" Directory="InstallDirectory" Guid="*">
+ <File Name="python_d.pdb" />
+ </Component>
+ <Component Id="pythonw_d.exe" Directory="InstallDirectory" Guid="*">
+ <File Name="pythonw_d.exe" />
+ </Component>
+ <Component Id="pythonw_d.pdb" Directory="InstallDirectory" Guid="*">
+ <File Name="pythonw_d.pdb" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="exe_icons">
+ <Component Id="py.ico" Directory="DLLs" Guid="*">
+ <File Name="py.ico" Source="!(bindpath.src)PC\py.ico" KeyPath="yes" />
+ </Component>
+ <Component Id="pyc.ico" Directory="DLLs" Guid="*">
+ <File Name="pyc.ico" Source="!(bindpath.src)PC\pyc.ico" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/exe/exe_pdb.wixproj b/Tools/msi/exe/exe_pdb.wixproj
new file mode 100644
index 0000000..dae3d0c
--- /dev/null
+++ b/Tools/msi/exe/exe_pdb.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{4A1F7045-8EE2-4276-ABB8-5E0C40E5F38B}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>exe_pdb</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeSymbols=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="exe.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/get_wix.py b/Tools/msi/get_wix.py
new file mode 100644
index 0000000..85b02f2
--- /dev/null
+++ b/Tools/msi/get_wix.py
@@ -0,0 +1,49 @@
+'''
+Downloads and extracts WiX to a local directory
+'''
+
+__author__ = 'Steve Dower <steve.dower@microsoft.com>'
+
+import io
+import os
+import sys
+
+from pathlib import Path
+from subprocess import Popen
+from zipfile import ZipFile
+
+EXTERNALS_DIR = None
+for p in Path(__file__).parents:
+ if any(p.glob("PCBuild/*.vcxproj")):
+ EXTERNALS_DIR = p / "externals"
+ break
+
+if not EXTERNALS_DIR:
+ print("Cannot find project root")
+ sys.exit(1)
+
+WIX_BINARIES_ZIP = 'http://wixtoolset.org/downloads/v3.10.1124.0/wix310-binaries.zip'
+TARGET_BIN_ZIP = EXTERNALS_DIR / "wix.zip"
+TARGET_BIN_DIR = EXTERNALS_DIR / "wix"
+
+POWERSHELL_COMMAND = "[IO.File]::WriteAllBytes('{}', (Invoke-WebRequest {} -UseBasicParsing).Content)"
+
+if __name__ == '__main__':
+ if TARGET_BIN_DIR.exists() and any(TARGET_BIN_DIR.glob("*")):
+ print('WiX is already installed')
+ sys.exit(0)
+
+ try:
+ TARGET_BIN_DIR.mkdir()
+ except FileExistsError:
+ pass
+
+ print('Downloading WiX to', TARGET_BIN_ZIP)
+ p = Popen(["powershell.exe", "-Command", POWERSHELL_COMMAND.format(TARGET_BIN_ZIP, WIX_BINARIES_ZIP)])
+ p.wait()
+ print('Extracting WiX to', TARGET_BIN_DIR)
+ with ZipFile(str(TARGET_BIN_ZIP)) as z:
+ z.extractall(str(TARGET_BIN_DIR))
+ TARGET_BIN_ZIP.unlink()
+
+ print('Extracted WiX')
diff --git a/Tools/msi/launcher/launcher.props b/Tools/msi/launcher/launcher.props
new file mode 100644
index 0000000..b145efe
--- /dev/null
+++ b/Tools/msi/launcher/launcher.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/launcher/launcher.wixproj b/Tools/msi/launcher/launcher.wixproj
new file mode 100644
index 0000000..2d06df0
--- /dev/null
+++ b/Tools/msi/launcher/launcher.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{921CF0E6-AEBC-4376-BA1D-CD46EBFE6DA5}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>launcher</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDefaultFeature=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="launcher.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/launcher/launcher.wxs b/Tools/msi/launcher/launcher.wxs
new file mode 100644
index 0000000..fe88ba5
--- /dev/null
+++ b/Tools/msi/launcher/launcher.wxs
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <Property Id="Suppress_TARGETDIR_Check" Value="1" />
+ <PropertyRef Id="UpgradeTable" />
+ <PropertyRef Id="ARPPRODUCTICON" />
+
+ <?ifdef IncludeDefaultFeature ?>
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="launcher_exe" Primary="yes" />
+ </Feature>
+ <Feature Id="AssociateFiles" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="launcher_exe" />
+ <ComponentGroupRef Id="launcher_reg" />
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeSymbols ?>
+ <Feature Id="Symbols" AllowAdvertise="no" Title="!(loc.TitlePdb)" Description="!(loc.DescriptionPdb)">
+ <ComponentGroupRef Id="launcher_pdb" />
+ </Feature>
+ <?endif ?>
+
+ <Directory Id="TARGETDIR" Name="SourceDir">
+ <Directory Id="LauncherInstallDirectory" />
+ </Directory>
+
+ <CustomAction Id="SetLauncherInstallDirectoryLM" Property="LauncherInstallDirectory" Value="[WindowsFolder]" />
+ <CustomAction Id="SetLauncherInstallDirectoryCU" Property="LauncherInstallDirectory" Value="[LocalAppDataFolder]Programs\Python\Launcher" />
+
+ <InstallExecuteSequence>
+ <Custom Before="SetLauncherInstallDirectoryLM" Action="SetLauncherInstallDirectoryCU">NOT Installed AND NOT ALLUSERS=1</Custom>
+ <Custom Before="CostFinalize" Action="SetLauncherInstallDirectoryLM">NOT Installed AND ALLUSERS=1</Custom>
+ </InstallExecuteSequence>
+ </Product>
+</Wix>
diff --git a/Tools/msi/launcher/launcher_en-US.wxl b/Tools/msi/launcher/launcher_en-US.wxl
new file mode 100644
index 0000000..a88f221
--- /dev/null
+++ b/Tools/msi/launcher/launcher_en-US.wxl
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">Launcher</String>
+ <String Id="ShortDescriptor">launcher</String>
+ <String Id="PythonFileDescription">Python File</String>
+ <String Id="PythonNoConFileDescription">Python File (no console)</String>
+ <String Id="PythonCompiledFileDescription">Compiled Python File</String>
+</WixLocalization>
diff --git a/Tools/msi/launcher/launcher_files.wxs b/Tools/msi/launcher/launcher_files.wxs
new file mode 100644
index 0000000..65f1193
--- /dev/null
+++ b/Tools/msi/launcher/launcher_files.wxs
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <ComponentGroup Id="launcher_exe">
+ <Component Id="py.exe" Directory="LauncherInstallDirectory" Guid="{B5107402-6958-461B-8B0A-4037D3327160}">
+ <File Id="py.exe" Name="py.exe" Source="py.exe" KeyPath="yes" />
+ </Component>
+ <Component Id="pyw.exe" Directory="LauncherInstallDirectory" Guid="{8E52B8CD-48BB-4D74-84CD-6238BCD11F20}">
+ <File Id="pyw.exe" Name="pyw.exe" Source="pyw.exe" KeyPath="yes" />
+ </Component>
+
+ <Component Id="launcher_path_cu" Directory="LauncherInstallDirectory" Guid="{95AEB930-367C-475C-A17E-A89BFCD4C670}">
+ <Condition>NOT ALLUSERS=1</Condition>
+
+ <RegistryValue KeyPath="yes" Root="HKMU" Key="Software\Python\PyLauncher\InstallDir" Value="[LauncherInstallDirectory]" Type="string" />
+ <Environment Id="PATH_CU" Action="set" Name="PATH" Part="first" Value="[LauncherInstallDirectory]" />
+ </Component>
+ <Component Id="launcher_path_lm" Directory="LauncherInstallDirectory" Guid="{4A41C365-4E27-4D38-A6D1-4A01B4A6500C}">
+ <Condition>ALLUSERS=1</Condition>
+ <RegistryValue KeyPath="yes" Root="HKMU" Key="Software\Python\PyLauncher\InstallDir" Value="[LauncherInstallDirectory]" Type="string" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="launcher_pdb">
+ <Component Id="py.pdb" Directory="LauncherInstallDirectory" Guid="*">
+ <File Id="py.pdb" Name="py.pdb" Source="py.pdb" />
+ </Component>
+ <Component Id="pyw.pdb" Directory="LauncherInstallDirectory" Guid="*">
+ <File Id="pyw.pdb" Name="pyw.pdb" Source="pyw.pdb" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/launcher/launcher_pdb.wixproj b/Tools/msi/launcher/launcher_pdb.wixproj
new file mode 100644
index 0000000..3efdd7f
--- /dev/null
+++ b/Tools/msi/launcher/launcher_pdb.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{A21D4A23-483F-4822-A0B1-FCB14D8CEBA7}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>launcher_pdb</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeSymbols=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="launcher.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/launcher/launcher_reg.wxs b/Tools/msi/launcher/launcher_reg.wxs
new file mode 100644
index 0000000..aab3d11
--- /dev/null
+++ b/Tools/msi/launcher/launcher_reg.wxs
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <ComponentGroup Id="launcher_reg">
+ <Component Id="file_association" Directory="LauncherInstallDirectory" Guid="{5AF84D9A-D820-456B-B230-6E0105A50276}">
+ <RegistryValue KeyPath="yes" Root="HKMU" Key="Software\Python\PyLauncher\AssociateFiles" Value="1" Type="integer" />
+
+ <ProgId Id="$(var.TestPrefix)Python.File" Description="!(loc.PythonFileDescription)" Advertise="no" Icon="py.exe" IconIndex="1">
+ <Extension Id="$(var.FileExtension)" ContentType="text/plain">
+ <Verb Id="open" TargetFile="py.exe" Argument="&quot;%L&quot; %*" />
+ </Extension>
+ </ProgId>
+ <RegistryValue Root="HKCR" Key="$(var.TestPrefix)Python.File\shellex\DropHandler" Value="{60254CA5-953B-11CF-8C96-00AA00B8708C}" Type="string" />
+
+ <ProgId Id="$(var.TestPrefix)Python.NoConFile" Description="!(loc.PythonNoConFileDescription)" Advertise="no" Icon="py.exe" IconIndex="1">
+ <Extension Id="$(var.FileExtension)w" ContentType="text/plain">
+ <Verb Id="open" TargetFile="pyw.exe" Argument="&quot;%L&quot; %*" />
+ </Extension>
+ </ProgId>
+ <RegistryValue Root="HKCR" Key="$(var.TestPrefix)Python.NoConFile\shellex\DropHandler" Value="{60254CA5-953B-11CF-8C96-00AA00B8708C}" Type="string" />
+
+ <ProgId Id="$(var.TestPrefix)Python.CompiledFile" Description="!(loc.PythonCompiledFileDescription)" Advertise="no" Icon="py.exe" IconIndex="2">
+ <Extension Id="$(var.FileExtension)c">
+ <Verb Id="open" TargetFile="py.exe" Argument="&quot;%L&quot; %*" />
+ </Extension>
+ <Extension Id="$(var.FileExtension)o" />
+ </ProgId>
+ <RegistryValue Root="HKCR" Key="$(var.TestPrefix)Python.CompiledFile\shellex\DropHandler" Value="{60254CA5-953B-11CF-8C96-00AA00B8708C}" Type="string" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/lib/lib.props b/Tools/msi/lib/lib.props
new file mode 100644
index 0000000..413ba0c
--- /dev/null
+++ b/Tools/msi/lib/lib.props
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+ <ItemGroup>
+ <ExcludeFolders Include="Lib\test;Lib\tests;Lib\tkinter;Lib\idlelib;Lib\turtledemo" />
+ <InstallFiles Include="$(PySourcePath)Lib\**\*"
+ Exclude="$(PySourcePath)Lib\**\*.pyc;
+ $(PySourcePath)Lib\**\*.pyo;
+ $(PySourcePath)Lib\site-packages\README;
+ @(ExcludeFolders->'$(PySourcePath)%(Identity)\*');
+ @(ExcludeFolders->'$(PySourcePath)%(Identity)\**\*')">
+ <SourceBase>$(PySourcePath)Lib</SourceBase>
+ <Source>!(bindpath.src)Lib\</Source>
+ <TargetBase>$(PySourcePath)Lib</TargetBase>
+ <Target_>Lib\</Target_>
+ <Group>lib_py</Group>
+ </InstallFiles>
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/lib/lib.wixproj b/Tools/msi/lib/lib.wixproj
new file mode 100644
index 0000000..e9281da
--- /dev/null
+++ b/Tools/msi/lib/lib.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{11367E76-3337-4602-8F1E-77DB4F370D7E}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>lib</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDefaultFeature=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="lib.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs
new file mode 100644
index 0000000..89bea62
--- /dev/null
+++ b/Tools/msi/lib/lib.wxs
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+ <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+
+ <PropertyRef Id="UpgradeTable" />
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <?ifdef IncludeDefaultFeature ?>
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <ComponentGroupRef Id="lib_py" />
+ <ComponentGroupRef Id="lib_files" />
+ <ComponentGroupRef Id="lib_extensions" />
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeSymbols ?>
+ <Feature Id="Symbols" AllowAdvertise="no" Title="!(loc.TitlePdb)" Description="!(loc.DescriptionPdb)">
+ <ComponentGroupRef Id="lib_extensions_symbols" />
+ </Feature>
+ <?endif ?>
+ <?ifdef IncludeDebugBinaries ?>
+ <Feature Id="DebugBinaries" AllowAdvertise="no" Title="!(loc.Title_d)" Description="!(loc.Description_d)">
+ <ComponentGroupRef Id="lib_extensions_d" />
+ </Feature>
+ <?endif ?>
+ </Product>
+</Wix>
diff --git a/Tools/msi/lib/lib_d.wixproj b/Tools/msi/lib/lib_d.wixproj
new file mode 100644
index 0000000..e632319
--- /dev/null
+++ b/Tools/msi/lib/lib_d.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{6C443CD3-8258-4335-BA03-49DA9C34CE4D}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>lib_d</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeDebugBinaries=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="lib.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/lib/lib_en-US.wxl b/Tools/msi/lib/lib_en-US.wxl
new file mode 100644
index 0000000..305bcc7
--- /dev/null
+++ b/Tools/msi/lib/lib_en-US.wxl
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">Standard Library</String>
+ <String Id="ShortDescriptor">lib</String>
+</WixLocalization>
diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs
new file mode 100644
index 0000000..0c901d3
--- /dev/null
+++ b/Tools/msi/lib/lib_files.wxs
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3 ?>
+ <Fragment>
+ <ComponentGroup Id="lib_extensions">
+ <?foreach ext in $(var.exts)?>
+
+ <Component Id="$(var.ext).pyd" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext).pyd" KeyPath="yes" />
+ </Component>
+
+ <?endforeach ?>
+
+ <Component Id="sqlite3.dll" Directory="DLLs" Guid="*">
+ <File Name="sqlite3.dll" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="lib_extensions_symbols">
+ <?foreach ext in $(var.exts)?>
+
+ <Component Id="$(var.ext).pdb" Directory="DLLs" Guid="*">
+ <Condition>SYMBOLS=1</Condition>
+ <File Name="$(var.ext).pdb" />
+ </Component>
+
+ <?endforeach ?>
+
+ <Component Id="sqlite3.pdb" Directory="DLLs" Guid="*">
+ <File Name="sqlite3.pdb" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+
+ <Fragment>
+ <ComponentGroup Id="lib_extensions_d">
+ <?foreach ext in $(var.exts)?>
+
+ <Component Id="$(var.ext)_d.pyd" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext)_d.pyd" />
+ </Component>
+ <Component Id="$(var.ext)_d.pdb" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext)_d.pdb" />
+ </Component>
+
+ <?endforeach ?>
+ </ComponentGroup>
+ </Fragment>
+ <Fragment>
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <ComponentGroup Id="lib_files">
+ <Component Id="PythonPathRegistry" Directory="Lib" Guid="*">
+ <RegistryKey Root="HKMU" Key="[REGISTRYKEY]">
+ <RegistryValue Key="PythonPath" Type="string" Value="[Lib];[DLLs]" />
+ </RegistryKey>
+ </Component>
+ <Component Id="Lib_site_packages_README" Directory="Lib_site_packages" Guid="*">
+ <File Id="Lib_site_packages_README" Name="README.txt" Source="!(bindpath.src)Lib\site-packages\README" KeyPath="yes" />
+ </Component>
+ <Component Id="Lib2to3_pickle_remove" Directory="Lib_lib2to3" Guid="$(var.RemoveLib2to3PickleComponentGuid)">
+ <RemoveFile Id="Lib2to3_pickle_remove_files" Name="*.pickle" On="uninstall" />
+ <RemoveFolder Id="Lib2to3_pickle_remove_folder" On="uninstall" />
+ </Component>
+ </ComponentGroup>
+ <DirectoryRef Id="Lib">
+ <Directory Id="Lib_site_packages" Name="site-packages" />
+ </DirectoryRef>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/lib/lib_pdb.wixproj b/Tools/msi/lib/lib_pdb.wixproj
new file mode 100644
index 0000000..21b5912
--- /dev/null
+++ b/Tools/msi/lib/lib_pdb.wixproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{5E0BCE93-D1AC-4591-BBCB-3A2BE5A4B3D1}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>lib_pdb</OutputName>
+ <OutputType>Package</OutputType>
+ <DefineConstants>IncludeSymbols=1;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <Import Project="lib.props" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props
new file mode 100644
index 0000000..5c02fd4
--- /dev/null
+++ b/Tools/msi/msi.props
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="ReleaseUri">
+ <PropertyGroup>
+ <DefineSolutionProperties>false</DefineSolutionProperties>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <SuppressIces>$(SuppressIces);ICE03;ICE57;ICE61</SuppressIces>
+ <CompilerSuppressSpecificWarnings>1026</CompilerSuppressSpecificWarnings>
+ <BuildForRelease Condition="'$(BuildForRelease)' == ''">false</BuildForRelease>
+ <SignOutput Condition="'$(SigningCertificate)' != ''">true</SignOutput>
+ <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
+ <Platform Condition="'$(Platform)' == ''">x86</Platform>
+ <InstallScope Condition="'$(InstallScope)' != 'perMachine'">perUser</InstallScope>
+ <!--
+ This URI is used to generate the various GUIDs used by the installer.
+ Installers built with the same URI will upgrade each other or block
+ when attempting to downgrade.
+
+ By default, this is the local computer name, which will produce
+ installers that do not interfere with other installers. Products
+ that intend to bundle Python should rebuild these modules with their
+ own URI to avoid conflicting with the official releases.
+
+ The official releases are built with http://www.python.org/.
+
+ This is not the same as the DownloadUrl property used in the bundle
+ projects.
+ -->
+ <ReleaseUri Condition="'$(ReleaseUri)' == ''">$(ComputerName)</ReleaseUri>
+ <ReleaseUri Condition="!$(ReleaseUri.EndsWith(`/`))">$(ReleaseUri)/</ReleaseUri>
+ </PropertyGroup>
+
+ <Import Project="wix.props" />
+ <Import Project="..\..\PCBuild\tcltk.props" />
+
+ <ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)common.wxs" />
+ <WxlTemplate Include="$(MSBuildThisFileDirectory)\*.wxl_template" />
+ <WixExtension Include="WixUtilExtension">
+ <HintPath>WixUtilExtension</HintPath>
+ <Name>WixUtilExtension</Name>
+ </WixExtension>
+ </ItemGroup>
+
+ <PropertyGroup>
+ <IntermediateOutputPath>$(MSBuildThisFileDirectory)\obj\$(Configuration)_$(Platform)\$(OutputName)</IntermediateOutputPath>
+ <IntermediateOutputPath Condition="'$(OutputSuffix)' != ''">$(IntermediateOutputPath)_$(OutputSuffix)</IntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)' == ''">$(BuildPath)</OutputPath>
+ <OutputPath Condition="!HasTrailingSlash($(OutputPath))">$(OutputPath)\</OutputPath>
+ <OutDir>$(OutputPath)</OutDir>
+ <ReuseCabinetCache>true</ReuseCabinetCache>
+ <CRTModule Condition="'$(VisualStudioVersion)' == '12.0'">$(CommonProgramFiles)\Merge Modules\Microsoft_VC120_CRT_$(Platform).msm</CRTModule>
+ <CRTModule Condition="'$(VisualStudioVersion)' == '14.0'">$(CommonProgramFiles)\Merge Modules\Microsoft_VC140_CRT_$(Platform).msm</CRTModule>
+ <CRTRedist Condition="'$(VisualStudioVersion)' == '12.0'">$([System.IO.Path]::GetFullPath(`$(VS120COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC120.CRT`))</CRTRedist>
+ <CRTRedist Condition="'$(VisualStudioVersion)' == '14.0'">$([System.IO.Path]::GetFullPath(`$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT`))</CRTRedist>
+ <CRTRedist Condition="'$(CRTRedist)' != '' and !Exists($(CRTRedist))"></CRTRedist>
+
+ <RevisionNumber>$(ReleaseLevelNumber)</RevisionNumber>
+ <RevisionNumber Condition="!$(BuildForRelease)">$([System.Math]::Floor($([System.DateTime]::Now.Subtract($([System.DateTime]::new(2001, 1, 1))).TotalDays)))</RevisionNumber>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <Bitness>32-bit</Bitness>
+ <Bitness Condition="$(Platform) == 'x64'">64-bit</Bitness>
+ <DefineConstants>
+ $(DefineConstants);
+ Version=$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber);
+ ShortVersion=$(MajorVersionNumber).$(MinorVersionNumber);
+ LongVersion=$(PythonVersion);
+ MajorVersionNumber=$(MajorVersionNumber);
+ MinorVersionNumber=$(MinorVersionNumber);
+ UpgradeMinimumVersion=$(MajorVersionNumber).$(MinorVersionNumber).0.0;
+ UpgradeMaximumVersion=$(MajorVersionNumber).$(MinorVersionNumber).150.0;
+ NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0;
+ PyDebugExt=$(PyDebugExt);
+ </DefineConstants>
+ <DefineConstants Condition="'$(CRTModule)' != '' and Exists($(CRTModule))">
+ $(DefineConstants);CRTModule=$(CRTModule);
+ </DefineConstants>
+ <DefineConstants Condition="'$(CRTRedist)' != ''">
+ $(DefineConstants);CRTRedist=$(CRTRedist);
+ </DefineConstants>
+ <DefineConstants Condition="$(Configuration) != 'Debug'">
+ $(DefineConstants);TestPrefix=;FileExtension=py;
+ </DefineConstants>
+ <DefineConstants Condition="$(Configuration) == 'Debug'">
+ $(DefineConstants);TestPrefix=x;FileExtension=px;
+ </DefineConstants>
+ <DefineConstants Condition="$(Platform) != 'x64'">
+ $(DefineConstants);Suffix32=-32;
+ </DefineConstants>
+ <DefineConstants Condition="$(Platform) == 'x64'">
+ $(DefineConstants);Suffix32=;
+ </DefineConstants>
+ </PropertyGroup>
+
+ <ItemDefinitionGroup>
+ <InstallFiles>
+ <Group>generated_filelist</Group>
+ <Condition></Condition>
+ <DiskId></DiskId>
+ </InstallFiles>
+ <LinkerBindInputPaths>
+ <Visible>false</Visible>
+ </LinkerBindInputPaths>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <LinkerBindInputPaths Include="$(BuildPath);$(PySourcePath)Doc\build\htmlhelp">
+ <BindName></BindName>
+ </LinkerBindInputPaths>
+ <LinkerBindInputPaths Include="$(PySourcePath)">
+ <BindName>src</BindName>
+ </LinkerBindInputPaths>
+ <LinkerBindInputPaths Include="$(tcltkDir)">
+ <BindName>tcltk</BindName>
+ </LinkerBindInputPaths>
+ <LinkerBindInputPaths Include="$(CRTRedist)" Condition="'$(CRTRedist)' != ''">
+ <BindName>crt</BindName>
+ </LinkerBindInputPaths>
+ </ItemGroup>
+
+ <Target Name="_ValidateMsiProps" BeforeTargets="PrepareForBuild">
+ <Error Text="Platform '$(Platform)' is not supported. Use 'x86' or 'x64'." Condition="$(Platform) != 'x86' and $(Platform) != 'x64'" />
+ </Target>
+
+ <ItemGroup>
+ <_Uuid Include="CoreUpgradeCode">
+ <Uri>upgradecode</Uri>
+ </_Uuid>
+ <_Uuid Include="UpgradeCode">
+ <Uri>upgradecode/$(OutputName)</Uri>
+ </_Uuid>
+ <_Uuid Include="InstallDirectoryGuidSeed">
+ <Uri>installdirectoryseed</Uri>
+ </_Uuid>
+ <_Uuid Include="PythonExeComponentGuid">
+ <Uri>python.exe</Uri>
+ </_Uuid>
+ <_Uuid Include="PythonwExeComponentGuid">
+ <Uri>pythonw.exe</Uri>
+ </_Uuid>
+ <_Uuid Include="RemoveLib2to3PickleComponentGuid">
+ <Uri>lib2to3/pickles</Uri>
+ </_Uuid>
+ </ItemGroup>
+ <Target Name="_GenerateGuids" AfterTargets="PrepareForBuild">
+ <PropertyGroup>
+ <_Uuids>@(_Uuid->'("%(Identity)", "%(Uri)")',',')</_Uuids>
+ <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri)' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))]))</_GenerateCommand>
+ </PropertyGroup>
+
+ <Exec Command='"$(PythonExe)" -c "$(_GenerateCommand)" &gt; "$(IntermediateOutputPath)$(OutputName)guids.txt"' IgnoreExitCode="false" />
+
+ <ReadLinesFromFile File="$(IntermediateOutputPath)$(OutputName)guids.txt">
+ <Output TaskParameter="Lines" ItemName="_UuidValue" />
+ </ReadLinesFromFile>
+
+ <PropertyGroup>
+ <DefineConstants>$(DefineConstants);@(_UuidValue,';');</DefineConstants>
+ </PropertyGroup>
+ </Target>
+</Project> \ No newline at end of file
diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py
deleted file mode 100644
index 6616613..0000000
--- a/Tools/msi/msi.py
+++ /dev/null
@@ -1,1454 +0,0 @@
-# Python MSI Generator
-# (C) 2003 Martin v. Loewis
-# See "FOO" in comments refers to MSDN sections with the title FOO.
-import msilib, schema, sequence, os, glob, time, re, shutil, zipfile
-import subprocess, tempfile
-from msilib import Feature, CAB, Directory, Dialog, Binary, add_data
-import uisample
-from win32com.client import constants
-from distutils.spawn import find_executable
-
-# Settings can be overridden in config.py below
-# 0 for official python.org releases
-# 1 for intermediate releases by anybody, with
-# a new product code for every package.
-snapshot = 1
-# 1 means that file extension is px, not py,
-# and binaries start with x
-testpackage = 0
-# Location of build tree
-srcdir = os.path.abspath("../..")
-# Text to be displayed as the version in dialogs etc.
-# goes into file name and ProductCode. Defaults to
-# current_version.day for Snapshot, current_version otherwise
-full_current_version = None
-# Is Tcl available at all?
-have_tcl = True
-# path to PCbuild directory
-PCBUILD="PCbuild"
-# msvcrt version
-MSVCR = "100"
-# Name of certificate in default store to sign MSI with
-certname = None
-# Make a zip file containing the PDB files for this build?
-pdbzip = True
-
-try:
- from config import *
-except ImportError:
- pass
-
-# Extract current version from Include/patchlevel.h
-lines = open(srcdir + "/Include/patchlevel.h").readlines()
-major = minor = micro = level = serial = None
-levels = {
- 'PY_RELEASE_LEVEL_ALPHA':0xA,
- 'PY_RELEASE_LEVEL_BETA': 0xB,
- 'PY_RELEASE_LEVEL_GAMMA':0xC,
- 'PY_RELEASE_LEVEL_FINAL':0xF
- }
-for l in lines:
- if not l.startswith("#define"):
- continue
- l = l.split()
- if len(l) != 3:
- continue
- _, name, value = l
- if name == 'PY_MAJOR_VERSION': major = value
- if name == 'PY_MINOR_VERSION': minor = value
- if name == 'PY_MICRO_VERSION': micro = value
- if name == 'PY_RELEASE_LEVEL': level = levels[value]
- if name == 'PY_RELEASE_SERIAL': serial = value
-
-short_version = major+"."+minor
-# See PC/make_versioninfo.c
-FIELD3 = 1000*int(micro) + 10*level + int(serial)
-current_version = "%s.%d" % (short_version, FIELD3)
-
-# This should never change. The UpgradeCode of this package can be
-# used in the Upgrade table of future packages to make the future
-# package replace this one. See "UpgradeCode Property".
-# upgrade_code gets set to upgrade_code_64 when we have determined
-# that the target is Win64.
-upgrade_code_snapshot='{92A24481-3ECB-40FC-8836-04B7966EC0D5}'
-upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'
-upgrade_code_64='{6A965A0C-6EE6-4E3A-9983-3263F56311EC}'
-
-if snapshot:
- current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24))
-
-if full_current_version is None:
- full_current_version = current_version
-
-extensions = [
- 'pyexpat.pyd',
- 'select.pyd',
- 'unicodedata.pyd',
- 'winsound.pyd',
- '_bz2.pyd',
- '_elementtree.pyd',
- '_socket.pyd',
- '_ssl.pyd',
- '_testcapi.pyd',
- '_tkinter.pyd',
- '_msi.pyd',
- '_ctypes.pyd',
- '_ctypes_test.pyd',
- '_sqlite3.pyd',
- '_hashlib.pyd',
- '_multiprocessing.pyd',
- '_lzma.pyd',
- '_decimal.pyd',
- '_testbuffer.pyd',
- '_testimportmultiple.pyd',
- '_overlapped.pyd',
-]
-
-# Well-known component UUIDs
-# These are needed for SharedDLLs reference counter; if
-# a different UUID was used for each incarnation of, say,
-# python24.dll, an upgrade would set the reference counter
-# from 1 to 2 (due to what I consider a bug in MSI)
-# Using the same UUID is fine since these files are versioned,
-# so Installer will always keep the newest version.
-# NOTE: All uuids are self generated.
-pythondll_uuid = {
- "24":"{9B81E618-2301-4035-AC77-75D9ABEB7301}",
- "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}",
- "26":"{34ebecac-f046-4e1c-b0e3-9bac3cdaacfa}",
- "27":"{4fe21c76-1760-437b-a2f2-99909130a175}",
- "30":"{6953bc3b-6768-4291-8410-7914ce6e2ca8}",
- "31":"{4afcba0b-13e4-47c3-bebe-477428b46913}",
- "32":"{3ff95315-1096-4d31-bd86-601d5438ad5e}",
- "33":"{f7581ca4-d368-4eea-8f82-d48c64c4f047}",
- "34":"{7A0C5812-2583-40D9-BCBB-CD7485F11377}",
- } [major+minor]
-
-# Compute the name that Sphinx gives to the docfile
-docfile = micro
-if level < 0xf:
- if level == 0xC:
- docfile += "rc%s" % (serial,)
- else:
- docfile += '%x%s' % (level, serial)
-docfile = 'python%s%s%s.chm' % (major, minor, docfile)
-
-# Build the mingw import library, libpythonXY.a
-# This requires 'nm' and 'dlltool' executables on your PATH
-def build_mingw_lib(lib_file, def_file, dll_file, mingw_lib):
- warning = "WARNING: %s - libpythonXX.a not built"
- nm = find_executable('nm')
- dlltool = find_executable('dlltool')
-
- if not nm or not dlltool:
- print(warning % "nm and/or dlltool were not found")
- return False
-
- nm_command = '%s -Cs %s' % (nm, lib_file)
- dlltool_command = "%s --dllname %s --def %s --output-lib %s" % \
- (dlltool, dll_file, def_file, mingw_lib)
- export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match
-
- f = open(def_file,'w')
- f.write("LIBRARY %s\n" % dll_file)
- f.write("EXPORTS\n")
-
- nm_pipe = os.popen(nm_command)
- for line in nm_pipe.readlines():
- m = export_match(line)
- if m:
- f.write(m.group(1)+"\n")
- f.close()
- exit = nm_pipe.close()
-
- if exit:
- print(warning % "nm did not run successfully")
- return False
-
- if os.system(dlltool_command) != 0:
- print(warning % "dlltool did not run successfully")
- return False
-
- return True
-
-# Target files (.def and .a) go in PCBuild directory
-lib_file = os.path.join(srcdir, PCBUILD, "python%s%s.lib" % (major, minor))
-def_file = os.path.join(srcdir, PCBUILD, "python%s%s.def" % (major, minor))
-dll_file = "python%s%s.dll" % (major, minor)
-mingw_lib = os.path.join(srcdir, PCBUILD, "libpython%s%s.a" % (major, minor))
-
-have_mingw = build_mingw_lib(lib_file, def_file, dll_file, mingw_lib)
-
-# Determine the target architecture
-if os.system("nmake /nologo /c /f msisupport.mak") != 0:
- raise RuntimeError("'nmake /f msisupport.mak' failed")
-dll_path = os.path.join(srcdir, PCBUILD, dll_file)
-msilib.set_arch_from_file(dll_path)
-if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"):
- raise SystemError("msisupport.dll for incorrect architecture")
-
-if msilib.Win64:
- upgrade_code = upgrade_code_64
-
-if snapshot:
- product_code = msilib.gen_uuid()
-else:
- # official release: generate UUID from the download link that the file will have
- import uuid
- product_code = uuid.uuid3(uuid.NAMESPACE_URL,
- 'http://www.python.org/ftp/python/%s.%s.%s/python-%s%s.msi' %
- (major, minor, micro, full_current_version, msilib.arch_ext))
- product_code = '{%s}' % product_code
-
-if testpackage:
- ext = 'px'
- testprefix = 'x'
-else:
- ext = 'py'
- testprefix = ''
-
-if msilib.Win64:
- SystemFolderName = "[System64Folder]"
- registry_component = 4|256
-else:
- SystemFolderName = "[SystemFolder]"
- registry_component = 4
-
-msilib.reset()
-
-# condition in which to install pythonxy.dll in system32:
-# a) it is Windows 9x or
-# b) it is NT, the user is privileged, and has chosen per-machine installation
-sys32cond = "(Windows9x or (Privileged and ALLUSERS))"
-
-def build_database():
- """Generate an empty database, with just the schema and the
- Summary information stream."""
- if snapshot:
- uc = upgrade_code_snapshot
- else:
- uc = upgrade_code
- if msilib.Win64:
- productsuffix = " (64-bit)"
- else:
- productsuffix = ""
- # schema represents the installer 2.0 database schema.
- # sequence is the set of standard sequences
- # (ui/execute, admin/advt/install)
- msiname = "python-%s%s.msi" % (full_current_version, msilib.arch_ext)
- db = msilib.init_database(msiname,
- schema, ProductName="Python "+full_current_version+productsuffix,
- ProductCode=product_code,
- ProductVersion=current_version,
- Manufacturer=u"Python Software Foundation",
- request_uac = True)
- # The default sequencing of the RemoveExistingProducts action causes
- # removal of files that got just installed. Place it after
- # InstallInitialize, so we first uninstall everything, but still roll
- # back in case the installation is interrupted
- msilib.change_sequence(sequence.InstallExecuteSequence,
- "RemoveExistingProducts", 1510)
- msilib.add_tables(db, sequence)
- # We cannot set ALLUSERS in the property table, as this cannot be
- # reset if the user choses a per-user installation. Instead, we
- # maintain WhichUsers, which can be "ALL" or "JUSTME". The UI manages
- # this property, and when the execution starts, ALLUSERS is set
- # accordingly.
- add_data(db, "Property", [("UpgradeCode", uc),
- ("WhichUsers", "ALL"),
- ("ProductLine", "Python%s%s" % (major, minor)),
- ])
- db.Commit()
- return db, msiname
-
-def remove_old_versions(db):
- "Fill the upgrade table."
- start = "%s.%s.0" % (major, minor)
- # This requests that feature selection states of an older
- # installation should be forwarded into this one. Upgrading
- # requires that both the old and the new installation are
- # either both per-machine or per-user.
- migrate_features = 1
- # See "Upgrade Table". We remove releases with the same major and
- # minor version. For an snapshot, we remove all earlier snapshots. For
- # a release, we remove all snapshots, and all earlier releases.
- if snapshot:
- add_data(db, "Upgrade",
- [(upgrade_code_snapshot, start,
- current_version,
- None, # Ignore language
- migrate_features,
- None, # Migrate ALL features
- "REMOVEOLDSNAPSHOT")])
- props = "REMOVEOLDSNAPSHOT"
- else:
- add_data(db, "Upgrade",
- [(upgrade_code, start, current_version,
- None, migrate_features, None, "REMOVEOLDVERSION"),
- (upgrade_code_snapshot, start, "%s.%d.0" % (major, int(minor)+1),
- None, migrate_features, None, "REMOVEOLDSNAPSHOT")])
- props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION"
-
- props += ";TARGETDIR;DLLDIR;LAUNCHERDIR"
- # Installer collects the product codes of the earlier releases in
- # these properties. In order to allow modification of the properties,
- # they must be declared as secure. See "SecureCustomProperties Property"
- add_data(db, "Property", [("SecureCustomProperties", props)])
-
-class PyDialog(Dialog):
- """Dialog class with a fixed layout: controls at the top, then a ruler,
- then a list of buttons: back, next, cancel. Optionally a bitmap at the
- left."""
- def __init__(self, *args, **kw):
- """Dialog(database, name, x, y, w, h, attributes, title, first,
- default, cancel, bitmap=true)"""
- Dialog.__init__(self, *args)
- ruler = self.h - 36
- bmwidth = 152*ruler/328
- if kw.get("bitmap", True):
- self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin")
- self.line("BottomLine", 0, ruler, self.w, 0)
-
- def title(self, title):
- "Set the title text of the dialog at the top."
- # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix,
- # text, in VerdanaBold10
- self.text("Title", 135, 10, 220, 60, 0x30003,
- r"{\VerdanaBold10}%s" % title)
-
- def back(self, title, next, name = "Back", active = 1):
- """Add a back button with a given title, the tab-next button,
- its name in the Control table, possibly initially disabled.
-
- Return the button, so that events can be associated"""
- if active:
- flags = 3 # Visible|Enabled
- else:
- flags = 1 # Visible
- return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next)
-
- def cancel(self, title, next, name = "Cancel", active = 1):
- """Add a cancel button with a given title, the tab-next button,
- its name in the Control table, possibly initially disabled.
-
- Return the button, so that events can be associated"""
- if active:
- flags = 3 # Visible|Enabled
- else:
- flags = 1 # Visible
- return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next)
-
- def next(self, title, next, name = "Next", active = 1):
- """Add a Next button with a given title, the tab-next button,
- its name in the Control table, possibly initially disabled.
-
- Return the button, so that events can be associated"""
- if active:
- flags = 3 # Visible|Enabled
- else:
- flags = 1 # Visible
- return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next)
-
- def xbutton(self, name, title, next, xpos):
- """Add a button with a given title, the tab-next button,
- its name in the Control table, giving its x position; the
- y-position is aligned with the other buttons.
-
- Return the button, so that events can be associated"""
- return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
-
-def add_ui(db):
- x = y = 50
- w = 370
- h = 300
- title = "[ProductName] Setup"
-
- # see "Dialog Style Bits"
- modal = 3 # visible | modal
- modeless = 1 # visible
- track_disk_space = 32
-
- add_data(db, 'ActionText', uisample.ActionText)
- add_data(db, 'UIText', uisample.UIText)
-
- # Bitmaps
- if not os.path.exists(srcdir+r"\PC\python_icon.exe"):
- raise RuntimeError("Run icons.mak in PC directory")
- add_data(db, "Binary",
- [("PythonWin", msilib.Binary(r"%s\PCbuild\installer.bmp" % srcdir)), # 152x328 pixels
- ("py.ico",msilib.Binary(srcdir+r"\PC\py.ico")),
- ])
- add_data(db, "Icon",
- [("python_icon.exe", msilib.Binary(srcdir+r"\PC\python_icon.exe"))])
-
- # Scripts
- # CheckDir sets TargetExists if TARGETDIR exists.
- # UpdateEditIDLE sets the REGISTRY.tcl component into
- # the installed/uninstalled state according to both the
- # Extensions and TclTk features.
- add_data(db, "Binary", [("Script", msilib.Binary("msisupport.dll"))])
- # See "Custom Action Type 1"
- if msilib.Win64:
- CheckDir = "CheckDir"
- UpdateEditIDLE = "UpdateEditIDLE"
- else:
- CheckDir = "_CheckDir@4"
- UpdateEditIDLE = "_UpdateEditIDLE@4"
- add_data(db, "CustomAction",
- [("CheckDir", 1, "Script", CheckDir)])
- if have_tcl:
- add_data(db, "CustomAction",
- [("UpdateEditIDLE", 1, "Script", UpdateEditIDLE)])
-
- # UI customization properties
- add_data(db, "Property",
- # See "DefaultUIFont Property"
- [("DefaultUIFont", "DlgFont8"),
- # See "ErrorDialog Style Bit"
- ("ErrorDialog", "ErrorDlg"),
- ("Progress1", "Install"), # modified in maintenance type dlg
- ("Progress2", "installs"),
- ("MaintenanceForm_Action", "Repair")])
-
- # Fonts, see "TextStyle Table"
- add_data(db, "TextStyle",
- [("DlgFont8", "Tahoma", 9, None, 0),
- ("DlgFontBold8", "Tahoma", 8, None, 1), #bold
- ("VerdanaBold10", "Verdana", 10, None, 1),
- ("VerdanaRed9", "Verdana", 9, 255, 0),
- ])
-
- compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py2_|lib2to3\\tests|venv\\scripts" "[TARGETDIR]Lib"'
- lib2to3args = r'-c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"'
- updatepipargs = r'-m ensurepip -U --default-pip'
- removepipargs = r'-B -m ensurepip._uninstall'
- # See "CustomAction Table"
- add_data(db, "CustomAction", [
- # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
- # See "Custom Action Type 51",
- # "Custom Action Execution Scheduling Options"
- ("InitialTargetDir", 307, "TARGETDIR",
- "[WindowsVolume]Python%s%s" % (major, minor)),
- ("SetDLLDirToTarget", 307, "DLLDIR", "[TARGETDIR]"),
- ("SetDLLDirToSystem32", 307, "DLLDIR", SystemFolderName),
- ("SetLauncherDirToTarget", 307, "LAUNCHERDIR", "[TARGETDIR]"),
- ("SetLauncherDirToWindows", 307, "LAUNCHERDIR", "[WindowsFolder]"),
- # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile
- # See "Custom Action Type 18"
- # msidbCustomActionTypeInScript (1024); run during actual installation
- # msidbCustomActionTypeNoImpersonate (2048); run action in system account, not user account
- ("CompilePyc", 18+1024+2048, "python.exe", compileargs),
- ("CompilePyo", 18+1024+2048, "python.exe", "-O "+compileargs),
- ("CompileGrammar", 18+1024+2048, "python.exe", lib2to3args),
- ("UpdatePip", 18+1024+2048, "python.exe", updatepipargs),
- ("RemovePip", 18+1024+2048, "python.exe", removepipargs),
- ])
-
- # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
- # Numbers indicate sequence; see sequence.py for how these action integrate
- add_data(db, "InstallUISequence",
- [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
- ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141),
- ("InitialTargetDir", 'TARGETDIR=""', 750),
- # In the user interface, assume all-users installation if privileged.
- ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751),
- ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752),
- ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753),
- ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754),
- ("SelectDirectoryDlg", "Not Installed", 1230),
- # XXX no support for resume installations yet
- #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
- ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
- ("ProgressDlg", None, 1280)])
- add_data(db, "AdminUISequence",
- [("InitialTargetDir", 'TARGETDIR=""', 750),
- ("SetDLLDirToTarget", 'DLLDIR=""', 751),
- ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752),
- ])
-
- # Prepend TARGETDIR to the system path, and remove it on uninstall.
- add_data(db, "Environment",
- [("PathAddition", "=-*Path", "[TARGETDIR];[TARGETDIR]Scripts;[~]", "REGISTRY.path")])
-
- # Execute Sequences
- add_data(db, "InstallExecuteSequence",
- [("InitialTargetDir", 'TARGETDIR=""', 750),
- ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751),
- ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752),
- ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753),
- ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754),
- ("UpdateEditIDLE", None, 1050),
- # run command if install state of pip changes to INSTALLSTATE_LOCAL
- # run after InstallFiles
- ("UpdatePip", "&pip_feature=3", 4001),
- # remove pip when state changes to INSTALLSTATE_ABSENT
- # run before RemoveFiles
- ("RemovePip", "&pip_feature=2", 3499),
- ("CompilePyc", "COMPILEALL", 4002),
- ("CompilePyo", "COMPILEALL", 4003),
- ("CompileGrammar", "COMPILEALL", 4004),
- ])
- add_data(db, "AdminExecuteSequence",
- [("InitialTargetDir", 'TARGETDIR=""', 750),
- ("SetDLLDirToTarget", 'DLLDIR=""', 751),
- ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752),
- ])
-
- #####################################################################
- # Standard dialogs: FatalError, UserExit, ExitDialog
- fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title,
- "Finish", "Finish", "Finish")
- fatal.title("[ProductName] Installer ended prematurely")
- fatal.back("< Back", "Finish", active = 0)
- fatal.cancel("Cancel", "Back", active = 0)
- fatal.text("Description1", 135, 70, 220, 80, 0x30003,
- "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.")
- fatal.text("Description2", 135, 155, 220, 20, 0x30003,
- "Click the Finish button to exit the Installer.")
- c=fatal.next("Finish", "Cancel", name="Finish")
- # See "ControlEvent Table". Parameters are the event, the parameter
- # to the action, and optionally the condition for the event, and the order
- # of events.
- c.event("EndDialog", "Exit")
-
- user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title,
- "Finish", "Finish", "Finish")
- user_exit.title("[ProductName] Installer was interrupted")
- user_exit.back("< Back", "Finish", active = 0)
- user_exit.cancel("Cancel", "Back", active = 0)
- user_exit.text("Description1", 135, 70, 220, 80, 0x30003,
- "[ProductName] setup was interrupted. Your system has not been modified. "
- "To install this program at a later time, please run the installation again.")
- user_exit.text("Description2", 135, 155, 220, 20, 0x30003,
- "Click the Finish button to exit the Installer.")
- c = user_exit.next("Finish", "Cancel", name="Finish")
- c.event("EndDialog", "Exit")
-
- exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
- "Finish", "Finish", "Finish")
- exit_dialog.title("Complete the [ProductName] Installer")
- exit_dialog.back("< Back", "Finish", active = 0)
- exit_dialog.cancel("Cancel", "Back", active = 0)
- exit_dialog.text("Acknowledgements", 135, 95, 220, 120, 0x30003,
- "Special Windows thanks to:\n"
- " Mark Hammond, without whose years of freely \n"
- " shared Windows expertise, Python for Windows \n"
- " would still be Python for DOS.")
-
- c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003,
- "{\\VerdanaRed9}Warning: Python 2.5.x is the last "
- "Python release for Windows 9x.")
- c.condition("Hide", "NOT Version9X")
-
- exit_dialog.text("Description", 135, 235, 220, 20, 0x30003,
- "Click the Finish button to exit the Installer.")
- c = exit_dialog.next("Finish", "Cancel", name="Finish")
- c.event("EndDialog", "Return")
-
- #####################################################################
- # Required dialog: FilesInUse, ErrorDlg
- inuse = PyDialog(db, "FilesInUse",
- x, y, w, h,
- 19, # KeepModeless|Modal|Visible
- title,
- "Retry", "Retry", "Retry", bitmap=False)
- inuse.text("Title", 15, 6, 200, 15, 0x30003,
- r"{\DlgFontBold8}Files in Use")
- inuse.text("Description", 20, 23, 280, 20, 0x30003,
- "Some files that need to be updated are currently in use.")
- inuse.text("Text", 20, 55, 330, 50, 3,
- "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.")
- inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess",
- None, None, None)
- c=inuse.back("Exit", "Ignore", name="Exit")
- c.event("EndDialog", "Exit")
- c=inuse.next("Ignore", "Retry", name="Ignore")
- c.event("EndDialog", "Ignore")
- c=inuse.cancel("Retry", "Exit", name="Retry")
- c.event("EndDialog","Retry")
-
-
- # See "Error Dialog". See "ICE20" for the required names of the controls.
- error = Dialog(db, "ErrorDlg",
- 50, 10, 330, 101,
- 65543, # Error|Minimize|Modal|Visible
- title,
- "ErrorText", None, None)
- error.text("ErrorText", 50,9,280,48,3, "")
- error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
- error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo")
- error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes")
- error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort")
- error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel")
- error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore")
- error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk")
- error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry")
-
- #####################################################################
- # Global "Query Cancel" dialog
- cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title,
- "No", "No", "No")
- cancel.text("Text", 48, 15, 194, 30, 3,
- "Are you sure you want to cancel [ProductName] installation?")
- cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
- "py.ico", None, None)
- c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
- c.event("EndDialog", "Exit")
-
- c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
- c.event("EndDialog", "Return")
-
- #####################################################################
- # Global "Wait for costing" dialog
- costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title,
- "Return", "Return", "Return")
- costing.text("Text", 48, 15, 194, 30, 3,
- "Please wait while the installer finishes determining your disk space requirements.")
- costing.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
- "py.ico", None, None)
- c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
- c.event("EndDialog", "Exit")
-
- #####################################################################
- # Preparation dialog: no user input except cancellation
- prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
- "Cancel", "Cancel", "Cancel")
- prep.text("Description", 135, 70, 220, 40, 0x30003,
- "Please wait while the Installer prepares to guide you through the installation.")
- prep.title("Welcome to the [ProductName] Installer")
- c=prep.text("ActionText", 135, 110, 220, 20, 0x30003, "Pondering...")
- c.mapping("ActionText", "Text")
- c=prep.text("ActionData", 135, 135, 220, 30, 0x30003, None)
- c.mapping("ActionData", "Text")
- prep.back("Back", None, active=0)
- prep.next("Next", None, active=0)
- c=prep.cancel("Cancel", None)
- c.event("SpawnDialog", "CancelDlg")
-
- #####################################################################
- # Target directory selection
- seldlg = PyDialog(db, "SelectDirectoryDlg", x, y, w, h, modal, title,
- "Next", "Next", "Cancel")
- seldlg.title("Select Destination Directory")
- c = seldlg.text("Existing", 135, 25, 235, 30, 0x30003,
- "{\VerdanaRed9}This update will replace your existing [ProductLine] installation.")
- c.condition("Hide", 'REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""')
- seldlg.text("Description", 135, 50, 220, 40, 0x30003,
- "Please select a directory for the [ProductName] files.")
-
- seldlg.back("< Back", None, active=0)
- c = seldlg.next("Next >", "Cancel")
- c.event("DoAction", "CheckDir", "TargetExistsOk<>1", order=1)
- # If the target exists, but we found that we are going to remove old versions, don't bother
- # confirming that the target directory exists. Strictly speaking, we should determine that
- # the target directory is indeed the target of the product that we are going to remove, but
- # I don't know how to do that.
- c.event("SpawnDialog", "ExistingDirectoryDlg", 'TargetExists=1 and REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""', 2)
- c.event("SetTargetPath", "TARGETDIR", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 3)
- c.event("SpawnWaitDialog", "WaitForCostingDlg", "CostingComplete=1", 4)
- c.event("NewDialog", "SelectFeaturesDlg", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 5)
-
- c = seldlg.cancel("Cancel", "DirectoryCombo")
- c.event("SpawnDialog", "CancelDlg")
-
- seldlg.control("DirectoryCombo", "DirectoryCombo", 135, 70, 172, 80, 393219,
- "TARGETDIR", None, "DirectoryList", None)
- seldlg.control("DirectoryList", "DirectoryList", 135, 90, 208, 136, 3, "TARGETDIR",
- None, "PathEdit", None)
- seldlg.control("PathEdit", "PathEdit", 135, 230, 206, 16, 3, "TARGETDIR", None, "Next", None)
- c = seldlg.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None)
- c.event("DirectoryListUp", "0")
- c = seldlg.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None)
- c.event("DirectoryListNew", "0")
-
- #####################################################################
- # SelectFeaturesDlg
- features = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal|track_disk_space,
- title, "Tree", "Next", "Cancel")
- features.title("Customize [ProductName]")
- features.text("Description", 135, 35, 220, 15, 0x30003,
- "Select the way you want features to be installed.")
- features.text("Text", 135,45,220,30, 3,
- "Click on the icons in the tree below to change the way features will be installed.")
-
- c=features.back("< Back", "Next")
- c.event("NewDialog", "SelectDirectoryDlg")
-
- c=features.next("Next >", "Cancel")
- c.mapping("SelectionNoItems", "Enabled")
- c.event("SpawnDialog", "DiskCostDlg", "OutOfDiskSpace=1", order=1)
- c.event("EndDialog", "Return", "OutOfDiskSpace<>1", order=2)
-
- c=features.cancel("Cancel", "Tree")
- c.event("SpawnDialog", "CancelDlg")
-
- # The browse property is not used, since we have only a single target path (selected already)
- features.control("Tree", "SelectionTree", 135, 75, 220, 95, 7, "_BrowseProperty",
- "Tree of selections", "Back", None)
-
- #c=features.pushbutton("Reset", 42, 243, 56, 17, 3, "Reset", "DiskCost")
- #c.mapping("SelectionNoItems", "Enabled")
- #c.event("Reset", "0")
-
- features.control("Box", "GroupBox", 135, 170, 225, 90, 1, None, None, None, None)
-
- c=features.xbutton("DiskCost", "Disk &Usage", None, 0.10)
- c.mapping("SelectionNoItems","Enabled")
- c.event("SpawnDialog", "DiskCostDlg")
-
- c=features.xbutton("Advanced", "Advanced", None, 0.30)
- c.event("SpawnDialog", "AdvancedDlg")
-
- c=features.text("ItemDescription", 140, 180, 210, 40, 3,
- "Multiline description of the currently selected item.")
- c.mapping("SelectionDescription","Text")
-
- c=features.text("ItemSize", 140, 225, 210, 33, 3,
- "The size of the currently selected item.")
- c.mapping("SelectionSize", "Text")
-
- #####################################################################
- # Disk cost
- cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
- "OK", "OK", "OK", bitmap=False)
- cost.text("Title", 15, 6, 200, 15, 0x30003,
- "{\DlgFontBold8}Disk Space Requirements")
- cost.text("Description", 20, 20, 280, 20, 0x30003,
- "The disk space required for the installation of the selected features.")
- cost.text("Text", 20, 53, 330, 60, 3,
- "The highlighted volumes (if any) do not have enough disk space "
- "available for the currently selected features. You can either "
- "remove some files from the highlighted volumes, or choose to "
- "install less features onto local drive(s), or select different "
- "destination drive(s).")
- cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
- None, "{120}{70}{70}{70}{70}", None, None)
- cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")
-
- #####################################################################
- # WhichUsers Dialog. Only available on NT, and for privileged users.
- # This must be run before FindRelatedProducts, because that will
- # take into account whether the previous installation was per-user
- # or per-machine. We currently don't support going back to this
- # dialog after "Next" was selected; to support this, we would need to
- # find how to reset the ALLUSERS property, and how to re-run
- # FindRelatedProducts.
- # On Windows9x, the ALLUSERS property is ignored on the command line
- # and in the Property table, but installer fails according to the documentation
- # if a dialog attempts to set ALLUSERS.
- whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
- "AdminInstall", "Next", "Cancel")
- whichusers.title("Select whether to install [ProductName] for all users of this computer.")
- # A radio group with two options: allusers, justme
- g = whichusers.radiogroup("AdminInstall", 135, 60, 235, 80, 3,
- "WhichUsers", "", "Next")
- g.condition("Disable", "VersionNT=600") # Not available on Vista and Windows 2008
- g.add("ALL", 0, 5, 150, 20, "Install for all users")
- g.add("JUSTME", 0, 25, 235, 20, "Install just for me (not available on Windows Vista)")
-
- whichusers.back("Back", None, active=0)
-
- c = whichusers.next("Next >", "Cancel")
- c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
- c.event("EndDialog", "Return", order = 2)
-
- c = whichusers.cancel("Cancel", "AdminInstall")
- c.event("SpawnDialog", "CancelDlg")
-
- #####################################################################
- # Advanced Dialog.
- advanced = PyDialog(db, "AdvancedDlg", x, y, w, h, modal, title,
- "CompilePyc", "Ok", "Ok")
- advanced.title("Advanced Options for [ProductName]")
-
- # A checkbox whether to build pyc files
- advanced.checkbox("CompilePyc", 135, 60, 230, 50, 3,
- "COMPILEALL", "Compile .py files to byte code after installation", "Ok")
-
- c = advanced.cancel("Ok", "CompilePyc", name="Ok") # Button just has location of cancel button.
- c.event("EndDialog", "Return")
-
- #####################################################################
- # Existing Directory dialog
- dlg = Dialog(db, "ExistingDirectoryDlg", 50, 30, 200, 80, modal, title,
- "No", "No", "No")
- dlg.text("Title", 10, 20, 180, 40, 3,
- "[TARGETDIR] exists. Are you sure you want to overwrite existing files?")
- c=dlg.pushbutton("Yes", 30, 60, 55, 17, 3, "Yes", "No")
- c.event("[TargetExists]", "0", order=1)
- c.event("[TargetExistsOk]", "1", order=2)
- c.event("EndDialog", "Return", order=3)
- c=dlg.pushbutton("No", 115, 60, 55, 17, 3, "No", "Yes")
- c.event("EndDialog", "Return")
-
- #####################################################################
- # Installation Progress dialog (modeless)
- progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
- "Cancel", "Cancel", "Cancel", bitmap=False)
- progress.text("Title", 20, 15, 200, 15, 0x30003,
- "{\DlgFontBold8}[Progress1] [ProductName]")
- progress.text("Text", 35, 65, 300, 30, 3,
- "Please wait while the Installer [Progress2] [ProductName]. "
- "This may take several minutes.")
- progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")
-
- c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...")
- c.mapping("ActionText", "Text")
-
- #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
- #c.mapping("ActionData", "Text")
-
- c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537,
- None, "Progress done", None, None)
- c.mapping("SetProgress", "Progress")
-
- progress.back("< Back", "Next", active=False)
- progress.next("Next >", "Cancel", active=False)
- progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg")
-
- # Maintenance type: repair/uninstall
- maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
- "Next", "Next", "Cancel")
- maint.title("Welcome to the [ProductName] Setup Wizard")
- maint.text("BodyText", 135, 63, 230, 42, 3,
- "Select whether you want to repair or remove [ProductName].")
- g=maint.radiogroup("RepairRadioGroup", 135, 108, 230, 60, 3,
- "MaintenanceForm_Action", "", "Next")
- g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
- g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
- g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")
-
- maint.back("< Back", None, active=False)
- c=maint.next("Finish", "Cancel")
- # Change installation: Change progress dialog to "Change", then ask
- # for feature selection
- c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
- c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
-
- # Reinstall: Change progress dialog to "Repair", then invoke reinstall
- # Also set list of reinstalled features to "ALL"
- c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5)
- c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6)
- c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7)
- c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8)
-
- # Uninstall: Change progress to "Remove", then invoke uninstall
- # Also set list of removed features to "ALL"
- c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11)
- c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12)
- c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13)
- c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14)
-
- # Close dialog when maintenance action scheduled
- c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
- c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
-
- maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg")
-
-
-# See "Feature Table". The feature level is 1 for all features,
-# and the feature attributes are 0 for the DefaultFeature, and
-# FollowParent for all other features. The numbers are the Display
-# column.
-def add_features(db):
- # feature attributes:
- # msidbFeatureAttributesFollowParent == 2
- # msidbFeatureAttributesDisallowAdvertise == 8
- # Features that need to be installed with together with the main feature
- # (i.e. additional Python libraries) need to follow the parent feature.
- # Features that have no advertisement trigger (e.g. the test suite)
- # must not support advertisement
- global default_feature, tcltk, htmlfiles, tools, testsuite
- global ext_feature, private_crt, prepend_path, pip_feature
- default_feature = Feature(db, "DefaultFeature", "Python",
- "Python Interpreter and Libraries",
- 1, directory = "TARGETDIR")
- shared_crt = Feature(db, "SharedCRT", "MSVCRT", "C Run-Time (system-wide)", 0,
- level=0)
- private_crt = Feature(db, "PrivateCRT", "MSVCRT", "C Run-Time (private)", 0,
- level=0)
- add_data(db, "Condition", [("SharedCRT", 1, sys32cond),
- ("PrivateCRT", 1, "not "+sys32cond)])
- # We don't support advertisement of extensions
- ext_feature = Feature(db, "Extensions", "Register Extensions",
- "Make this Python installation the default Python installation", 3,
- parent = default_feature, attributes=2|8)
- if have_tcl:
- tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5,
- parent = default_feature, attributes=2)
- htmlfiles = Feature(db, "Documentation", "Documentation",
- "Python HTMLHelp File", 7, parent = default_feature)
- tools = Feature(db, "Tools", "Utility Scripts",
- "Python utility scripts (Tools/)", 9,
- parent = default_feature, attributes=2)
- # pip installation isn't enabled by default until a clean uninstall procedure
- # becomes possible
- pip_feature = Feature(db, "pip_feature", "pip",
- "Install (or upgrade from an earlier version) pip, "
- "a tool for installing and managing Python packages.", 11,
- parent = default_feature, attributes=2|8)
- testsuite = Feature(db, "Testsuite", "Test suite",
- "Python test suite (Lib/test/)", 13,
- parent = default_feature, attributes=2|8)
- # prepend_path is an additional feature which is to be off by default.
- # Since the default level for the above features is 1, this needs to be
- # at least level higher.
- prepend_path = Feature(db, "PrependPath", "Add python.exe to Path",
- "Prepend [TARGETDIR] to the system Path variable. "
- "This allows you to type 'python' into a command "
- "prompt without needing the full path.", 15,
- parent = default_feature, attributes=2|8,
- level=2)
-
-def extract_msvcr100():
- # Find the redistributable files
- if msilib.Win64:
- arch = "x64"
- else:
- arch = "x86"
- dir = os.path.join(os.environ['VS100COMNTOOLS'], r"..\..\VC\redist\%s\Microsoft.VC100.CRT" % arch)
-
- result = []
- installer = msilib.MakeInstaller()
- # At least for VS2010, manifests are no longer provided
- name = "msvcr100.dll"
- path = os.path.join(dir, name)
- kw = {'src':path}
- kw['version'] = installer.FileVersion(path, 0)
- kw['language'] = installer.FileVersion(path, 1)
- return name, kw
-
-def generate_license():
- import shutil, glob
- out = open("LICENSE.txt", "w")
- shutil.copyfileobj(open(os.path.join(srcdir, "LICENSE")), out)
- shutil.copyfileobj(open("crtlicense.txt"), out)
- for name, pat, file in (("bzip2","bzip2-*", "LICENSE"),
- ("openssl", "openssl-*", "LICENSE"),
- ("Tcl", "tcl-8*", "license.terms"),
- ("Tk", "tk-8*", "license.terms"),
- ("Tix", "tix-*", "license.terms")):
- out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % name)
- dirs = glob.glob(srcdir+"/../"+pat)
- if not dirs:
- raise ValueError, "Could not find "+srcdir+"/../"+pat
- if len(dirs) > 2 and not snapshot:
- raise ValueError, "Multiple copies of "+pat
- dir = dirs[0]
- shutil.copyfileobj(open(os.path.join(dir, file)), out)
- out.close()
-
-
-class PyDirectory(Directory):
- """By default, all components in the Python installer
- can run from source."""
- def __init__(self, *args, **kw):
- if "componentflags" not in kw:
- kw['componentflags'] = 2 #msidbComponentAttributesOptional
- Directory.__init__(self, *args, **kw)
-
-def hgmanifest():
- # Fetch file list from Mercurial
- process = subprocess.Popen(['hg', 'manifest'], stdout=subprocess.PIPE)
- stdout, stderr = process.communicate()
- # Create nested directories for file tree
- result = {}
- for line in stdout.splitlines():
- components = line.split('/')
- d = result
- while len(components) > 1:
- d1 = d.setdefault(components[0], {})
- d = d1
- del components[0]
- d[components[0]] = None
- return result
-
-
-# See "File Table", "Component Table", "Directory Table",
-# "FeatureComponents Table"
-def add_files(db):
- installer = msilib.MakeInstaller()
- hgfiles = hgmanifest()
- cab = CAB("python")
- tmpfiles = []
- # Add all executables, icons, text files into the TARGETDIR component
- root = PyDirectory(db, cab, None, srcdir, "TARGETDIR", "SourceDir")
- default_feature.set_current()
- root.add_file("README.txt", src="README")
- root.add_file("NEWS.txt", src="Misc/NEWS")
- generate_license()
- root.add_file("LICENSE.txt", src=os.path.abspath("LICENSE.txt"))
- root.start_component("python.exe", keyfile="python.exe")
- root.add_file("%s/python.exe" % PCBUILD)
- root.start_component("pythonw.exe", keyfile="pythonw.exe")
- root.add_file("%s/pythonw.exe" % PCBUILD)
-
- # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table"
- dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".")
- launcherdir = PyDirectory(db, cab, root, srcdir, "LAUNCHERDIR", ".")
-
- # msidbComponentAttributes64bit = 256; this disables registry redirection
- # to allow setting the SharedDLLs key in the 64-bit portion even for a
- # 32-bit installer.
- # XXX does this still allow to install the component on a 32-bit system?
- # Pick up 32-bit binary always
- launchersrc = PCBUILD
- if launchersrc.lower() == 'pcbuild\\x64-pgo':
- launchersrc = 'PCBuild\\win32-pgo'
- if launchersrc.lower() == 'pcbuild\\amd64':
- launchersrc = 'PCBuild'
- launcher = os.path.join(srcdir, launchersrc, "py.exe")
- launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe")
- launcherdir.add_file(launcher,
- version=installer.FileVersion(launcher, 0),
- language=installer.FileVersion(launcher, 1))
- launcherw = os.path.join(srcdir, launchersrc, "pyw.exe")
- launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe")
- launcherdir.add_file(launcherw,
- version=installer.FileVersion(launcherw, 0),
- language=installer.FileVersion(launcherw, 1))
-
- pydll = "python%s%s.dll" % (major, minor)
- pydllsrc = os.path.join(srcdir, PCBUILD, pydll)
- dlldir.start_component("DLLDIR", flags = 8, keyfile = pydll, uuid = pythondll_uuid)
- pyversion = installer.FileVersion(pydllsrc, 0)
- if not snapshot:
- # For releases, the Python DLL has the same version as the
- # installer package.
- assert pyversion.split(".")[:3] == current_version.split(".")
- dlldir.add_file("%s/python%s%s.dll" % (PCBUILD, major, minor),
- version=pyversion,
- language=installer.FileVersion(pydllsrc, 1))
- DLLs = PyDirectory(db, cab, root, srcdir + "/" + PCBUILD, "DLLs", "DLLS|DLLs")
-
- # msvcr90.dll: Need to place the DLL and the manifest into the root directory,
- # plus another copy of the manifest in the DLLs directory, with the manifest
- # pointing to the root directory
- root.start_component("msvcr90", feature=private_crt)
- # Results are ID,keyword pairs
- crtdll, kwds = extract_msvcr100()
- root.add_file(crtdll, **kwds)
- # Copy the manifest
- # Actually, don't do that anymore - no DLL in DLLs should have a manifest
- # dependency on msvcr90.dll anymore, so this should not be necessary
- #manifest_dlls = manifest[0]+".root"
- #open(manifest_dlls, "w").write(open(manifest[1]['src']).read().replace("msvcr","../msvcr"))
- #DLLs.start_component("msvcr90_dlls", feature=private_crt)
- #DLLs.add_file(manifest[0], src=os.path.abspath(manifest_dlls))
-
- # Now start the main component for the DLLs directory;
- # no regular files have been added to the directory yet.
- DLLs.start_component()
-
- # Check if _ctypes.pyd exists
- have_ctypes = os.path.exists(srcdir+"/%s/_ctypes.pyd" % PCBUILD)
- if not have_ctypes:
- print("WARNING: _ctypes.pyd not found, ctypes will not be included")
- extensions.remove("_ctypes.pyd")
-
- # Add all .py files in Lib, except tkinter, test
- dirs = []
- pydirs = [(root, "Lib", hgfiles["Lib"], default_feature)]
- while pydirs:
- # Commit every now and then, or else installer will complain
- db.Commit()
- parent, dir, files, feature = pydirs.pop()
- if dir.startswith("plat-"):
- continue
- if dir in ["tkinter", "idlelib", "turtledemo"]:
- if not have_tcl:
- continue
- feature = tcltk
- tcltk.set_current()
- elif dir in ('test', 'tests'):
- feature = testsuite
- elif not have_ctypes and dir == "ctypes":
- continue
- feature.set_current()
- lib = PyDirectory(db, cab, parent, dir, dir, "%s|%s" % (parent.make_short(dir), dir))
- dirs.append(lib)
- has_py = False
- for name, subdir in files.items():
- if subdir is None:
- assert os.path.isfile(os.path.join(lib.absolute, name))
- if name == 'README':
- lib.add_file("README.txt", src="README")
- else:
- lib.add_file(name)
- has_py = has_py or name.endswith(".py") or name.endswith(".pyw")
- else:
- assert os.path.isdir(os.path.join(lib.absolute, name))
- pydirs.append((lib, name, subdir, feature))
-
- if has_py:
- lib.remove_pyc()
- # Add DLLs
- default_feature.set_current()
- lib = DLLs
- lib.add_file("py.ico", src=srcdir+"/PC/py.ico")
- lib.add_file("pyc.ico", src=srcdir+"/PC/pyc.ico")
- dlls = []
- tclfiles = []
- for f in extensions:
- if f=="_tkinter.pyd":
- continue
- if not os.path.exists(srcdir + "/" + PCBUILD + "/" + f):
- print("WARNING: Missing extension", f)
- continue
- dlls.append(f)
- lib.add_file(f)
- lib.add_file('python3.dll')
- # Add sqlite
- if msilib.msi_type=="Intel64;1033":
- sqlite_arch = "/ia64"
- elif msilib.msi_type=="x64;1033":
- sqlite_arch = "/amd64"
- tclsuffix = "64"
- else:
- sqlite_arch = ""
- tclsuffix = ""
- lib.add_file("sqlite3.dll")
- if have_tcl:
- if not os.path.exists("%s/%s/_tkinter.pyd" % (srcdir, PCBUILD)):
- print("WARNING: Missing _tkinter.pyd")
- else:
- lib.start_component("TkDLLs", tcltk)
- lib.add_file("_tkinter.pyd")
- dlls.append("_tkinter.pyd")
- tcldir = os.path.normpath(srcdir+("/../tcltk%s/bin" % tclsuffix))
- for f in glob.glob1(tcldir, "*.dll"):
- lib.add_file(f, src=os.path.join(tcldir, f))
- # check whether there are any unknown extensions
- for f in glob.glob1(srcdir+"/"+PCBUILD, "*.pyd"):
- if f.endswith("_d.pyd"): continue # debug version
- if f in dlls: continue
- print("WARNING: Unknown extension", f)
-
- # Add headers
- default_feature.set_current()
- lib = PyDirectory(db, cab, root, "include", "include", "INCLUDE|include")
- lib.glob("*.h")
- lib.add_file("pyconfig.h", src="../PC/pyconfig.h")
- # Add import libraries
- lib = PyDirectory(db, cab, root, PCBUILD, "libs", "LIBS|libs")
- for f in dlls:
- lib.add_file(f.replace('pyd','lib'))
- lib.add_file('python%s%s.lib' % (major, minor))
- lib.add_file('python3.lib')
- # Add the mingw-format library
- if have_mingw:
- lib.add_file('libpython%s%s.a' % (major, minor))
- if have_tcl:
- # Add Tcl/Tk
- tcldirs = [(root, '../tcltk%s/lib' % tclsuffix, 'tcl')]
- tcltk.set_current()
- while tcldirs:
- parent, phys, dir = tcldirs.pop()
- lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir))
- if not os.path.exists(lib.absolute):
- continue
- for f in os.listdir(lib.absolute):
- if os.path.isdir(os.path.join(lib.absolute, f)):
- tcldirs.append((lib, f, f))
- else:
- lib.add_file(f)
- # Add tools
- tools.set_current()
- tooldir = PyDirectory(db, cab, root, "Tools", "Tools", "TOOLS|Tools")
- for f in ['i18n', 'pynche', 'Scripts']:
- lib = PyDirectory(db, cab, tooldir, f, f, "%s|%s" % (tooldir.make_short(f), f))
- lib.glob("*.py")
- lib.glob("*.pyw")
- lib.remove_pyc()
- lib.glob("*.txt")
- if f == "pynche":
- x = PyDirectory(db, cab, lib, "X", "X", "X|X")
- x.glob("*.txt")
- if os.path.exists(os.path.join(lib.absolute, "README")):
- lib.add_file("README.txt", src="README")
- if f == 'Scripts':
- lib.add_file("2to3.py", src="2to3")
- lib.add_file("pydoc3.py", src="pydoc3")
- lib.add_file("pyvenv.py", src="pyvenv")
- # Add documentation
- htmlfiles.set_current()
- lib = PyDirectory(db, cab, root, "Doc", "Doc", "DOC|Doc")
- lib.start_component("documentation", keyfile=docfile)
- lib.add_file(docfile, src="build/htmlhelp/"+docfile)
-
- cab.commit(db)
-
- for f in tmpfiles:
- os.unlink(f)
-
-# See "Registry Table", "Component Table"
-def add_registry(db):
- # File extensions, associated with the REGISTRY.def component
- # IDLE verbs depend on the tcltk feature.
- # msidbComponentAttributesRegistryKeyPath = 4
- # -1 for Root specifies "dependent on ALLUSERS property"
- tcldata = []
- if have_tcl:
- tcldata = [
- ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
- "py.IDLE")]
- add_data(db, "Component",
- # msidbComponentAttributesRegistryKeyPath = 4
- [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
- "InstallPath"),
- ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
- "Documentation"),
- ("REGISTRY.path", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
- None),
- ("REGISTRY.ensurepip", msilib.gen_uuid(), "TARGETDIR", registry_component, "EnsurePipRun",
- None),
- ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", registry_component,
- None, None)] + tcldata)
- # See "FeatureComponents Table".
- # The association between TclTk and pythonw.exe is necessary to make ICE59
- # happy, because the installer otherwise believes that the IDLE and PyDoc
- # shortcuts might get installed without pythonw.exe being install. This
- # is not true, since installing TclTk will install the default feature, which
- # will cause pythonw.exe to be installed.
- # REGISTRY.tcl is not associated with any feature, as it will be requested
- # through a custom action
- tcldata = []
- if have_tcl:
- tcldata = [(tcltk.id, "pythonw.exe")]
- add_data(db, "FeatureComponents",
- [(default_feature.id, "REGISTRY"),
- (htmlfiles.id, "REGISTRY.doc"),
- (prepend_path.id, "REGISTRY.path"),
- (pip_feature.id, "REGISTRY.ensurepip"),
- (ext_feature.id, "REGISTRY.def")] +
- tcldata
- )
- # Extensions are not advertised. For advertised extensions,
- # we would need separate binaries that install along with the
- # extension.
- pat = r"Software\Classes\%sPython.%sFile\shell\%s\command"
- ewi = "Edit with IDLE"
- pat2 = r"Software\Classes\%sPython.%sFile\DefaultIcon"
- pat3 = r"Software\Classes\%sPython.%sFile"
- pat4 = r"Software\Classes\%sPython.%sFile\shellex\DropHandler"
- tcl_verbs = []
- if have_tcl:
- tcl_verbs=[
- ("py.IDLE", -1, pat % (testprefix, "", ewi), "",
- r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"',
- "REGISTRY.tcl"),
- ("pyw.IDLE", -1, pat % (testprefix, "NoCon", ewi), "",
- r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"',
- "REGISTRY.tcl"),
- ]
- add_data(db, "Registry",
- [# Extensions
- ("py.ext", -1, r"Software\Classes\."+ext, "",
- "Python.File", "REGISTRY.def"),
- ("pyw.ext", -1, r"Software\Classes\."+ext+'w', "",
- "Python.NoConFile", "REGISTRY.def"),
- ("pyc.ext", -1, r"Software\Classes\."+ext+'c', "",
- "Python.CompiledFile", "REGISTRY.def"),
- ("pyo.ext", -1, r"Software\Classes\."+ext+'o', "",
- "Python.CompiledFile", "REGISTRY.def"),
- # MIME types
- ("py.mime", -1, r"Software\Classes\."+ext, "Content Type",
- "text/plain", "REGISTRY.def"),
- ("pyw.mime", -1, r"Software\Classes\."+ext+'w', "Content Type",
- "text/plain", "REGISTRY.def"),
- #Verbs
- ("py.open", -1, pat % (testprefix, "", "open"), "",
- r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"),
- ("pyw.open", -1, pat % (testprefix, "NoCon", "open"), "",
- r'"[LAUNCHERDIR]pyw.exe" "%1" %*', "REGISTRY.def"),
- ("pyc.open", -1, pat % (testprefix, "Compiled", "open"), "",
- r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"),
- ] + tcl_verbs + [
- #Icons
- ("py.icon", -1, pat2 % (testprefix, ""), "",
- r'[DLLs]py.ico', "REGISTRY.def"),
- ("pyw.icon", -1, pat2 % (testprefix, "NoCon"), "",
- r'[DLLs]py.ico', "REGISTRY.def"),
- ("pyc.icon", -1, pat2 % (testprefix, "Compiled"), "",
- r'[DLLs]pyc.ico', "REGISTRY.def"),
- # Descriptions
- ("py.txt", -1, pat3 % (testprefix, ""), "",
- "Python File", "REGISTRY.def"),
- ("pyw.txt", -1, pat3 % (testprefix, "NoCon"), "",
- "Python File (no console)", "REGISTRY.def"),
- ("pyc.txt", -1, pat3 % (testprefix, "Compiled"), "",
- "Compiled Python File", "REGISTRY.def"),
- # Drop Handler
- ("py.drop", -1, pat4 % (testprefix, ""), "",
- "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"),
- ("pyw.drop", -1, pat4 % (testprefix, "NoCon"), "",
- "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"),
- ("pyc.drop", -1, pat4 % (testprefix, "Compiled"), "",
- "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"),
- ])
-
- # PATHEXT
- add_data(db, "Environment",
- [("PathExtAddition", "=-*PathExt", "[~];.PY", "REGISTRY.def")])
-
- # Registry keys
- prefix = r"Software\%sPython\PythonCore\%s" % (testprefix, short_version)
- add_data(db, "Registry",
- [("InstallPath", -1, prefix+r"\InstallPath", "", "[TARGETDIR]", "REGISTRY"),
- ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "",
- "Python %s" % short_version, "REGISTRY"),
- ("PythonPath", -1, prefix+r"\PythonPath", "",
- r"[TARGETDIR]Lib;[TARGETDIR]DLLs", "REGISTRY"),
- ("Documentation", -1, prefix+r"\Help\Main Python Documentation", "",
- "[TARGETDIR]Doc\\"+docfile , "REGISTRY.doc"),
- ("Modules", -1, prefix+r"\Modules", "+", None, "REGISTRY"),
- ("AppPaths", -1, r"Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe",
- "", r"[TARGETDIR]Python.exe", "REGISTRY.def"),
- ("DisplayIcon", -1,
- r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" % product_code,
- "DisplayIcon", "[TARGETDIR]python.exe", "REGISTRY"),
- # Fake registry entry to allow installer to track whether ensurepip has been run
- ("EnsurePipRun", -1, prefix+r"\EnsurePipRun", "", "#1", "REGISTRY.ensurepip"),
- ])
- # Shortcuts, see "Shortcut Table"
- add_data(db, "Directory",
- [("ProgramMenuFolder", "TARGETDIR", "."),
- ("MenuDir", "ProgramMenuFolder", "PY%s%s|%sPython %s.%s" % (major,minor,testprefix,major,minor))])
- add_data(db, "RemoveFile",
- [("MenuDir", "TARGETDIR", None, "MenuDir", 2)])
- tcltkshortcuts = []
- if msilib.Win64:
- bitted = "64 bit"
- else:
- bitted = "32 bit"
- if have_tcl:
- tcltkshortcuts = [
- ("IDLE", "MenuDir",
- "IDLE|IDLE (Python "+short_version+" GUI - "+bitted+")",
- "pythonw.exe", tcltk.id, r'"[TARGETDIR]Lib\idlelib\idle.pyw"',
- None, None, "python_icon.exe", 0, None, "TARGETDIR"),
- ]
- add_data(db, "Shortcut",
- tcltkshortcuts +
- [# Advertised shortcuts: targets are features, not files
- ("Python", "MenuDir",
- "PYTHON|Python "+short_version+" (command line - "+bitted+")",
- "python.exe", default_feature.id, None, None, None,
- "python_icon.exe", 2, None, "TARGETDIR"),
- # Advertising the Manual breaks on (some?) Win98, and the shortcut lacks an
- # icon first.
- #("Manual", "MenuDir", "MANUAL|Python Manuals", "documentation",
- # htmlfiles.id, None, None, None, None, None, None, None),
- ## Non-advertised shortcuts: must be associated with a registry component
- ("Manual", "MenuDir", "MANUAL|Python "+short_version+" Manuals",
- "REGISTRY.doc", "[#%s]" % docfile,
- None, None, None, None, None, None, None),
- ("PyDoc", "MenuDir",
- "MODDOCS|Python "+short_version+" Docs Server (pydoc - "+
- bitted+")", "python.exe", default_feature.id, r'-m pydoc -b',
- None, None, "python_icon.exe", 0, None, "TARGETDIR"),
- ("Uninstall", "MenuDir", "UNINST|Uninstall Python "+
- short_version+" ("+bitted+")", "REGISTRY",
- SystemFolderName+"msiexec", "/x%s" % product_code,
- None, None, None, None, None, None),
- ])
- db.Commit()
-
-def build_pdbzip():
- pdbexclude = ['kill_python.pdb', 'make_buildinfo.pdb',
- 'make_versioninfo.pdb']
- path = "python-%s%s-pdb.zip" % (full_current_version, msilib.arch_ext)
- pdbzip = zipfile.ZipFile(path, 'w')
- for f in glob.glob1(os.path.join(srcdir, PCBUILD), "*.pdb"):
- if f not in pdbexclude and not f.endswith('_d.pdb'):
- pdbzip.write(os.path.join(srcdir, PCBUILD, f), f)
- pdbzip.close()
-
-db,msiname = build_database()
-try:
- add_features(db)
- add_ui(db)
- add_files(db)
- add_registry(db)
- remove_old_versions(db)
- db.Commit()
-finally:
- del db
-
-# Merge CRT into MSI file. This requires the database to be closed.
-mod_dir = os.path.join(os.environ["ProgramFiles"], "Common Files", "Merge Modules")
-if msilib.Win64:
- modules = ["Microsoft_VC100_CRT_x64.msm"]
-else:
- modules = ["Microsoft_VC100_CRT_x86.msm"]
-
-for i, n in enumerate(modules):
- modules[i] = os.path.join(mod_dir, n)
-
-def merge(msi, feature, rootdir, modules):
- cab_and_filecount = []
- # Step 1: Merge databases, extract cabfiles
- m = msilib.MakeMerge2()
- m.OpenLog("merge.log")
- m.OpenDatabase(msi)
- for module in modules:
- print module
- m.OpenModule(module,0)
- m.Merge(feature, rootdir)
- print "Errors:"
- for e in m.Errors:
- print e.Type, e.ModuleTable, e.DatabaseTable
- print " Modkeys:",
- for s in e.ModuleKeys: print s,
- print
- print " DBKeys:",
- for s in e.DatabaseKeys: print s,
- print
- cabname = tempfile.mktemp(suffix=".cab")
- m.ExtractCAB(cabname)
- cab_and_filecount.append((cabname, len(m.ModuleFiles)))
- m.CloseModule()
- m.CloseDatabase(True)
- m.CloseLog()
-
- # Step 2: Add CAB files
- i = msilib.MakeInstaller()
- db = i.OpenDatabase(msi, constants.msiOpenDatabaseModeTransact)
-
- v = db.OpenView("SELECT LastSequence FROM Media")
- v.Execute(None)
- maxmedia = -1
- while 1:
- r = v.Fetch()
- if not r: break
- seq = r.IntegerData(1)
- if seq > maxmedia:
- maxmedia = seq
- print "Start of Media", maxmedia
-
- for cabname, count in cab_and_filecount:
- stream = "merged%d" % maxmedia
- msilib.add_data(db, "Media",
- [(maxmedia+1, maxmedia+count, None, "#"+stream, None, None)])
- msilib.add_stream(db, stream, cabname)
- os.unlink(cabname)
- maxmedia += count
- # The merge module sets ALLUSERS to 1 in the property table.
- # This is undesired; delete that
- v = db.OpenView("DELETE FROM Property WHERE Property='ALLUSERS'")
- v.Execute(None)
- v.Close()
- db.Commit()
-
-merge(msiname, "SharedCRT", "TARGETDIR", modules)
-
-# certname (from config.py) should be (a substring of)
-# the certificate subject, e.g. "Python Software Foundation"
-if certname:
- os.system('signtool sign /n "%s" '
- '/t http://timestamp.verisign.com/scripts/timestamp.dll '
- '/d "Python %s" '
- '%s' % (certname, full_current_version, msiname))
-
-if pdbzip:
- build_pdbzip()
diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets
new file mode 100644
index 0000000..b507dc3
--- /dev/null
+++ b/Tools/msi/msi.targets
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <Target Name="ProcessInstallFiles" AfterTargets="PrepareForBuild" Condition="@(InstallFiles) != ''">
+ <PropertyGroup>
+ <_FileListTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.csv</_FileListTarget>
+ <_InstallFilesTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.wxs</_InstallFilesTarget>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <InstallFiles>
+ <_Source>%(Source)$([msbuild]::MakeRelative(%(SourceBase), %(FullPath)))</_Source>
+ <_Target>%(Target_)$([msbuild]::MakeRelative(%(TargetBase), %(FullPath)))</_Target>
+ </InstallFiles>
+ </ItemGroup>
+
+ <WriteLinesToFile File="$(_FileListTarget)" Lines="@(InstallFiles->'&quot;%(_Source)&quot;,&quot;%(_Target)&quot;,&quot;%(Group)&quot;,&quot;%(DiskId)&quot;,&quot;%(Condition)&quot;')" Overwrite="true" />
+ <Exec Command='"$(PythonExe)" csv_to_wxs.py "$(_FileListTarget)" "$(_InstallFilesTarget)"'
+ WorkingDirectory="$(MSBuildThisFileDirectory)" />
+
+ <ItemGroup>
+ <FileWrites Include="$(_FileListTarget);$(_InstallFilesTarget)" />
+ <Compile Include="$(_InstallFilesTarget)" />
+ </ItemGroup>
+ </Target>
+
+ <Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild" Inputs="@(WxlTemplate)" Outputs="$(IntermediateOutputPath)%(Filename).wxl">
+ <PropertyGroup>
+ <_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)`).Replace(`{{LongVersion}}`, `$(PythonVersion)`).Replace(`{{Bitness}}`, `$(Bitness)`))</_Content>
+ <_ExistingContent Condition="Exists('$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl')">$([System.IO.File]::ReadAllText($(IntermediateOutputPath)%(WxlTemplate.Filename).wxl))</_ExistingContent>
+ </PropertyGroup>
+
+ <WriteLinesToFile File="$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl"
+ Lines="$(_Content)"
+ Overwrite="true"
+ Condition="$(_Content) != $(_ExistingContent)" />
+
+ <ItemGroup>
+ <EmbeddedResource Include="$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl" />
+ <FileWrites Include="$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl" />
+ </ItemGroup>
+ </Target>
+
+ <Import Project="$(WixTargetsPath)" />
+
+ <Target Name="SignCabs">
+ <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" />
+ <Exec Command="$(_SignCommand) @(SignCabs->'&quot;%(FullPath)&quot;',' ')" ContinueOnError="false" />
+ </Target>
+ <Target Name="SignMsi">
+ <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" />
+ <Exec Command="$(_SignCommand) @(SignMsi->'&quot;%(FullPath)&quot;',' ')" ContinueOnError="false" />
+ </Target>
+ <Target Name="SignBundleEngine">
+ <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" />
+ <Exec Command="$(_SignCommand) @(SignBundleEngine->'&quot;%(FullPath)&quot;',' ')" ContinueOnError="false" />
+ </Target>
+ <Target Name="SignBundle">
+ <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" />
+ <Exec Command="$(_SignCommand) @(SignBundle->'&quot;%(FullPath)&quot;',' ')" ContinueOnError="false" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/Tools/msi/msilib.py b/Tools/msi/msilib.py
deleted file mode 100644
index c208b91..0000000
--- a/Tools/msi/msilib.py
+++ /dev/null
@@ -1,679 +0,0 @@
-# Microsoft Installer Library
-# (C) 2003 Martin v. Loewis
-
-import win32com.client.gencache
-import win32com.client
-import pythoncom, pywintypes
-from win32com.client import constants
-import re, string, os, sets, glob, subprocess, sys, _winreg, struct, _msi
-
-try:
- basestring
-except NameError:
- basestring = (str, unicode)
-
-# Partially taken from Wine
-datasizemask= 0x00ff
-type_valid= 0x0100
-type_localizable= 0x0200
-
-typemask= 0x0c00
-type_long= 0x0000
-type_short= 0x0400
-type_string= 0x0c00
-type_binary= 0x0800
-
-type_nullable= 0x1000
-type_key= 0x2000
-# XXX temporary, localizable?
-knownbits = datasizemask | type_valid | type_localizable | \
- typemask | type_nullable | type_key
-
-# Summary Info Property IDs
-PID_CODEPAGE=1
-PID_TITLE=2
-PID_SUBJECT=3
-PID_AUTHOR=4
-PID_KEYWORDS=5
-PID_COMMENTS=6
-PID_TEMPLATE=7
-PID_LASTAUTHOR=8
-PID_REVNUMBER=9
-PID_LASTPRINTED=11
-PID_CREATE_DTM=12
-PID_LASTSAVE_DTM=13
-PID_PAGECOUNT=14
-PID_WORDCOUNT=15
-PID_CHARCOUNT=16
-PID_APPNAME=18
-PID_SECURITY=19
-
-def reset():
- global _directories
- _directories = sets.Set()
-
-def EnsureMSI():
- win32com.client.gencache.EnsureModule('{000C1092-0000-0000-C000-000000000046}', 1033, 1, 0)
-
-def EnsureMSM():
- try:
- win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 1, 0)
- except pywintypes.com_error:
- win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 2, 0)
-
-_Installer=None
-def MakeInstaller():
- global _Installer
- if _Installer is None:
- EnsureMSI()
- _Installer = win32com.client.Dispatch('WindowsInstaller.Installer',
- resultCLSID='{000C1090-0000-0000-C000-000000000046}')
- return _Installer
-
-_Merge=None
-def MakeMerge2():
- global _Merge
- if _Merge is None:
- EnsureMSM()
- _Merge = win32com.client.Dispatch("Msm.Merge2.1")
- return _Merge
-
-class Table:
- def __init__(self, name):
- self.name = name
- self.fields = []
-
- def add_field(self, index, name, type):
- self.fields.append((index,name,type))
-
- def sql(self):
- fields = []
- keys = []
- self.fields.sort()
- fields = [None]*len(self.fields)
- for index, name, type in self.fields:
- index -= 1
- unk = type & ~knownbits
- if unk:
- print "%s.%s unknown bits %x" % (self.name, name, unk)
- size = type & datasizemask
- dtype = type & typemask
- if dtype == type_string:
- if size:
- tname="CHAR(%d)" % size
- else:
- tname="CHAR"
- elif dtype == type_short:
- assert size==2
- tname = "SHORT"
- elif dtype == type_long:
- assert size==4
- tname="LONG"
- elif dtype == type_binary:
- assert size==0
- tname="OBJECT"
- else:
- tname="unknown"
- print "%s.%sunknown integer type %d" % (self.name, name, size)
- if type & type_nullable:
- flags = ""
- else:
- flags = " NOT NULL"
- if type & type_localizable:
- flags += " LOCALIZABLE"
- fields[index] = "`%s` %s%s" % (name, tname, flags)
- if type & type_key:
- keys.append("`%s`" % name)
- fields = ", ".join(fields)
- keys = ", ".join(keys)
- return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys)
-
- def create(self, db):
- v = db.OpenView(self.sql())
- v.Execute(None)
- v.Close()
-
-class Binary:
- def __init__(self, fname):
- self.name = fname
- def __repr__(self):
- return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name
-
-def gen_schema(destpath, schemapath):
- d = MakeInstaller()
- schema = d.OpenDatabase(schemapath,
- win32com.client.constants.msiOpenDatabaseModeReadOnly)
-
- # XXX ORBER BY
- v=schema.OpenView("SELECT * FROM _Columns")
- curtable=None
- tables = []
- v.Execute(None)
- f = open(destpath, "wt")
- f.write("from msilib import Table\n")
- while 1:
- r=v.Fetch()
- if not r:break
- name=r.StringData(1)
- if curtable != name:
- f.write("\n%s = Table('%s')\n" % (name,name))
- curtable = name
- tables.append(name)
- f.write("%s.add_field(%d,'%s',%d)\n" %
- (name, r.IntegerData(2), r.StringData(3), r.IntegerData(4)))
- v.Close()
-
- f.write("\ntables=[%s]\n\n" % (", ".join(tables)))
-
- # Fill the _Validation table
- f.write("_Validation_records = [\n")
- v = schema.OpenView("SELECT * FROM _Validation")
- v.Execute(None)
- while 1:
- r = v.Fetch()
- if not r:break
- # Table, Column, Nullable
- f.write("(%s,%s,%s," %
- (`r.StringData(1)`, `r.StringData(2)`, `r.StringData(3)`))
- def put_int(i):
- if r.IsNull(i):f.write("None, ")
- else:f.write("%d," % r.IntegerData(i))
- def put_str(i):
- if r.IsNull(i):f.write("None, ")
- else:f.write("%s," % `r.StringData(i)`)
- put_int(4) # MinValue
- put_int(5) # MaxValue
- put_str(6) # KeyTable
- put_int(7) # KeyColumn
- put_str(8) # Category
- put_str(9) # Set
- put_str(10)# Description
- f.write("),\n")
- f.write("]\n\n")
-
- f.close()
-
-def gen_sequence(destpath, msipath):
- dir = os.path.dirname(destpath)
- d = MakeInstaller()
- seqmsi = d.OpenDatabase(msipath,
- win32com.client.constants.msiOpenDatabaseModeReadOnly)
-
- v = seqmsi.OpenView("SELECT * FROM _Tables");
- v.Execute(None)
- f = open(destpath, "w")
- print >>f, "import msilib,os;dirname=os.path.dirname(__file__)"
- tables = []
- while 1:
- r = v.Fetch()
- if not r:break
- table = r.StringData(1)
- tables.append(table)
- f.write("%s = [\n" % table)
- v1 = seqmsi.OpenView("SELECT * FROM `%s`" % table)
- v1.Execute(None)
- info = v1.ColumnInfo(constants.msiColumnInfoTypes)
- while 1:
- r = v1.Fetch()
- if not r:break
- rec = []
- for i in range(1,r.FieldCount+1):
- if r.IsNull(i):
- rec.append(None)
- elif info.StringData(i)[0] in "iI":
- rec.append(r.IntegerData(i))
- elif info.StringData(i)[0] in "slSL":
- rec.append(r.StringData(i))
- elif info.StringData(i)[0]=="v":
- size = r.DataSize(i)
- bytes = r.ReadStream(i, size, constants.msiReadStreamBytes)
- bytes = bytes.encode("latin-1") # binary data represented "as-is"
- if table == "Binary":
- fname = rec[0]+".bin"
- open(os.path.join(dir,fname),"wb").write(bytes)
- rec.append(Binary(fname))
- else:
- rec.append(bytes)
- else:
- raise "Unsupported column type", info.StringData(i)
- f.write(repr(tuple(rec))+",\n")
- v1.Close()
- f.write("]\n\n")
- v.Close()
- f.write("tables=%s\n" % repr(map(str,tables)))
- f.close()
-
-class _Unspecified:pass
-def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified):
- "Change the sequence number of an action in a sequence list"
- for i in range(len(seq)):
- if seq[i][0] == action:
- if cond is _Unspecified:
- cond = seq[i][1]
- if seqno is _Unspecified:
- seqno = seq[i][2]
- seq[i] = (action, cond, seqno)
- return
- raise ValueError, "Action not found in sequence"
-
-def add_data(db, table, values):
- d = MakeInstaller()
- v = db.OpenView("SELECT * FROM `%s`" % table)
- count = v.ColumnInfo(0).FieldCount
- r = d.CreateRecord(count)
- for value in values:
- assert len(value) == count, value
- for i in range(count):
- field = value[i]
- if isinstance(field, (int, long)):
- r.SetIntegerData(i+1,field)
- elif isinstance(field, basestring):
- r.SetStringData(i+1,field)
- elif field is None:
- pass
- elif isinstance(field, Binary):
- r.SetStream(i+1, field.name)
- else:
- raise TypeError, "Unsupported type %s" % field.__class__.__name__
- v.Modify(win32com.client.constants.msiViewModifyInsert, r)
- r.ClearData()
- v.Close()
-
-def add_stream(db, name, path):
- d = MakeInstaller()
- v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name)
- r = d.CreateRecord(1)
- r.SetStream(1, path)
- v.Execute(r)
- v.Close()
-
-def init_database(name, schema,
- ProductName, ProductCode, ProductVersion,
- Manufacturer,
- request_uac = False):
- try:
- os.unlink(name)
- except OSError:
- pass
- ProductCode = ProductCode.upper()
- d = MakeInstaller()
- # Create the database
- db = d.OpenDatabase(name,
- win32com.client.constants.msiOpenDatabaseModeCreate)
- # Create the tables
- for t in schema.tables:
- t.create(db)
- # Fill the validation table
- add_data(db, "_Validation", schema._Validation_records)
- # Initialize the summary information, allowing at most 20 properties
- si = db.GetSummaryInformation(20)
- si.SetProperty(PID_TITLE, "Installation Database")
- si.SetProperty(PID_SUBJECT, ProductName)
- si.SetProperty(PID_AUTHOR, Manufacturer)
- si.SetProperty(PID_TEMPLATE, msi_type)
- si.SetProperty(PID_REVNUMBER, gen_uuid())
- if request_uac:
- wc = 2 # long file names, compressed, original media
- else:
- wc = 2 | 8 # +never invoke UAC
- si.SetProperty(PID_WORDCOUNT, wc)
- si.SetProperty(PID_PAGECOUNT, 200)
- si.SetProperty(PID_APPNAME, "Python MSI Library")
- # XXX more properties
- si.Persist()
- add_data(db, "Property", [
- ("ProductName", ProductName),
- ("ProductCode", ProductCode),
- ("ProductVersion", ProductVersion),
- ("Manufacturer", Manufacturer),
- ("ProductLanguage", "1033")])
- db.Commit()
- return db
-
-def add_tables(db, module):
- for table in module.tables:
- add_data(db, table, getattr(module, table))
-
-def make_id(str):
- #str = str.replace(".", "_") # colons are allowed
- str = str.replace(" ", "_")
- str = str.replace("-", "_")
- str = str.replace("+", "_")
- if str[0] in string.digits:
- str = "_"+str
- assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
- return str
-
-def gen_uuid():
- return str(pythoncom.CreateGuid())
-
-class CAB:
- def __init__(self, name):
- self.name = name
- self.files = []
- self.filenames = sets.Set()
- self.index = 0
-
- def gen_id(self, dir, file):
- logical = _logical = make_id(file)
- pos = 1
- while logical in self.filenames:
- logical = "%s.%d" % (_logical, pos)
- pos += 1
- self.filenames.add(logical)
- return logical
-
- def append(self, full, file, logical = None):
- if os.path.isdir(full):
- return
- if not logical:
- logical = self.gen_id(dir, file)
- self.index += 1
- self.files.append((full, logical))
- return self.index, logical
-
- def commit(self, db):
- try:
- os.unlink(self.name+".cab")
- except OSError:
- pass
- _msi.FCICreate(self.name+".cab", self.files)
- add_data(db, "Media",
- [(1, self.index, None, "#"+self.name, None, None)])
- add_stream(db, self.name, self.name+".cab")
- os.unlink(self.name+".cab")
- db.Commit()
-
-_directories = sets.Set()
-class Directory:
- def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None):
- """Create a new directory in the Directory table. There is a current component
- at each point in time for the directory, which is either explicitly created
- through start_component, or implicitly when files are added for the first
- time. Files are added into the current component, and into the cab file.
- To create a directory, a base directory object needs to be specified (can be
- None), the path to the physical directory, and a logical directory name.
- Default specifies the DefaultDir slot in the directory table. componentflags
- specifies the default flags that new components get."""
- index = 1
- _logical = make_id(_logical)
- logical = _logical
- while logical in _directories:
- logical = "%s%d" % (_logical, index)
- index += 1
- _directories.add(logical)
- self.db = db
- self.cab = cab
- self.basedir = basedir
- self.physical = physical
- self.logical = logical
- self.component = None
- self.short_names = {}
- self.ids = sets.Set()
- self.keyfiles = {}
- self.componentflags = componentflags
- if basedir:
- self.absolute = os.path.join(basedir.absolute, physical)
- blogical = basedir.logical
- else:
- self.absolute = physical
- blogical = None
- # initially assume that all files in this directory are unpackaged
- # as files from self.absolute get added, this set is reduced
- self.unpackaged_files = set()
- for f in os.listdir(self.absolute):
- if os.path.isfile(os.path.join(self.absolute, f)):
- self.unpackaged_files.add(f)
- add_data(db, "Directory", [(logical, blogical, default)])
-
- def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None):
- """Add an entry to the Component table, and make this component the current for this
- directory. If no component name is given, the directory name is used. If no feature
- is given, the current feature is used. If no flags are given, the directory's default
- flags are used. If no keyfile is given, the KeyPath is left null in the Component
- table."""
- if flags is None:
- flags = self.componentflags
- if uuid is None:
- uuid = gen_uuid()
- else:
- uuid = uuid.upper()
- if component is None:
- component = self.logical
- self.component = component
- if Win64:
- flags |= 256
- if keyfile:
- keyid = self.cab.gen_id(self.absolute, keyfile)
- self.keyfiles[keyfile] = keyid
- else:
- keyid = None
- add_data(self.db, "Component",
- [(component, uuid, self.logical, flags, None, keyid)])
- if feature is None:
- feature = current_feature
- add_data(self.db, "FeatureComponents",
- [(feature.id, component)])
-
- def make_short(self, file):
- long = file
- file = re.sub(r'[\?|><:/*"+,;=\[\]]', '_', file) # restrictions on short names
- parts = file.split(".", 1)
- if len(parts)>1:
- suffix = parts[1].upper()
- else:
- suffix = ''
- prefix = parts[0].upper()
- if len(prefix) <= 8 and '.' not in suffix and len(suffix) <= 3:
- if suffix:
- file = prefix+"."+suffix
- else:
- file = prefix
- assert file not in self.short_names, (file, self.short_names[file])
- else:
- prefix = prefix[:6]
- if suffix:
- # last three characters of last suffix
- suffix = suffix.rsplit('.')[-1][:3]
- pos = 1
- while 1:
- if suffix:
- file = "%s~%d.%s" % (prefix, pos, suffix)
- else:
- file = "%s~%d" % (prefix, pos)
- if file not in self.short_names: break
- pos += 1
- assert pos < 10000
- if pos in (10, 100, 1000):
- prefix = prefix[:-1]
- self.short_names[file] = long
- return file
-
- def add_file(self, file, src=None, version=None, language=None):
- """Add a file to the current component of the directory, starting a new one
- if there is no current component. By default, the file name in the source
- and the file table will be identical. If the src file is specified, it is
- interpreted relative to the current directory. Optionally, a version and a
- language can be specified for the entry in the File table."""
- if not self.component:
- self.start_component(self.logical, current_feature)
- if not src:
- # Allow relative paths for file if src is not specified
- src = file
- file = os.path.basename(file)
- absolute = os.path.join(self.absolute, src)
- if absolute.startswith(self.absolute):
- # mark file as packaged
- relative = absolute[len(self.absolute)+1:]
- if relative in self.unpackaged_files:
- self.unpackaged_files.remove(relative)
- assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names
- if self.keyfiles.has_key(file):
- logical = self.keyfiles[file]
- else:
- logical = None
- sequence, logical = self.cab.append(absolute, file, logical)
- assert logical not in self.ids
- self.ids.add(logical)
- short = self.make_short(file)
- full = "%s|%s" % (short, file)
- filesize = os.stat(absolute).st_size
- # constants.msidbFileAttributesVital
- # Compressed omitted, since it is the database default
- # could add r/o, system, hidden
- attributes = 512
- add_data(self.db, "File",
- [(logical, self.component, full, filesize, version,
- language, attributes, sequence)])
- if not version:
- # Add hash if the file is not versioned
- filehash = MakeInstaller().FileHash(absolute, 0)
- add_data(self.db, "MsiFileHash",
- [(logical, 0, filehash.IntegerData(1),
- filehash.IntegerData(2), filehash.IntegerData(3),
- filehash.IntegerData(4))])
- # Automatically remove .pyc/.pyo files on uninstall (2)
- # XXX: adding so many RemoveFile entries makes installer unbelievably
- # slow. So instead, we have to use wildcard remove entries
- # if file.endswith(".py"):
- # add_data(self.db, "RemoveFile",
- # [(logical+"c", self.component, "%sC|%sc" % (short, file),
- # self.logical, 2),
- # (logical+"o", self.component, "%sO|%so" % (short, file),
- # self.logical, 2)])
-
- def glob(self, pattern, exclude = None):
- """Add a list of files to the current component as specified in the
- glob pattern. Individual files can be excluded in the exclude list."""
- files = glob.glob1(self.absolute, pattern)
- for f in files:
- if exclude and f in exclude: continue
- self.add_file(f)
- return files
-
- def remove_pyc(self):
- "Remove .pyc/.pyo files from __pycache__ on uninstall"
- directory = self.logical + "_pycache"
- add_data(self.db, "Directory", [(directory, self.logical, "__PYCA~1|__pycache__")])
- flags = 256 if Win64 else 0
- add_data(self.db, "Component",
- [(directory, gen_uuid(), directory, flags, None, None)])
- add_data(self.db, "FeatureComponents", [(current_feature.id, directory)])
- add_data(self.db, "CreateFolder", [(directory, directory)])
- add_data(self.db, "RemoveFile",
- [(self.component, self.component, "*.*", directory, 2),
- ])
-
- def removefile(self, key, pattern):
- "Add a RemoveFile entry"
- add_data(self.db, "RemoveFile", [(self.component+key, self.component, pattern, self.logical, 2)])
-
-
-class Feature:
- def __init__(self, db, id, title, desc, display, level = 1,
- parent=None, directory = None, attributes=0):
- self.id = id
- if parent:
- parent = parent.id
- add_data(db, "Feature",
- [(id, parent, title, desc, display,
- level, directory, attributes)])
- def set_current(self):
- global current_feature
- current_feature = self
-
-class Control:
- def __init__(self, dlg, name):
- self.dlg = dlg
- self.name = name
-
- def event(self, ev, arg, cond = "1", order = None):
- add_data(self.dlg.db, "ControlEvent",
- [(self.dlg.name, self.name, ev, arg, cond, order)])
-
- def mapping(self, ev, attr):
- add_data(self.dlg.db, "EventMapping",
- [(self.dlg.name, self.name, ev, attr)])
-
- def condition(self, action, condition):
- add_data(self.dlg.db, "ControlCondition",
- [(self.dlg.name, self.name, action, condition)])
-
-class RadioButtonGroup(Control):
- def __init__(self, dlg, name, property):
- self.dlg = dlg
- self.name = name
- self.property = property
- self.index = 1
-
- def add(self, name, x, y, w, h, text, value = None):
- if value is None:
- value = name
- add_data(self.dlg.db, "RadioButton",
- [(self.property, self.index, value,
- x, y, w, h, text, None)])
- self.index += 1
-
-class Dialog:
- def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel):
- self.db = db
- self.name = name
- self.x, self.y, self.w, self.h = x,y,w,h
- add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)])
-
- def control(self, name, type, x, y, w, h, attr, prop, text, next, help):
- add_data(self.db, "Control",
- [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)])
- return Control(self, name)
-
- def text(self, name, x, y, w, h, attr, text):
- return self.control(name, "Text", x, y, w, h, attr, None,
- text, None, None)
-
- def bitmap(self, name, x, y, w, h, text):
- return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None)
-
- def line(self, name, x, y, w, h):
- return self.control(name, "Line", x, y, w, h, 1, None, None, None, None)
-
- def pushbutton(self, name, x, y, w, h, attr, text, next):
- return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None)
-
- def radiogroup(self, name, x, y, w, h, attr, prop, text, next):
- add_data(self.db, "Control",
- [(self.name, name, "RadioButtonGroup",
- x, y, w, h, attr, prop, text, next, None)])
- return RadioButtonGroup(self, name, prop)
-
- def checkbox(self, name, x, y, w, h, attr, prop, text, next):
- return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None)
-
-def pe_type(path):
- header = open(path, "rb").read(1000)
- # offset of PE header is at offset 0x3c
- pe_offset = struct.unpack("<i", header[0x3c:0x40])[0]
- assert header[pe_offset:pe_offset+4] == "PE\0\0"
- machine = struct.unpack("<H", header[pe_offset+4:pe_offset+6])[0]
- return machine
-
-def set_arch_from_file(path):
- global msi_type, Win64, arch_ext
- machine = pe_type(path)
- if machine == 0x14c:
- # i386
- msi_type = "Intel"
- Win64 = 0
- arch_ext = ''
- elif machine == 0x200:
- # Itanium
- msi_type = "Intel64"
- Win64 = 1
- arch_ext = '.ia64'
- elif machine == 0x8664:
- # AMD64
- msi_type = "x64"
- Win64 = 1
- arch_ext = '.amd64'
- else:
- raise ValueError, "Unsupported architecture"
- msi_type += ";1033"
diff --git a/Tools/msi/msisupport.c b/Tools/msi/msisupport.c
deleted file mode 100644
index 1fd2ee4..0000000
--- a/Tools/msi/msisupport.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "windows.h"
-#include "msiquery.h"
-
-/* Print a debug message to the installer log file.
- * To see the debug messages, install with
- * msiexec /i pythonxy.msi /l*v python.log
- */
-static UINT debug(MSIHANDLE hInstall, LPCSTR msg)
-{
- MSIHANDLE hRec = MsiCreateRecord(1);
- if (!hRec || MsiRecordSetStringA(hRec, 1, msg) != ERROR_SUCCESS) {
- return ERROR_INSTALL_FAILURE;
- }
- MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRec);
- MsiCloseHandle(hRec);
- return ERROR_SUCCESS;
-}
-
-/* Check whether the TARGETDIR exists and is a directory.
- * Set TargetExists appropriately.
- */
-UINT __declspec(dllexport) __stdcall CheckDir(MSIHANDLE hInstall)
-{
-#define PSIZE 1024
- WCHAR wpath[PSIZE];
- char path[PSIZE];
- UINT result;
- DWORD size = PSIZE;
- DWORD attributes;
-
-
- result = MsiGetPropertyW(hInstall, L"TARGETDIR", wpath, &size);
- if (result != ERROR_SUCCESS)
- return result;
- wpath[size] = L'\0';
- path[size] = L'\0';
-
- attributes = GetFileAttributesW(wpath);
- if (attributes == INVALID_FILE_ATTRIBUTES ||
- !(attributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- return MsiSetPropertyA(hInstall, "TargetExists", "0");
- } else {
- return MsiSetPropertyA(hInstall, "TargetExists", "1");
- }
-}
-
-/* Update the state of the REGISTRY.tcl component according to the
- * Extension and TclTk features. REGISTRY.tcl must be installed
- * if both features are installed, and must be absent otherwise.
- */
-UINT __declspec(dllexport) __stdcall UpdateEditIDLE(MSIHANDLE hInstall)
-{
- INSTALLSTATE ext_old, ext_new, tcl_old, tcl_new, reg_new;
- UINT result;
-
- result = MsiGetFeatureStateA(hInstall, "Extensions", &ext_old, &ext_new);
- if (result != ERROR_SUCCESS)
- return result;
- result = MsiGetFeatureStateA(hInstall, "TclTk", &tcl_old, &tcl_new);
- if (result != ERROR_SUCCESS)
- return result;
-
- /* If the current state is Absent, and the user did not select
- the feature in the UI, Installer apparently sets the "selected"
- state to unknown. Update it to the current value, then. */
- if (ext_new == INSTALLSTATE_UNKNOWN)
- ext_new = ext_old;
- if (tcl_new == INSTALLSTATE_UNKNOWN)
- tcl_new = tcl_old;
-
- // XXX consider current state of REGISTRY.tcl?
- if (((tcl_new == INSTALLSTATE_LOCAL) ||
- (tcl_new == INSTALLSTATE_SOURCE) ||
- (tcl_new == INSTALLSTATE_DEFAULT)) &&
- ((ext_new == INSTALLSTATE_LOCAL) ||
- (ext_new == INSTALLSTATE_SOURCE) ||
- (ext_new == INSTALLSTATE_DEFAULT))) {
- reg_new = INSTALLSTATE_SOURCE;
- } else {
- reg_new = INSTALLSTATE_ABSENT;
- }
- result = MsiSetComponentStateA(hInstall, "REGISTRY.tcl", reg_new);
- return result;
-}
-
-BOOL APIENTRY DllMain(HANDLE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved)
-{
- return TRUE;
-}
-
diff --git a/Tools/msi/msisupport.mak b/Tools/msi/msisupport.mak
deleted file mode 100644
index 2905dbe..0000000
--- a/Tools/msi/msisupport.mak
+++ /dev/null
@@ -1,9 +0,0 @@
-# /OPT: REF and ICF are added by VS.NET by default
-msisupport.dll: msisupport.obj
- link.exe /OUT:msisupport.dll /INCREMENTAL:NO /NOLOGO /DLL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF msisupport.obj msi.lib kernel32.lib
-
-# We request a static CRT, so that there will be no CRT dependencies
-# for the target system. We cannot do without a CRT, since it provides
-# the DLL entry point.
-msisupport.obj: msisupport.c
- cl /O2 /D WIN32 /D NDEBUG /D _WINDOWS /MT /W3 /c msisupport.c
diff --git a/Tools/msi/path/path.wixproj b/Tools/msi/path/path.wixproj
new file mode 100644
index 0000000..2792e14
--- /dev/null
+++ b/Tools/msi/path/path.wixproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{91C99298-8E2E-4422-A5AF-CC4FFF9A58D3}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>path</OutputName>
+ <OutputType>Package</OutputType>
+ <SuppressIces>ICE71</SuppressIces>
+ </PropertyGroup>
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs
new file mode 100644
index 0000000..7e462e2
--- /dev/null
+++ b/Tools/msi/path/path.wxs
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
+ <Package InstallerVersion="300" Compressed="yes" InstallScope="perUser" Platform="$(var.Platform)" />
+
+ <PropertyRef Id="UpgradeTable" />
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
+ <Component Id="PrependPath_CU" Directory="InstallDirectory" Guid="*">
+ <Condition>NOT ALLUSERS=1</Condition>
+ <RegistryValue KeyPath="yes" Root="HKCU" Key="[REGISTRYKEY]\PrependPath" Value="1" Type="integer" />
+
+ <CreateFolder Directory="Scripts" />
+ <RemoveFolder Id="Remove_Scripts_CU" Directory="Scripts" On="uninstall" />
+
+ <Environment Id="PATH_CU" Action="set" Name="PATH" Part="first" Value="[InstallDirectory]" />
+ <Environment Id="SCRIPTS_PATH_CU" Action="set" Name="PATH" Part="first" Value="[Scripts]" />
+ </Component>
+ <Component Id="PrependPath_LM" Directory="InstallDirectory" Guid="*">
+ <Condition>ALLUSERS=1</Condition>
+ <RegistryValue KeyPath="yes" Root="HKLM" Key="[REGISTRYKEY]\PrependPath" Value="1" Type="integer" />
+
+ <CreateFolder Directory="Scripts" />
+ <RemoveFolder Id="Remove_Scripts_LM" Directory="Scripts" On="uninstall" />
+
+ <Environment Id="PATH_LM" Action="set" Name="PATH" Part="first" Value="[InstallDirectory]" System="yes" />
+ <Environment Id="SCRIPTS_PATH_LM" Action="set" Name="PATH" Part="first" Value="[Scripts]" System="yes" />
+ <Environment Id="PY_PATHEXT_LM" Action="set" Name="PATHEXT" Part="last" Value=".PY" System="yes" />
+ <Environment Id="PYW_PATHEXT_LM" Action="set" Name="PATHEXT" Part="last" Value=".PYW" System="yes" />
+ </Component>
+ </Feature>
+ </Product>
+</Wix>
+
diff --git a/Tools/msi/path/path_en-US.wxl b/Tools/msi/path/path_en-US.wxl
new file mode 100644
index 0000000..33a7886
--- /dev/null
+++ b/Tools/msi/path/path_en-US.wxl
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
+ <String Id="Descriptor">Add to Path</String>
+ <String Id="ShortDescriptor">Path</String>
+ <String Id="NoPython">No !(loc.ProductName) installation was detected.</String>
+</WixLocalization>
diff --git a/Tools/msi/pip/pip.wixproj b/Tools/msi/pip/pip.wixproj
new file mode 100644
index 0000000..718c02c
--- /dev/null
+++ b/Tools/msi/pip/pip.wixproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{91C99298-8E2E-4422-A5AF-CC4FFF9A58D3}</ProjectGuid>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputName>pip</OutputName>
+ <OutputType>Package</OutputType>
+ <SuppressIces>ICE71</SuppressIces>
+ </PropertyGroup>
+ <Import Project="..\msi.props" />
+ <ItemGroup>
+ <Compile Include="*.wxs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="*.wxl" />
+ </ItemGroup>
+
+ <Import Project="..\msi.targets" />
+</Project> \ No newline at end of file
diff --git a/Tools/msi/pip/pip.wxs b/Tools/msi/pip/pip.wxs
new file mode 100644