備忘録

備忘録

エクスプローラのナビゲーションウィンドウからCreative Cloud Filesを削除する方法

Ⅰ. はじめに

タイトルの通り「エクスプローラのナビゲーションウィンドウから Creative Cloud Files Personal Account user@example.com を削除する方法」です。

Ⅱ. 手順

1. 以下コマンドを実行する

reg add "HKEY_CLASSES_ROOT\CLSID\{0E270DAA-1BE6-48F2-AC49-090D8DE75392}" /v "System.IsPinnedToNameSpaceTree" /t REG_DWORD /d 0 /f

以上

実行結果

ナビゲーションウィンドウから削除された

Rust 基本文法メモ

fn say_hello(name: String) {
  println!("hello {name} !!!");
}

fn sum(a: i32, b: i32) -> i32 {
  return a + b;
}

fn main() {
  println!("Hello, world!");
  println!("aaa {}", "bbb");

  let mut a: i32 = 1;
  println!("a is :{}", a);
  a = 2;
  println!("a is :{}", a);

  let a: &str = "aaa";

  let a1: i32 = 1;
  let a2: u32 = 1;
  let a3: f64 = 1.0;
  let a4: bool = true;

  // cast
  let floatValue = 1 as f64;

  // tuple
  let tuple1 = (1,true, 2.0);
  let tuple2 = (1,true, 2.0);

  println!("{:?}", tuple1); // 全ての値
  println!("{:?}", tuple1.0); // インデックスで要素を指定する
  println!("{}", tuple1 == tuple2); // 比較

  // array
  let array1: [i32; 3] = [1,2,3]; // 1,2,3
  let array2: [i32; 100] = [0; 100]; // 0, 0, 0, .... 0

  println!("{:?}", array1);
  println!("{}", array1[0]);

  // Vector
  let vector1: Vec<i32> = vec![1,2,3];// 1,2,3
  let vector2: Vec<i32> = vec![0; 100]; // 0, 0, 0, .... 0
  let mut vector3 :Vec<i32> = Vec::new();
  vector3.push(1);
  vector3.push(2);
  vector3.push(3);
  println!("{vector3:?}");

  // LINQ
  // https://microsoft.github.io/rust-for-dotnet-devs/latest/linq/index.html
  let results = array1
      .iter()
      .filter(|x| x >= &&2)
      .collect::<Vec<&i32>>();

  println!("{results:?}");

  // char
  let c1: char = 'a';
  let c2: char = '😂';
  println!("{c1}, {c2}");

  // String
  let string1: String = String::from("abc");
  let mut string2: String = "def".to_string();
  string2 = string2 + " ghi";

  println!("{string2}");

  let string3 = format!("{string1}{string2}!!!");
  println!("{string3}");

  // Function
  say_hello("tanaka".to_string());
  println!("{}", sum(1, 2));

  // if
  if 1 > 0 && (true || false) {
      println!("aaa");
  } else if 1 > 0 {
      println!("bbb");
  } else {
      println!("ccc");
  }

  let result = if true { true } else {false};
  println!("{}", result);

  // Switch
  let x: i32 = 3;
  match x {
      0 => println!("x is 0"),
      1 | 2 => {
      println!("x is 1 or 2");
      println!("Multi line");
      },
      _ => println!("x is unknown")
  }

  let result = match x { 0 => 0, 1=>1, _=> 999};
  println!("{}", result);

  // While true
  let mut x: i32 = 0;
  loop {
      x += 1;
      if x > 10 {
      break;
      }

      if x %2 == 0 {
      continue;
      }

      println!("hello");
  }

  // while
  let mut x: i32 = 0;
  while x < 10 {
      println!("while x: {}", x);
      x += 1;
  }

  // for
  for x in [1,2,3] {
      println!("for x: {}", x);
  }
}
// 関数引数の参照渡し
fn concat (a: &String, b: &String) -> String{
  return format!("{a}{b}");
}

fn main(){
  let s1: String = "hello".to_string();
  let s2: String = "world".to_string();
  let s3: String = concat(&s1, &s2);

  println!("{s1} {s2} {s3}");
}

cpprestsdkを利用してWebサーバを構築する方法

Ⅰ. はじめに

タイトルの通り「cpprestsdkを利用してWebサーバを構築する方法」です。

Ⅱ. サンプルプログラム

#include <Windows.h>
#include <iostream>
#include <format>

#include <cpprest/http_listener.h>

