2023年3月

介绍

在复制大量文件的情况下,robocopy比xcopy更快。这是因为robocopy使用多线程技术和其他优化方式来提高复制速度和效率。此外,robocopy还具有断点续传和其他有用的功能,可以让您更好地控制文件复制过程。

相比之下,xcopy是一个更简单的工具,没有像robocopy那样的高级功能和优化技术。xcopy可以在简单的情况下提供良好的效果,但是对于大规模复制操作,robocopy会更加适用。

综上所述,如果您需要复制大量文件或要复制文件夹的子文件夹和文件,请使用robocopy。如果您需要复制一些较小的文件或需要进行基本的复制操作,则使用xcopy可能更加简单和方便。

命令

可以使用以下命令将一个文件夹中的所有内容复制到另一个地方:

robocopy <源文件夹路径> <目标文件夹路径> /E

其中,<源文件夹路径>是需要复制的文件夹路径,<目标文件夹路径>是复制后文件夹的路径。/E参数表示复制所有子文件夹和文件。如果目标路径不存在,robocopy会自动创建该路径。

例如,如果要将D:\Documents文件夹中的所有文件和文件夹复制到E:\Backup文件夹中,可以使用以下命令:

robocopy D:\Documents E:\Backup /E

执行命令后,Robocopy会开始复制所有的文件和文件夹,并显示复制进度。

参数区别

选项是否复制时间戳是否覆盖已有文件描述
/E复制源目录及其子目录中所有的非空目录和文件到目标目录中,同时保留源目录结构。这个选项还会复制文件和目录的属性和时间戳。如果指定了/R/W选项,则在文件复制过程中出现错误时进行重试。
/COPYALL复制源目录及其子目录中所有的非空目录和文件到目标目录中,同时保留源目录结构。这个选项会复制文件和目录的属性、时间戳和权限信息。如果指定了/R/W选项,则在文件复制过程中出现错误时进行重试。
/MIR复制源目录及其子目录中所有的非空目录和文件到目标目录中,并在必要时删除目标目录中存在但源目录中不存在的文件和目录,从而将目标目录与源目录完全同步。这个选项会复制文件和目录的属性和时间戳,如果需要,可以覆盖目标目录中已有的同名文件。如果指定了/R/W选项,则在文件复制过程中出现错误时进行重试。

  1. 打开注册表编辑器:按下Win+R键,输入regedit,回车。
  2. 找到服务的注册表项:在注册表编辑器中,依次展开HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services。
  3. 找到需要修改的服务:在Services下找到需要修改的服务的注册表项。
  4. 修改服务名称:在服务的注册表项中,找到DisplayName键,双击打开,修改键值数据为新的服务名称。
  5. 修改服务描述:在服务的注册表项中,找到Description键,双击打开,修改键值数据为新的服务描述。
  6. 保存修改:修改完成后,点击注册表编辑器的“文件”菜单,选择“退出”保存修改。
  7. 重启计算机:修改服务名称和描述后,需要重启计算机才能生效。

简单版:

export function HandleUrlParam(url: string, param?: Record<string, any> | null): string {
  if (param) {
    const paramArray = [] as string[];
    const keys = Object.keys(param);
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      const value = param[key]?.toString() ?? "";
      paramArray.push(`${key}=${value}`);
    }
    if (paramArray.length > 0) {
      let paramText = paramArray.join("&");

      if (url.indexOf("?") >= 0) {
        url = `${url}${paramText}`;
      } else {
        url = `${url}?${paramText}`;
      }
    }
  }
  return url;
}

复杂版:
https://github.com/Leonardozn/json-qs-converter

Plus版:

export function HandleUrlParamPlus(url: string, param?: Record<string, any> | null): string {
  if (param) {
    let paramArray = GetUrlParamList('',param);

    if (paramArray.length > 0) {
      let paramText = paramArray.join("&");

      if (url.indexOf("?") >= 0) {
        url = `${url}${paramText}`;
      } else {
        url = `${url}?${paramText}`;
      }
    }
  }
  return url;
}

