@@ -339,10 +339,11 @@ def _sentinel_file_checks(example_path, install_dir):
339339
340340
341341def is_admin () -> bool :
342- try :
343- return ctypes .windll .shell32 .IsUserAnAdmin ()
344- except Exception :
345- return False
342+ #try:
343+ # return ctypes.windll.shell32.IsUserAnAdmin()
344+ #except Exception:
345+ # return False
346+ return False
346347
347348
348349def calculate_msi_install_path (installer : Path ) -> Path :
@@ -355,6 +356,7 @@ def calculate_msi_install_path(installer: Path) -> Path:
355356 else :
356357 local_dir = os .environ .get ("LOCALAPPDATA" , str (Path .home () / r"AppData\Local" ))
357358 root_dir = Path (local_dir ) / "Programs"
359+ root_dir .mkdir (parents = True , exist_ok = True )
358360
359361 assert root_dir .is_dir () # Sanity check to avoid strange unexpected errors
360362 return Path (root_dir ) / dir_name
@@ -388,8 +390,13 @@ def _run_installer_msi(
388390 "/qn" ,
389391 ]
390392
391- log_path = Path (os .environ .get ("TEMP" )) / (install_dir .name + ".log" )
393+ log_path = Path (os .environ .get ("TEMP" )) / (install_dir .name + "-install .log" )
392394 cmd .extend (["/L*V" , str (log_path )])
395+
396+ post_install_log = Path (os .environ .get ("TEMP" )) / (install_dir .name + "-postinstall.log" )
397+ if post_install_log .exists ():
398+ os .remove (post_install_log )
399+
393400 try :
394401 process = _execute (cmd , installer_input = installer_input , timeout = timeout , check = check )
395402 except subprocess .CalledProcessError as e :
@@ -401,9 +408,23 @@ def _run_installer_msi(
401408 log_path .read_text (encoding = "utf-16" , errors = "replace" )[- 15000 :]
402409 ) # last 15k chars
403410 print (f"\n === MSI LOG { log_path } END ===" )
411+ if post_install_log .exists ():
412+ print (f"\n === MSI POST INSTALL LOG { post_install_log } START ===" )
413+ print (post_install_log .read_text (encoding = "utf-8" , errors = "replace" ))
414+ print (f"\n === MSI POST INSTALL LOG { log_path } END ===" )
415+ else :
416+ print (f"\n (post-install log not found at { post_install_log } )\n " )
404417 raise e
405418 if check :
406419 print ("A check for MSI Installers not yet implemented" )
420+
421+ # Sanity check the installation directory
422+ expected_items = [install_dir / "base" , install_dir / "base" / "conda-meta" , install_dir / "_conda.exe" ]
423+ missing_items = [item for item in expected_items if not item .exists ()]
424+ if missing_items :
425+ missing_items_string = "\n " .join (missing_items )
426+ raise Exception (f"Sanity check failed, unable to find expected paths: \n { missing_items_string } " )
427+
407428 return process
408429
409430
@@ -419,7 +440,45 @@ def _run_uninstaller_msi(
419440 str (installer ),
420441 "/qn" ,
421442 ]
422- process = _execute (cmd , timeout = timeout , check = check )
443+
444+ # Temporary debug
445+ print ("base exists:" , (install_dir / "base" ).exists ())
446+ print ("conda-meta exists:" , (install_dir / "base" / "conda-meta" ).exists ())
447+ print ("conda-meta history exists:" , (install_dir / "base" / "conda-meta" / "history" ).exists ())
448+
449+ print (f"\n === Top-level contents of { install_dir } ===" )
450+ for p in sorted (install_dir .iterdir ()):
451+ kind = "DIR " if p .is_dir () else "FILE"
452+ print (f"{ kind :4} { p .name } " )
453+
454+ # Add MSI verbose log file
455+ log_path = Path (os .environ .get ("TEMP" )) / (install_dir .name + "-uninstall.log" )
456+ cmd .extend (["/L*V" , str (log_path )])
457+
458+ # Add log file for pre_uninstall.bat
459+ pre_uninstall_log = Path (os .environ .get ("TEMP" )) / (install_dir .name + "-preuninstall.log" )
460+ if pre_uninstall_log .exists ():
461+ os .remove (pre_uninstall_log )
462+ try :
463+ process = _execute (cmd , installer_input = None , timeout = timeout , check = check )
464+ except subprocess .CalledProcessError :
465+ # Dump pre-uninstall log
466+ if pre_uninstall_log .exists ():
467+ print (f"\n === PRE-UNINSTALL LOG { pre_uninstall_log } START ===" )
468+ print (pre_uninstall_log .read_text (encoding = "utf-8" , errors = "replace" )[- 15000 :])
469+ print (f"=== PRE-UNINSTALL LOG { pre_uninstall_log } END ===\n " )
470+ else :
471+ print (f"\n (pre-uninstall log not found at { pre_uninstall_log } )\n " )
472+
473+ # Dump MSI uninstall log (often UTF-16)
474+ if log_path .exists ():
475+ print (f"\n === MSI UNINSTALL LOG { log_path } START ===" )
476+ print (log_path .read_text (encoding = "utf-16" , errors = "replace" )[- 15000 :]) # last 15k chars
477+ print (f"=== MSI UNINSTALL LOG { log_path } END ===\n " )
478+ else :
479+ print (f"\n (msi uninstall log not found at { log_path } )\n " )
480+ raise
481+
423482 if check :
424483 # TODO:
425484 # Check log and if there are remaining files, similar to the exe installers
0 commit comments