int main()
{
  SetConsoleOutputCP(CP_UTF8);

  auto address = utility::conversions::to_string_t("http://127.0.0.1:80");
  web::http::experimental::listener::http_listener listener(address);

  listener.support(web::http::methods::GET, [](web::http::http_request request)
    {
      auto parameters = web::uri::split_query(request.request_uri().query());
      auto param1 = utility::conversions::utf16_to_utf8(parameters.at(L"param1"));
      auto param2 = utility::conversions::utf16_to_utf8(parameters.at(L"param2"));

      std::cout << param1 << std::endl;
      std::cout << param2 << std::endl;

      request.reply(web::http::status_codes::OK, "OK");
    });

  listener.support(web::http::methods::POST, [](web::http::http_request request)
    {
      auto json = request.extract_json().get();
      auto name = utility::conversions::utf16_to_utf8(json[L"name"].as_string());

      std::cout << name << std::endl;

      auto str = std::format("Hello {0}", name);
      request.reply(web::http::status_codes::OK, str);
    });

  listener.open().wait();

  getchar();
  listener.close();
  return 0;
}

実行結果

GET
POST

WebRTC (WHIP)を利用して動画配信をする方法

Ⅰ. はじめに

タイトルの通り「WebRTC (WHIP)を利用して動画配信をする方法」です。

この記事では例としてgo2rtcを利用します。

料金 名称
有料 Nimble Streamer
有料 Cloudflare Stream
有料 Dolby.io
有料 RED5
無料 go2rtc
無料 broadcast-box
無料 livekit

Ⅱ. 手順

1. OBS 30.0 以降をインストールする

https://github.com/obsproject/obs-studio/releases/

2. go2rtcをダウンロードする

https://github.com/AlexxIT/go2rtc/releases

3. go2rtcを実行する
> go2rtc.exe
15:55:07.286 INF go2rtc version 1.8.1 windows/amd64
15:55:07.303 INF [api] listen addr=0.0.0.0:1984
15:55:07.304 INF [rtsp] listen addr=0.0.0.0:8554
15:55:07.304 INF [webrtc] listen addr=0.0.0.0:8555/tcp
4. 以下URLにアクセスする

http://127.0.0.1:1984

5. Temporary streamを追加する


6. OBSで配信を開始する
http://127.0.0.1:1984/api/webrtc?dst=test001


7. 配信画面を開く


実行結果

100ms 前後の遅延で配信出来ている

LinuxでGPUをパススルーして仮想マシンで利用する方法

Ⅰ. はじめに

タイトルの通り「LinuxでGPUをパススルーして仮想マシンで利用する方法」です。

Ⅱ. 環境

ホスト Ubuntu 22.04.3 LTS
Linux Kernel 6.2.0-34-generic
ゲスト Windows 11 Pro 21H2
CPU AMD Ryzen 9 5900X BOX
GPU GeForce RTX 4070 Ti
マザーボード ASUS TUF GAMING B550-PLUS

Ⅲ. 手順

1. BIOS設定を変更する

CPUがAMDの場合以下3つを有効にする
1. IOMMU
2. NX mode
3. SVM mode

CPUがIntelの場合以下2つを有効にする
1. VT-d
2. VT-x
※片方しか存在しない場合は片方だけ有効にする

2. UEFIを利用してUbuntuをインストールする
3. GRUBを編集する
$ sudo vim /etc/default/grub

# CPUがAMD製の場合
GRUB_CMDLINE_LINUX_DEFAULT="amd_iommu=on quiet splash"

# CPUがIntel製の場合
GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on quiet splash"
4. GRUBの設定を反映する
sudo update-grub
5. 再起動する
sudo reboot
6. IOMMUが有効になったか確認する
$ sudo dmesg | grep -i -e DMAR -e IOMMU
[    0.425579] iommu: Default domain type: Passthrough (set via kernel command line)
7. 仮想化ソフトウェアをインストールする
sudo apt install qemu-system-x86 libvirt-clients libvirt-daemon-system libvirt-daemon-config-network bridge-utils virt-manager ovmf  
8. ユーザのグループにkvm, libvirt を追加する
sudo usermod -a -G kvm,libvirt $(whoami)

# 確認
sudo groups $(whoami)
9. QEMUの設定を変更する
$ sudo vim /etc/libvirt/qemu.conf

user = "ENTER_YOUR_USERNAME"
group = "ENTER_YOUR_USERNAME"
10. libvirtの設定を変更する
$ sudo vim /etc/libvirt/libvirtd.conf

unix_sock_group = "libvirt"
unix_sock_rw_perms = "0770"

# 以下2行はファイル末尾に追記
log_filters="3:qemu 1:libvirt"
log_outputs="2:file:/var/log/libvirt/libvirtd.log"
11. libvirtdを実行する
sudo systemctl enable libvirtd
sudo systemctl restart libvirtd
12. libvirtネットワークを自動起動する
sudo virsh net-autostart default
13. 仮想化設定確認
virt-host-validate
14. virtioのWindows用ドライバ(ISOファイル)をダウンロードする

https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md

15. virt-managerを利用して仮想マシンを設定する

名前は必ず「win11」を指定する。※参考


16. Windowsをインストールする