function GetUrlParamList(parentKey: string, param?: Record<string, any> | null) {
  let paramArray = [] as string[];
  if (param) {
    const keys = Object.keys(param);
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      const value = param[key] ?? "";
      if (!_.isObject(value)) {
        if (parentKey) {
          paramArray.push(`${parentKey}.${key}=${value}`);
        } else {
          paramArray.push(`${key}=${value}`);
        }
      } else {
        let childParamList = GetUrlParamList(key, value)
        if (parentKey) {
          for (let i = 0; i < childParamList.length; i++) {
            childParamList[i] = `${parentKey}.${childParamList[i]}`
          }
        }
        paramArray = _.concat(paramArray, childParamList)
      }
    }
  }
  return paramArray
}

# 判断当前用户是否为管理员
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

# 如果当前用户不是管理员,则重新以管理员身份启动 PowerShell
if (-not $isAdmin) {
    # 获取当前脚本的路径
    $scriptPath = $MyInvocation.MyCommand.Path
    Start-Process PowerShell -Verb RunAs "-Command `"cd '$pwd'; & '$scriptPath';`""
    exit
}

# 在这里编写需要以管理员身份运行的代码

main.ts

import '~/util/openInEditorConfig'

openInEditorConfig.ts

import { warpperEnv } from "~/util/build";

let envSettings = warpperEnv()
if (process.env.NODE_ENV === 'development') {
    let host = window.location.host
    window.VUE_DEVTOOLS_CONFIG = {
        openInEditorHost: `http://${host}/${envSettings.VITE_PUBLIC_PATH}/`
    }
}

src\util\build\index.ts

/**
 * 默认环境配置, 具体配置在 .env.xxx文件中修改
 */
const settings: EnvSettings = {
  VITE_PORT: 5003,
  VITE_PUBLIC_PATH: "/projexec",
  VITE_ONLY_OFFICE_HOST: 'http://192.168.101.88:1080',
  VITE_DOCUMENT_SERVER_HOST: 'http://localhost:9540',
  VITE_DOCUMENT_SERVER_VUE_HOST: 'http://localhost:8848',
  VITE_FILE_READY_ADDRESS: "http://xxxxxxxxxxxxx.aliyuncs.com/"
};

/**
 * 包装环境配置,用于将字符串格式化为boolean或number类型
 * @param envConf 环境配置
 * @returns 
 */
const warpperEnv = (envConf?: Record<string, any>): EnvSettings => {
  let ret = { ...settings, };

  if (!envConf) envConf = loadEnv()
  for (const envName of Object.keys(envConf)) {
    const envValue = envConf[envName]
    if (!envValue || typeof (envValue) !== 'string') {
      continue
    }

    let value: any = envValue.replace(/\\n/g, "\n");

    if (value === "true") {
      value = true
    } else if (value === "false") {
      value = false;
    }

    if (envName === "VITE_PORT") {
      value = Number(value);
    }

    ret[envName] = value;
  }
  return ret;
};


/**
 * 加载环境变量 import.meta.env
 * @returns 
 */
const loadEnv = () => {
  /**
   * development 开发环境从import.meta.env获取环境变量
   * 非development 开发环境则从config.js获取环境变量
   */

  // 在生产环境中,这些环境变量会在构建时被静态替换,因此,在引用它们时请使用完全静态的字符串。动态的 key 将无法生效。例如,动态 key 取值 import.meta.env[key] 是无效的。
  // https://cn.vitejs.dev/guide/env-and-mode.html#env-variables
  const env = import.meta.env;

  if (env.MODE === 'development') {
    return env;
  }

  Object.assign(env, window.appConfig)

  return env;
};

export { settings, warpperEnv };

public\config.js-test

window.appConfig = {
  // VITE_PORT:'80',
  VITE_PUBLIC_PATH:'projexec',
  VITE_ONLY_OFFICE_HOST:'http://192.168.101.88:1080',
  VITE_DOCUMENT_SERVER_HOST:'http://192.168.101.80:55000/document',
  VITE_DOCUMENT_SERVER_VUE_HOST:'http://192.168.101.80:55000/document',
  VITE_FILE_READY_ADDRESS: "http://xxxxxxxxxxxxxx.aliyuncs.com/"
}