diff --git a/core/includes/install.inc b/core/includes/install.inc
index 2834e918f535105e9f4be231ee9bef6b4b0b11c6..3f2f79b6fc70bf8166dcd8234e73a54feb498802 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -109,7 +109,7 @@ function drupal_install_profile_distribution_name() {
   // At all other times, we load the profile via standard methods.
   else {
     $profile = \Drupal::installProfile();
-    $info = system_get_info('module', $profile);
+    $info = \Drupal::service('extension.list.profile')->getExtensionInfo($profile);
   }
   return isset($info['distribution']['name']) ? $info['distribution']['name'] : 'Drupal';
 }
@@ -134,7 +134,7 @@ function drupal_install_profile_distribution_version() {
   // At all other times, we load the profile via standard methods.
   else {
     $profile = \Drupal::installProfile();
-    $info = system_get_info('module', $profile);
+    $info = \Drupal::service('extension.list.profile')->getExtensionInfo($profile);
     return $info['version'];
   }
 }
@@ -1095,7 +1095,8 @@ function drupal_check_module($module) {
  *
  * Note that this function does an expensive file system scan to get info file
  * information for dependencies. If you only need information from the info
- * file itself, use system_get_info().
+ * file itself, use
+ * \Drupal::service('extension.list.profile')->getExtensionInfo().
  *
  * Example of .info.yml file:
  * @code
diff --git a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php
index eb564ee9ab8ac29334ba2a4c1057b2124e7c9720..5aee5cf0f22792cb1f64fd8d5090e3f20e0dffd5 100644
--- a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php
+++ b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php
@@ -49,13 +49,6 @@ class MenuLinkDefaultForm implements MenuLinkFormInterface, ContainerInjectionIn
    */
   protected $moduleHandler;
 
-  /**
-   * The module data from system_get_info().
-   *
-   * @var array
-   */
-  protected $moduleData;
-
   /**
    * Constructs a new \Drupal\Core\Menu\Form\MenuLinkDefaultForm.
    *
diff --git a/core/modules/block/tests/src/Kernel/BlockConfigSchemaTest.php b/core/modules/block/tests/src/Kernel/BlockConfigSchemaTest.php
index 2bf41e0f4c02c4665d88efdc0a2ab6483fcf2eaf..99854faf4facf3f6f78d5b03a740a885d8a30f79 100644
--- a/core/modules/block/tests/src/Kernel/BlockConfigSchemaTest.php
+++ b/core/modules/block/tests/src/Kernel/BlockConfigSchemaTest.php
@@ -27,7 +27,7 @@ class BlockConfigSchemaTest extends KernelTestBase {
     'forum',
     'node',
     'statistics',
-    // BlockManager->getModuleName() calls system_get_info().
+    // \Drupal\block\Entity\Block->preSave() calls system_region_list().
     'system',
     'taxonomy',
     'user',
diff --git a/core/modules/ckeditor/ckeditor.module b/core/modules/ckeditor/ckeditor.module
index 869c0e916d41f9705c87bfedc4a5b398a9d73479..55bbf5b2fb6ca107602e7a1d8fd0ec9c4aa54f3c 100644
--- a/core/modules/ckeditor/ckeditor.module
+++ b/core/modules/ckeditor/ckeditor.module
@@ -85,7 +85,7 @@ function _ckeditor_theme_css($theme = NULL) {
     $theme = \Drupal::config('system.theme')->get('default');
   }
   if (isset($theme) && $theme_path = drupal_get_path('theme', $theme)) {
-    $info = system_get_info('theme', $theme);
+    $info = \Drupal::service('extension.list.theme')->getExtensionInfo($theme);
     if (isset($info['ckeditor_stylesheets'])) {
       $css = $info['ckeditor_stylesheets'];
       foreach ($css as $key => $url) {
diff --git a/core/modules/help/src/Controller/HelpController.php b/core/modules/help/src/Controller/HelpController.php
index edf8a8a5b734896720bd58ec899d8e69500b272d..92d12d6ceba0686f2800a7c5cbbc3558cc0c7d35 100644
--- a/core/modules/help/src/Controller/HelpController.php
+++ b/core/modules/help/src/Controller/HelpController.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\help\HelpSectionManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -28,6 +29,13 @@ class HelpController extends ControllerBase {
    */
   protected $helpManager;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * Creates a new HelpController.
    *
@@ -35,10 +43,18 @@ class HelpController extends ControllerBase {
    *   The current route match.
    * @param \Drupal\help\HelpSectionManager $help_manager
    *   The help section manager.
+   * @param \Drupal\Core\Extension\ModuleExtensionList|null $module_extension_list
+   *   The module extension list. This is left optional for BC reasons, but the
+   *   optional usage is deprecated and will become required in Drupal 9.0.0.
    */
-  public function __construct(RouteMatchInterface $route_match, HelpSectionManager $help_manager) {
+  public function __construct(RouteMatchInterface $route_match, HelpSectionManager $help_manager, ModuleExtensionList $module_extension_list = NULL) {
     $this->routeMatch = $route_match;
     $this->helpManager = $help_manager;
+    if ($module_extension_list === NULL) {
+      @trigger_error('Calling HelpController::__construct() with the $module_extension_list argument is supported in drupal:8.8.0 and will be required before drupal:9.0.0. See https://www.drupal.org/node/2709919.', E_USER_DEPRECATED);
+      $module_extension_list = \Drupal::service('extension.list.module');
+    }
+    $this->moduleExtensionList = $module_extension_list;
   }
 
   /**
@@ -47,7 +63,8 @@ public function __construct(RouteMatchInterface $route_match, HelpSectionManager
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('current_route_match'),
-      $container->get('plugin.manager.help_section')
+      $container->get('plugin.manager.help_section'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -119,7 +136,7 @@ public function helpPage($name) {
       $module_name = $this->moduleHandler()->getName($name);
       $build['#title'] = $module_name;
 
-      $info = system_get_info('module', $name);
+      $info = $this->moduleExtensionList->getExtensionInfo($name);
       if ($info['package'] === 'Core (Experimental)') {
         $this->messenger()->addWarning($this->t('This module is experimental. <a href=":url">Experimental modules</a> are provided for testing purposes only. Use at your own risk.', [':url' => 'https://www.drupal.org/core/experimental']));
       }
@@ -137,7 +154,7 @@ public function helpPage($name) {
 
       // Only print list of administration pages if the module in question has
       // any such pages associated with it.
-      $admin_tasks = system_get_module_admin_tasks($name, system_get_info('module', $name));
+      $admin_tasks = system_get_module_admin_tasks($name, $info);
       if (!empty($admin_tasks)) {
         $links = [];
         foreach ($admin_tasks as $task) {
diff --git a/core/modules/help/tests/src/Functional/HelpTest.php b/core/modules/help/tests/src/Functional/HelpTest.php
index 8d1e538c176d7f51d0bea527230ae21aba68338b..608263d4c9dcce9c51b7ffe05ef8ecb377b21bb8 100644
--- a/core/modules/help/tests/src/Functional/HelpTest.php
+++ b/core/modules/help/tests/src/Functional/HelpTest.php
@@ -124,7 +124,8 @@ protected function verifyHelp($response = 200) {
       if ($response == 200) {
         $this->assertTitle($name . ' | Drupal', new FormattableMarkup('%module title was displayed', ['%module' => $module]));
         $this->assertEquals($name, $this->cssSelect('h1.page-title')[0]->getText(), "$module heading was displayed");
-        $admin_tasks = system_get_module_admin_tasks($module, system_get_info('module', $module));
+        $info = \Drupal::service('extension.list.module')->getExtensionInfo($module);
+        $admin_tasks = system_get_module_admin_tasks($module, $info);
         if (!empty($admin_tasks)) {
           $this->assertText(t('@module administration pages', ['@module' => $name]));
         }
diff --git a/core/modules/media/media.install b/core/modules/media/media.install
index 25a4f5dfe203305d6e84a53ffde65482dcf26a6b..83b6a35c21cde802b2c93ee397d07ec3dad269ea 100644
--- a/core/modules/media/media.install
+++ b/core/modules/media/media.install
@@ -80,7 +80,7 @@ function media_requirements($phase) {
 
     // Prevent installation if the 1.x branch of the contrib module is enabled.
     if (\Drupal::moduleHandler()->moduleExists('media_entity')) {
-      $info = system_get_info('module', 'media_entity');
+      $info = \Drupal::service('extension.list.module')->getExtensionInfo('media_entity');
       if (version_compare($info['version'], '8.x-2') < 0) {
         $requirements['media_module_incompatibility'] = [
           'title' => t('Media'),
diff --git a/core/modules/quickedit/quickedit.module b/core/modules/quickedit/quickedit.module
index fc92d9ca789767c12b12e3761a438d213f5dd7b3..9741006e6195ad06524a64fe38b22f29b3489ff1 100644
--- a/core/modules/quickedit/quickedit.module
+++ b/core/modules/quickedit/quickedit.module
@@ -80,7 +80,7 @@ function quickedit_library_info_alter(&$libraries, $extension) {
     // First let the base theme modify the library, then the actual theme.
     $alter_library = function (&$library, $theme) use (&$alter_library) {
       if (!empty($theme) && $theme_path = drupal_get_path('theme', $theme)) {
-        $info = system_get_info('theme', $theme);
+        $info = \Drupal::service('extension.list.theme')->getExtensionInfo($theme);
         // Recurse to process base theme(s) first.
         if (isset($info['base theme'])) {
           $alter_library($library, $info['base theme']);
diff --git a/core/modules/system/src/Controller/AdminController.php b/core/modules/system/src/Controller/AdminController.php
index 3da4b0901dc9b93bdfa4e74427e3888c070e9633..767a8ce2267b0df6f789a7a1d2df94368e33dd66 100644
--- a/core/modules/system/src/Controller/AdminController.php
+++ b/core/modules/system/src/Controller/AdminController.php
@@ -3,12 +3,45 @@
 namespace Drupal\system\Controller;
 
 use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Extension\ModuleExtensionList;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Controller for admin section.
  */
 class AdminController extends ControllerBase {
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
+  /**
+   * AdminController constructor.
+   *
+   * @param \Drupal\Core\Extension\ModuleExtensionList|null $extension_list_module
+   *   The module extension list. This is left optional for BC reasons, but the
+   *   optional usage is deprecated and will become required in Drupal 9.0.0.
+   */
+  public function __construct(ModuleExtensionList $extension_list_module = NULL) {
+    if ($extension_list_module === NULL) {
+      @trigger_error('Calling AdminController::__construct() with the $module_extension_list argument is supported in drupal:8.8.0 and will be required before drupal:9.0.0. See https://www.drupal.org/node/2709919.', E_USER_DEPRECATED);
+      $extension_list_module = \Drupal::service('extension.list.module');
+    }
+    $this->moduleExtensionList = $extension_list_module;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('extension.list.module')
+    );
+  }
+
   /**
    * Prints a listing of admin tasks, organized by module.
    *
@@ -16,7 +49,7 @@ class AdminController extends ControllerBase {
    *   A render array containing the listing.
    */
   public function index() {
-    $module_info = system_get_info('module');
+    $module_info = $this->moduleExtensionList->getAllInstalledInfo();
     foreach ($module_info as $module => $info) {
       $module_info[$module] = new \stdClass();
       $module_info[$module]->info = $info;
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 69433cf8977a91461834ceb088cf3fa29a4a7415..001ddcae8830c9d6818f33b9832901dab720b1ef 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -50,7 +50,7 @@ function system_requirements($phase) {
     // is not running the default installation profile.
     $profile = \Drupal::installProfile();
     if ($profile != 'standard') {
-      $info = system_get_info('module', $profile);
+      $info = \Drupal::service('extension.list.module')->getExtensionInfo($profile);
       $requirements['install_profile'] = [
         'title' => t('Installation profile'),
         'value' => t('%profile_name (%profile-%version)', [
@@ -67,7 +67,7 @@ function system_requirements($phase) {
     $experimental = [];
     $enabled_modules = \Drupal::moduleHandler()->getModuleList();
     foreach ($enabled_modules as $module => $data) {
-      $info = system_get_info('module', $module);
+      $info = \Drupal::service('extension.list.module')->getExtensionInfo($module);
       if (isset($info['package']) && $info['package'] === 'Core (Experimental)') {
         $experimental[$module] = $info['name'];
       }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index b65838f376cec723a3bed44ed4dd08019370b57e..b6dc4fb101c251389b650e4f9ed416385fd55747 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -979,10 +979,16 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
  *   information for $name, if given. If no records are available, an empty
  *   array is returned.
  *
+ * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
+ *   \Drupal::service('extension.list.$type')->getExtensionInfo() or
+ *   \Drupal::service('extension.list.$type')->getAllInstalledInfo() instead.
+ *
+ * @see https://www.drupal.org/node/2709919
  * @see \Drupal\Core\Extension\ModuleExtensionList::getList()
  * @see \Drupal\Core\Extension\ThemeExtensionList
  */
 function system_get_info($type, $name = NULL) {
+  @trigger_error("system_get_info() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal::service('extension.list.$type')->getExtensionInfo() or \Drupal::service('extension.list.$type')->getAllInstalledInfo() instead. See https://www.drupal.org/node/2709919", E_USER_DEPRECATED);
   /** @var \Drupal\Core\Extension\ExtensionList $extension_list */
   $extension_list = \Drupal::service('extension.list.' . $type);
   if (isset($name)) {
@@ -1168,7 +1174,8 @@ function system_admin_compact_mode() {
  * @param string $module
  *   Module name.
  * @param array $info
- *   The module's information, as provided by system_get_info().
+ *   The module's information, as provided by
+ *   \Drupal::service('extension.list.module')->getExtensionInfo().
  *
  * @return array
  *   An array of task links.
diff --git a/core/modules/system/tests/src/Kernel/System/SystemGetInfoTest.php b/core/modules/system/tests/src/Kernel/System/SystemGetInfoTest.php
index cd42fa48707d52214c51312005ac2518e7ffc10a..881005b02686cb876158f3d32f2c1eb3b1d1b803 100644
--- a/core/modules/system/tests/src/Kernel/System/SystemGetInfoTest.php
+++ b/core/modules/system/tests/src/Kernel/System/SystemGetInfoTest.php
@@ -8,6 +8,7 @@
  * Tests system_get_info().
  *
  * @group system
+ * @group legacy
  */
 class SystemGetInfoTest extends KernelTestBase {
 
@@ -15,6 +16,9 @@ class SystemGetInfoTest extends KernelTestBase {
 
   /**
    * Tests system_get_info().
+   *
+   * @expectedDeprecation system_get_info() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal::service('extension.list.module')->getExtensionInfo() or \Drupal::service('extension.list.module')->getAllInstalledInfo() instead. See https://www.drupal.org/node/2709919
+   * @expectedDeprecation system_get_info() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal::service('extension.list.theme')->getExtensionInfo() or \Drupal::service('extension.list.theme')->getAllInstalledInfo() instead. See https://www.drupal.org/node/2709919
    */
   public function testSystemGetInfo() {
     $system_module_info = system_get_info('module', 'system');
diff --git a/core/profiles/demo_umami/demo_umami.install b/core/profiles/demo_umami/demo_umami.install
index 37025e0826840a23ff81be443afedb74cf05d21f..4137ca2ef37fbc50642a444711c01cdb404ac44d 100644
--- a/core/profiles/demo_umami/demo_umami.install
+++ b/core/profiles/demo_umami/demo_umami.install
@@ -15,7 +15,7 @@ function demo_umami_requirements($phase) {
   $requirements = [];
   if ($phase == 'runtime') {
     $profile = \Drupal::installProfile();
-    $info = system_get_info('module', $profile);
+    $info = \Drupal::service('extension.list.profile')->getExtensionInfo($profile);
     $requirements['experimental_profile_used'] = [
       'title' => t('Experimental installation profile used'),
       'value' => $info['name'],
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
index f6e8ee7136fdf25e264fe4c0e767d815fd3c3606..d625c2d9f68e7b9318be128026834ea1dd76a7bd 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
@@ -321,7 +321,7 @@ public function testThemeInfoAlter() {
     // Legacy assertions.
     // @todo Remove once theme initialization/info has been modernized.
     // @see https://www.drupal.org/node/2228093
-    $info = system_get_info('theme', $name);
+    $info = \Drupal::service('extension.list.theme')->getExtensionInfo($name);
     $this->assertTrue(isset($info['regions']['test_region']));
     $regions = system_region_list($name);
     $this->assertTrue(isset($regions['test_region']));
@@ -337,7 +337,7 @@ public function testThemeInfoAlter() {
     // Legacy assertions.
     // @todo Remove once theme initialization/info has been modernized.
     // @see https://www.drupal.org/node/2228093
-    $info = system_get_info('theme', $name);
+    $info = \Drupal::service('extension.list.theme')->getExtensionInfo($name);
     $this->assertFalse(isset($info['regions']['test_region']));
     $regions = system_region_list($name);
     $this->assertFalse(isset($regions['test_region']));