17. nvflashまたはamdvbflashをダウンロードする
18. nvflashまたはamdvbflashを実行する
# デフォルトターゲットを変更する
sudo systemctl set-default multi-user

# ディスプレイマネージャを終了する
sudo systemctl stop gdm3

# Ctrl + Alt + F2でCUIを表示する

# NVFlashを実行する(rmmodコマンド実行を要求された場合は従う)
./nvflash --save vbios.rom

# デフォルトターゲットを変更する
sudo systemctl set-default graphical

# ディスプレイマネージャを起動する
sudo systemctl restart gdm3
19. vbios.romを編集する

0x0 〜 0x93FF まですべて削除する
(55 AA 7E EB 4B 37 34 30 30 E9 4C 19 77 CC 56 49 44 45 4F より前を全て削除する)


20. vbios.romを配置する
sudo mkdir /usr/share/vgabios
sudo cp vbios.rom /usr/share/vgabios/vbios.rom
cd /usr/share/vgabios
sudo chmod -R 644 vbios.rom
sudo chown ENTER_YOUR_USERNAME:ENTER_YOUR_USERNAME vbios.rom
21. スクリプトをcloneする
git clone https://github.com/kagasu/single-gpu-passthrough
cd single-gpu-passthrough
sudo chmod +x install_hooks.sh
sudo ./install_hooks.sh
22. 仮想マシンの設定を変更する


以下4つの要素を削除する

<graphics type="spice" autoport="yes">
  <listen type="address"/>
  <gl enable="no"/>
</graphics>
<audio id="1" type="none"/>
<video>
  <model type="bochs" vram="16384" heads="1" primary="yes"/>
  <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</video>
<channel type="spicevmc">
  <target type="virtio" name="com.redhat.spice.0"/>
  <address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
23. パススルーするPCIデバイス(GPU)を指定する

画像の場合は2個指定する(まとめて指定できないので1個ずつ指定する)

24. 仮想マシンの設定を変更する
<rom file='/usr/share/vgabios/vbios.rom'/>


25. パススルーするUSBデバイス(マウス、キーボードなど)を指定する


26. 起動順序を変更する


27. NICのリンク状態をアクティブにする


28. 実行する


29. virtioのドライバをインストールする


実行結果



FAQ

Q. ログの出力先は?

A. 以下ファイルです

/var/log/libvirt/libvirtd.log
/var/log/libvirt/qemu/win11.log
Q. 以下ログが出力されています。問題ありますか?
$ sudo cat /var/log/libvirt/libvirtd.log | grep --text error
error : virNetSocketReadWire:1793 : End of file while reading data: 入力/出力エラーです

A. 問題ないと思われます。
筆者の環境でも同様のエラーが出力されていますが問題なくゲストが動作しています。

Q. プチフリ(Stutter)が発生します。解決方法は?

A. 筆者の環境では以下3点の設定を行う事で軽減しました。
完全に無くすことはできませんでした。まれにプチフリが発生します。競技レベルでのゲームプレイは難しいです。

1. Huge Pagesを設定する
https://qiita.com/disksystem/items/773cbcb4fd9b0bd2e1ee

2. XMLを編集する

<domain>
  <cpu mode='host-passthrough' check='none'>
    <topology sockets='1' cores='n' threads='m'/>
+   <!-- AMD製CPUでSMTを有効にする -->
+   <feature policy='require' name='topoext'/>
+   <!-- ホスト側のCPUキャッシュを仮想CPUにパススルーする -->
+   <cache mode='passthrough'/>
  </cpu>

+  <iothreads>2</iothreads>
+  <cputune>
+    <vcpupin vcpu='0' cpuset='1'/>
+    <vcpupin vcpu='1' cpuset='2'/>
+    <vcpupin vcpu='2' cpuset='3'/>
+    <vcpupin vcpu='3' cpuset='4'/>
+    <vcpupin vcpu='4' cpuset='5'/>
+    <vcpupin vcpu='5' cpuset='6'/>
+    <vcpupin vcpu='6' cpuset='7'/>
+    <vcpupin vcpu='7' cpuset='8'/>
+    <vcpupin vcpu='8' cpuset='9'/>
+    <vcpupin vcpu='9' cpuset='10'/>
+    <vcpupin vcpu='10' cpuset='11'/>
+    <vcpupin vcpu='11' cpuset='12'/>
+    <emulatorpin cpuset='13,14'/>
+    <iothreadpin iothread='1' cpuset='13'/>
+    <iothreadpin iothread='2' cpuset='14'/>
+  </cputune>

+  <memoryBacking>
+    <hugepages/>
+  </memoryBacking>

-  <memballoon model="virtio">
-    <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
-  </memballoon>
+  <memballoon model="none"/>
</domain>

3. ゲスト側Windowsで「メモリ内のページのロック」に任意のユーザを設定する
この設定でHuge Pages(WindowsではLarge Pageと呼ぶ)に対応できる