diskpart #运行diskpart工具 隐藏 EFI 分区的方法
有时候系统的EFI分区也显示在资源管理器中,双击提示不能进去,区分大小一般是300M,这就是系统启动分区EFI分区,一般情况下是看不见的,如果你能看见说明系统经过了某些操作才会如此,现在可以按以下操作,不让这个系统分区展示出来。

打开cmd或powershell,按如下命令行操作(以powershell示例,#及后面文字为注释内容不需要输入):

diskpart  #运行diskpart工具
lis dis  #列出所有磁盘
sel dis 2  #选中u盘,视你的磁盘大小判断选择数字,2是我的u盘
lis par  #列出所有分区
sel par 2  #选中efi分区,视你的分区大小判断选择,2是我的efi分区
detail par  #查看该分区详细信息

#如果在磁盘管理器中看不到可以显示出来的
#set id=06  #取消分区隐藏,如果是1b或1c就改成0b或0c,执行该命令后磁盘管理中就能看到efi盘符了

#这里在LTR一列可以看到分配的盘符,我这里是H,区分大小写的
remove letter=H  #移除分区盘符,视你的efi分区盘符选择

#设置回隐藏的
#set id=16  #分区类型改回隐藏

1705558696616.jpg

EFI分区文件结构(仅说明3个必要文件)

(EFI分区)..................此分区必须为Fat32格式,不然UEFI固件将无法识别
|
+--EFI
  |--Microsoft
  |  +--Boot
  |     |--bootmgfw.efi...一个针对Windows的efi应用,使Boot Menu界面上的Windows Boot Manager可以工作
  |     +--BCD............启动配置文件,用户编辑启动菜单以及默认的启动顺序等
  |--Boot
      +--bootx64.efi.......一个针对UEFI的统一efi应用,可以针对所有的系统。如果是32位系统,则是boota32.ef

引导流程

                                     计算机加电
                                        |
                                      BIOS自检
                                        |
                                    UEFI固件启动
                                        |
                        根据NVRAM下的BootOrder顺序加载启动设备
                                        |
              获取对应启动设备下第一个存有正确efi应用的Fat32格式分区并加载
                                        |
                            读取efi应用信息,加载到BCD文件
                                        |
读取BCD文件下的记录以加载系统,默认Windows10系统是加载C:\Windows\System32\winload.efi应用
                                        |
                  接下来就交给系统服务了。这样子就完成了系统的启动过程

说明一下:

什么叫做根据NVRAM下的BootOrder顺序加载启动设备,这个里面有几个知识点

NVRAM(非易失性存储器) 是BIOS用于存储本计算机启动设备信息的载体,可以通过 bcdedit /enum firmware 来查看信息,参考 这个

BootOrder 顾名思义就是一个引导顺序,可以在BIOS下调节,比如先引导Windows Boot Manager还是先引导ATA HDD0这个设备

什么叫做获取对应启动设备下第一个存有正确efi应用的Fat32格式分区并加载?正常情况来说,一个硬盘分区仅有一个Fat32格式的EFI分区,并且往往是在第一个,但是当出现多了EFI分区那么UEFI固件将如何加载呢?对于首选启动已经设置为了Windows Boot Manager的情况下可以忽略,因为这个里面已经明确定义了加载哪块硬盘的哪个分区下哪个文件。当没有这个Windows Boot Manager项目而只能通过ATA HDDX下的分区查找时,经测试。会加载上可识别的拥有正确efi应用(位置: (EFI_Partition)\EFI\Boot\bootx64.efi )的第一个EFI分区,并根据efi应用的信息加载对应的BCD文件。

So,总结如下。可以没有 (EFI_Partition)\EFI\Boot\bootx64.efi ,也可以没有: (EFI_Partition)\EFI\Microsoft\Boot\bootmgfw.efi ,但是不能2个同时没有,存在 (EFI_Partition)\EFI\Boot\bootx64.efi 的情况下,可以在BIOS的Boot Menu界面选择ATA HDDX启动,存在 (EFI_Partition)\EFI\Microsoft\Boot\bootmgfw.efi 并设置正确的情况下,可以在BIOS的Boot Menu界面上选择 Windows Boot Manager启动。

说几个关于引导的命令
mountvol 用于加载分区,比如 mountvol K: /s 加载默认的EFI分区到K盘

bcdboot 用于修复efi文件,比如 bcdboot C:\Windows /l en-us 将同时修复 (EFI_Partition)\EFI\Boot\bootx64.efi 和 (EFI_Partition)\EFI\Microsoft\Boot\bootmgfw.efi 2个文件

bootrec 可用于重新创建BCD文件,比如 bootrec /rebulidbcd 会在默认的位置 (EFI_Partition)\EFI\Microsoft\Boot 重新生成识别到的系统的BCD文件

bcdedit 用于编辑BCD文件

如果安装了双系统,不小心把WIN系统的引导删除了怎么恢复:
需要有PE系统,没有可以自己制作一个,这里不展开了
进去PE系统后修复BCD,以U启通PE为例:进入安装界面,点击左下角修复计算机。依次点击:“疑难解答”,“高级选项”,“命令提示符”。进入CMD命令 接下来依次输入

diskpart
list disk //列出所有挂在磁盘
sel disk X //选中刚刚自己发现的系统所在磁盘(X自己替换成数字)
lis​​​​​​​t vol​​​​​​​ //查看磁盘里各个盘符,并确定自己的win系统所在的盘符(通常为C盘)
list par //列出上一步所选磁盘的分区,其中就有存放efi的分区,类型为系统,大小几百M
sel par x  //选择efi的分区,x为分区编号
assign letter=o  //为选择的分区分配一个盘符为o以便修复
exit //退出diskpart,不要关闭命令行框

4077bec5accc431db430a3659d709633.png
bcdboot命令进行修复
命令行使用bcdboot命令,大概但不是下面这样
这里的c:\不一定是系统盘,需要用dir命令列出盘内文件来自己判断哪个才是系统盘,dir c:\ 和 dir d:\ 等,记住系统盘是哪个。
046ffeb9e06742c19fc4d95e938e4b33.png
然后执行bcdboot命令:
最后输入

bcdboot x:\windows /s o: /f uefi /l zh-cn  //其中x为亲自判断的系统盘盘符。
#盘符x:是你自己刚刚确定的盘符,最后的/l是小写的L,不是1

会提示“已成功创建启动文件”。

注意:有的电脑会显示“尝试复制启动文件失败”,如果以上输入没有问题,那么问题在于你的x盘不对,或者说再这个命令行里符号x不代表它。
如果显示“尝试复制启动文件失败”,输入exit退出diskpart并使用dir命令判断那个是系统盘。

然后输入exit退出命令行,关机重能进入弄丢的Windows了。

终于大功告成

小结
到目前为止是windows进去了但是我最初的目的还没达到阿,就是切换双系统。其实在这个折腾的过程中我已经解决了,下面来唠唠上面说的蠢的过程:
首先第一张图的系统选择页面是由ubuntu系统设置的开机引导页面供自己选择进入哪个系统,而我当时忘记了,所以就开始准备在windows系统里面准备设置开机引导来供选择进入哪个系统,最后没有成功还把windows搞得进不去了。原理上应该是可行了,两个系统之间的切换只需修改一个系统的开机引导选择就行了,而我已经在ubuntu里面设置了(具体设置可以参考这里),至于为什么没有开机的时候进入这个选择的页面是因为,BIOS里面把windows作为最先启动的了,所以以前开机直接就进windows了,没有出现选择的页面。当我把BIOS启动优先级改成了ubuntu最先启动,这时就会出现选择系统的页面了,然后选择就好了,就这么简单。

PHP易错点

<?php

//空格会被判断为真
var_dump(!!'0'); //false
var_dump(!!' '); //true,空格会被判断为真


        var updateStatus = true
        window.addEventListener('beforeunload', function (event) {
            // 取消关闭窗口事件
            if (!updateStatus) return true
            event.preventDefault();
            // Chrome 需要返回一个空字符串
            event.returnValue = '当前数据有更新还未保存,是否要离开?';
            return '当前数据有更新还未保存,是否要离开?'
        })

操作计数器的值
在使用计数器之前,需要使用 counter-reset 属性来初始化它的值。这个属性也可用于指定计数器的初始值。

下面,我们将名为 section 的计数器初始化为默认值(0)。

counter-reset: section;

你也可以同时初始化多个计数器,并可以指定其初始值。下面,我们将名为 section 和 topic 的计数器初始化为默认值,并将 page 计数器的初始值指定为 3。

counter-reset: section page 3 topic;

在初始化之后,计数器的值就可以使用 counter-increment 来指定其为递增或递减。例如,下面声明了一个随着 h3 标签递增的 section 计数器。

h3::before {
  counter-increment: section; /* Increment the value of section counter by 1 */
}

你可以在计数器的名称后指定单次递增或递减的值(正数或负数)。

计数器的名称不可以为 none、inherit 或 initial,否则,相应的声明会被忽略。

显示计数器
计数器的值可以使用 counter() 或 counters() 函数以在 content 属性中显示。

例如,以下使用 counter() 声明的计数器会在每一个 h3 标题前面添加文本 Section :,其中的 是十进制计数的值(默认显示样式):

h3::before {
  counter-increment: section; /* Increment the value of section counter by 1 */
  content: "Section " counter(section) ": "; /* Display counter value in default style (decimal) */
}

当不需要包含父级上下文的编号,而仅需要嵌套内容的编号时,应使用 counter() 函数。例如,以下示例的每一个嵌套内容的计数都从 1 开始:

1 One
  1 Nested one
  2 Nested two
2 Two
  1 Nested one
  2 Nested two
  3 Nested three
3 Three

当需要同时包含父级上下文和嵌套内容的编号时,应使用 counters() 函数。例如,以下示例的每一个嵌套内容会包含父级编号:

1 One
  1.1 Nested one
  1.2 Nested two
2 Two
  2.1 Nested one
  2.2 Nested two
  2.3 Nested three
3 Three

counter() 函数有两种形式: counter() 和 counter(, )。生成的文本是伪元素范围内指定名称的最内层计数器的值。

counters() 函数也同样有两种形式:counters(, ) 和 counters(, , )。生成的文本由在伪元素范围内所有指定名称的计数器的值组成。这些值从最外层到最内层,使用指定的字符串()分隔。

以上两个函数均可以使用指定的 来渲染其值(默认值为 decimal)。你也可以使用 list-style-type 属性其他可选的值,或自定义样式。

基础示例和计数器嵌套示例这两个示例分别展示了 counter() 和 counters() 的使用方法。

#简单的用法, 直接使用 CSS property: list-style-type
counter(myCount); 使用阿拉伯数字 1, 2, 3 表示计数器的值
counter(myCount, trad-chinese-informal); 使用汉字 一, 二, 三 表示计数器的值

查看详细 @counter-style 的用法

反向计数器
反向计数器是一种用于递减(而非递增)的计数器。反向计数器可以通过在 counter-reset 属性中将计数器的名称使用 reversed() 函数包裹来创建。

反向计数器的默认初始值与元素的数量相同(不同于常规的默认初始值为 0 的计数器)。这使得实现从元素数量为初始值倒数到 1 的计数器变得更加容易。

例如,要创建一个名为 section 反向计数器(使用默认初始值),你只需要这样写:

counter-reset: reversed(section);

你也可以指定它的初始值。

计数器的值会随着通过 counter-increment 属性指定的负数递减。

备注: 对于非反向计数器,你也仍然可以使用 counter-increment 属性实现递减。使用反向计数器的优点在于:其默认初始值可以自动根据元素数量生成,自动应用于有序列表的 list-item 计数器也可以借此反转编号。

有序列表(list item)计数器
使用

    元素创建的有序列表,会自动应用名为 list-item 的计数器。

    和其他的计数器一样,其也是一个默认自增(+1)且初始值为 0 的计数器,对于反向计数器,则以元素数量为初始值,且默认自减(-1)。与自定义的计数器不同,list-item 是根据其是否为反向计数器而自动自增或自减的。

    可以通过 CSS 修改 list-item 计数器应用在有序列表上的默认行为。例如,你可以改变默认初始值,或使用 counter-increment 改变递增或递减的方式。

    示例
    基础示例
    以下示例会在每一个标题前添加一个“Section [the value of the counter]:”字符串。

    body {
      counter-reset: section; /* Set a counter named 'section', and its initial value is 0. */
    }
    
    h3::before {
      counter-increment: section; /* Increment the value of section counter by 1 */
      content: "Section " counter(section) ": "; /* Display the word 'Section ', the value of
                                                      section counter, and a colon before the content
                                                      of each h3 */
    }
    <h3>Introduction</h3>
    <h3>Body</h3>
    <h3>Conclusion</h3>

    基础示例:反向计数器
    以下示例与上一个类似,区别在于其使用了反向计数器。如果你的浏览器支持 reversed() 函数,其结果就会类似于这样:
    reversed counter

    body {
      counter-reset: reversed(
        section
      ); /* Set a counter named 'section', and its initial value is 0. */
    }
    
    h3::before {
      counter-increment: section -1; /* Decrement the value of section counter by 1 */
      content: "Section " counter(section) ": "; /* Display the word 'Section ', the value of
                                                     section counter, and a colon before the content
                                                     of each h3 */
    }
    <h3>Introduction</h3>
    <h3>Body</h3>
    <h3>Conclusion</h3>

    一个更加复杂的示例
    有时我们不需要让计数器在每一次递增时都显示其值,以下示例仅在链接的内容为空时将其替换为由计数器生成的值。

    :root {
      counter-reset: link;
    }
    
    a[href] {
      counter-increment: link;
    }
    
    a[href]:empty::after {
      content: "[" counter(link) "]";
    }
    <p>See <a href="https://www.mozilla.org/"></a></p>
    <p>Do not forget to <a href="contact-me.html">leave a message</a>!</p>
    <p>See also <a href="https://developer.mozilla.org/"></a></p>

    计数器嵌套示例
    CSS 计数器对创建目录(多级有序列表)特别有用,因为其会在子元素中自动创建一个 CSS 计数器的实例。使用 counters() 函数,可以在不同级别的嵌套计数器之间可以插入分隔字符串。

    ol {
      counter-reset: section; /* Creates a new instance of the
                                                section counter with each ol
                                                element */
      list-style-type: none;
    }
    
    li::before {
      counter-increment: section; /* Increments only this instance
                                                of the section counter */
      content: counters(section, ".") " "; /* Combines the values of all instances
                                                of the section counter, separated
                                                by a period */
    }
    <ol>
      <li>item</li>          <!-- 1     -->
      <li>item               <!-- 2     -->
        <ol>
          <li>item</li>      <!-- 2.1   -->
          <li>item</li>      <!-- 2.2   -->
          <li>item           <!-- 2.3   -->
            <ol>
              <li>item</li>  <!-- 2.3.1 -->
              <li>item</li>  <!-- 2.3.2 -->
            </ol>
            <ol>
              <li>item</li>  <!-- 2.3.1 -->
              <li>item</li>  <!-- 2.3.2 -->
              <li>item</li>  <!-- 2.3.3 -->
            </ol>
          </li>
          <li>item</li>      <!-- 2.4   -->
        </ol>
      </li>
      <li>item</li>          <!-- 3     -->
      <li>item</li>          <!-- 4     -->
    </ol>
    <ol>
      <li>item</li>          <!-- 1     -->
      <li>item</li>          <!-- 2     -->
    </ol>