結果だけでなく過程も見てください

日々の奮闘を綴る日記です。

C# DirectShowで動画を再生する方法

当方Windows 10でVisual Studio Community 2019を使用しています。

参照の追加

C#のプロジェクトを右クリック→追加→COM参照を選択します。
f:id:taiyakisun:20210617180605p:plain

[ActiveMovie control type library]にチェックを入れ、OKを押します。
f:id:taiyakisun:20210617180821p:plain

もしActiveMovie control type libraryが存在しない場合などは次の方法でdllを追加してください。

[参照]→[参照]ボタン→C:\Windows\System32\quartz.dllを選択して、③が追加されたことを確認します。
f:id:taiyakisun:20210617181041p:plain

必要なパッケージ

using QuartzTypeLib;

コード

C#でフォームアプリケーションでプロジェクトを作成します。

GUI

デザイナーで以下のコンポーネントを追加します。
・Panel (名前:panel1)
・Button (名前:button1)
ここでは、ボタンを押すとpanelに動画が再生されるようにコードを書きます。

C#のコード

private FilgraphManager objFilterGraph = null;
private IBasicAudio objBasicAudio = null;
private IVideoWindow objVideoWindow = null;
private IMediaEvent objMediaEvent = null;
private IMediaEventEx objMediaEventEx = null;
private IMediaPosition objMediaPosition = null;
private IMediaControl objMediaControl = null;

private const int WM_APP = 0x8000;
private const int WM_GRAPHNOTIFY = WM_APP + 1;
private const int EC_COMPLETE = 0x01;
private const int WS_CHILD = 0x40000000;
private const int WS_CLIPCHILDREN = 0x2000000;

enum MediaStatus { None, Stopped, Paused, Running };
private MediaStatus currentStatus = MediaStatus.None;

private void button1_Click(object sender, EventArgs e)
{
    objFilterGraph = new FilgraphManager();

    // ここに固定で再生したい動画ファイルのフルパスを書く
    objFilterGraph.RenderFile(@"C:\temp\midori.avi");

    objBasicAudio = objFilterGraph as IBasicAudio;
    objBasicAudio.Volume = -1000;    // 音量を少し下げておく

    try
    {
        objVideoWindow = objFilterGraph as IVideoWindow;
        objVideoWindow.Owner = (int)panel1.Handle;
        objVideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;        
        objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left,
                                            panel1.ClientRectangle.Top,
                                            panel1.ClientRectangle.Width,
                                            panel1.ClientRectangle.Height);
    }
    catch (Exception ex)
    {
        objVideoWindow = null;
    }

    objMediaEvent = objFilterGraph as IMediaEvent;

    // メッセージの傍受 DirectShowを親ウィンドウに送信します
    objMediaEventEx = objFilterGraph as IMediaEventEx;
    objMediaEventEx.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, 0);

    // ビデオまたはオーディオトラックを開始および停止する
    objMediaControl = objFilterGraph as IMediaControl;

    // 再生開始
    objMediaControl.Run();
    currentStatus = MediaStatus.Running;
}

フォーム終了時などに実行する解放処理は以下の通りです。

if (objMediaControl != null)
{
    objMediaControl.Stop();
}

currentStatus = MediaStatus.Stopped;

if (objMediaEventEx != null)
{
    objMediaEventEx.SetNotifyWindow(0, 0, 0);
}

if (objVideoWindow != null)
{
    objVideoWindow.Visible = 0;
    objVideoWindow.Owner = 0;
}

if (objMediaControl != null) objMediaControl = null;
if (objMediaPosition != null) objMediaPosition = null;
if (objMediaEventEx != null) objMediaEventEx = null;
if (objMediaEvent != null) objMediaEvent = null;
if (objVideoWindow != null) objVideoWindow = null;
if (objBasicAudio != null) objBasicAudio = null;
if (objFilterGraph != null) objFilterGraph = null;

一時停止する場合は以下のコードを実行します。

objMediaControl.Pause();

一時停止を再開する場合は以下のコードを実行します。

objMediaControl.Run();

動画を末尾まで再生したことを検知して止めるためのコードは以下の通りです。
メッセージプロシージャをオーバーライドして特定のメッセージだけ処理を追加する形にしています。

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_GRAPHNOTIFY)
    {
        int lEventCode;
        int lParam1, lParam2;

        while (true)
        {
            try
            {
                objMediaEventEx.GetEvent(out lEventCode,
                    out lParam1,
                    out lParam2,
                    0);

                objMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);

                if (lEventCode == EC_COMPLETE)
                {
                    objMediaControl.Stop();
                    objMediaPosition.CurrentPosition = 0;
                    currentStatus = MediaStatus.Stopped;
                }
            }
            catch (Exception)
            {
                break;
            }
        }
    }

    base.WndProc(ref m);
}

トラックバー(シークバー)の設置

どうせなのでトラックバーも設置してしまいましょう。
トラックバー設置により、再生位置をクリックしたりドラッグしたりして、好きな位置に飛べるようにします。

GUIの設置

デザイナ画面でTrackbarを設置します。変数名はデフォルトのtrackBar1とします。

コード

button1_Click関数で再生を開始するときにトラックバーの設定コードを追加します。
まずトラックバーの取りうる値をMinimumとMaximumに設定します。
ここでは動画の秒数をMaximumに設定します。

private void button8_Click(object sender, EventArgs e)
{
    :
    // 再生開始
    objMediaControl.Run();
    currentStatus = MediaStatus.Running;

    // トラックバーの設定
    this.trackBar1.Minimum = 0;
    this.trackBar1.Maximum = (int)objMediaPosition.Duration;
    this.trackBar1.Value = 0;
    this.trackBar1.TickFrequency = 1;

再生中にトラックバーを更新する関数を作成します。

private void updateTrackBar()
{
    if (this.currentStatus == MediaStatus.Running && this.objMediaPosition != null)
    {
        this.trackBar1.Value = (int)objMediaPosition.CurrentPosition;
    }
    else
    {
        this.trackBar1.Minimum = 0;
        this.trackBar1.Maximum = 0;
        this.trackBar1.Value = 0;
    }
}

上述したトラックバー更新関数をコールするコードを追加します。
まずは動画の再生が完了したときにトラックバーを0に戻すため、WndProc関数にコードを追加します。

protected override void WndProc(ref Message m)
{
    :
    if (lEventCode == EC_COMPLETE)
    {
        :
        updateTrackBar();
    }
}

次に、1秒に1度トラックバーを更新するためにタイマーを設定し、そこからupdateTrackBar関数を呼び出します。

private void Form1_Load(object sender, EventArgs e)
{
    :
    // トラックバーの更新
    Timer trackbar_timer = new Timer();
    trackbar_timer.Interval = 1000;
    trackbar_timer.Enabled = true;
    trackbar_timer.Start();
    trackbar_timer.Tick += (sender, e) =>
    {
        if (this.currentStatus == MediaStatus.Running)
        {
            this.updateTrackBar();
        }
    };

続いて、マウスクリックとマウスの移動でシークバーを更新するようにします。
MouseDownとMouseMoveイベントハンドラを作成してください。

MouseDownについては、クリックされた場所とトラックバーの幅から比率を計算して、その場所に再生位置を設定するだけです。

private void trackBar1_MouseDown(object sender, MouseEventArgs e)
{
    if (this.currentStatus == MediaStatus.Running && this.objMediaPosition != null)
    {
        if (e.Button == MouseButtons.Left)
        {
            double pos = ((double)e.X / this.trackBar1.Width) * (this.trackBar1.Maximum - this.trackBar1.Minimum);

            // トラックバー
            this.trackBar1.Value = (int)(pos);

            // 動画再生位置
            this.objMediaPosition.CurrentPosition = pos;
        }
    }
}

MouseMoveについては、基本的にMouseDownと同じですが、範囲外にマウスをドラッグされた場合の対応コードを追加したものとなります。

private void trackBar1_MouseMove(object sender, MouseEventArgs e)
{
    if (this.currentStatus == MediaStatus.Running && this.objMediaPosition != null)
    {
        if (e.Button == MouseButtons.Left)
        {
            double pos = ((double)e.X / this.trackBar1.Width) * (this.trackBar1.Maximum - this.trackBar1.Minimum);

            try
            {
                if ((int)(pos) >= this.trackBar1.Minimum && (int)pos <= this.trackBar1.Maximum)
                {
                    // トラックバー
                    this.trackBar1.Value = (int)(pos);

                    // 動画再生位置
                    this.objMediaPosition.CurrentPosition = pos;
                }
            }
            catch(ArgumentException)
            {
                // 位置を超えて設定してしまった場合は例外が飛ぶが無視する
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message, "error");
            }
        }
    }
}

C#でデスクトップのアイコン情報を取得したり、位置を変更したりする方法

これによりアイコン位置を記憶して復元するなどの操作をすることができます。
工夫次第ではアイコンの自動整理なんかもできそうです。

エラー処理をいれていないので適宜実装お願いします。



GUI構成

サンプルとしてフォームアプリケーションで、ボタン「button1」とリストボックス「listBox1」を配置します。
button1を押すことで取得したアイコンの情報をlistBox1に表示します。

なお、使うかどうかわからないのですがアイコン情報をすべて取得している箇所があります。
ここはご参考で(DEBUG:と書いている箇所)



デスクトップのアイコン情報の取得

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
enum WindowMessage
{
	WM_KEYDOWN = 0x0100,
}

public const uint PROCESS_VM_OPERATION = 0x8;
public const uint PROCESS_VM_READ = 0x10;
public const uint PROCESS_VM_WRITE = 0x20;
public const uint MEM_RESERVE = 0x2000;
public const uint MEM_COMMIT = 0x1000;
public const uint PAGE_READWRITE = 0x4;
public const int LVM_GETITEM = 0x1005;
public const int LVM_GETITEMPOSITION = 0x1010;
public const int LVM_SETITEMPOSITION = 0x100F;
public const uint MEM_RELEASE = 0x8000;

public const uint LVM_FIRST = 0x1000;
public const uint LVM_GETITEMCOUNT = LVM_FIRST + 4;
public const uint LVM_GETITEMW = LVM_FIRST + 75;

public const int LVIF_TEXT = 0x0001;

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string strclassName, string strWindowName);

[DllImport("user32", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint wMsg, int wParam, int lParam);

[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);

[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);

[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);

[DllImport("kernel32.dll")]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);

[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);

// アイコンアイテムの情報を所持する構造体
// 構造体の情報は→を参照 https://docs.microsoft.com/ja-jp/windows/win32/api/commctrl/ns-commctrl-lvitema
public struct LVITEM
{
	public int mask;
	public int iItem;
	public int iSubItem;
	public int state;
	public int stateMask;
	public IntPtr pszText;
	public int cchTextMax;
	public int iImage;
	public IntPtr lParam;
	public int iIndent;
	public int iGroupId;
	public int cColumns;
	public IntPtr puColumns;
	public IntPtr piColFmt;
	public int iGroup;
}

private void button1_Click(object sender, EventArgs e)
{
	GetIconPosition();
}

public static int MakeLParam(int wLow, int wHigh)
{
	return (((short)wHigh << 16) | (wLow & 0xffff));
}

private void GetIconPosition()
{
	// デスクトップのウィンドウハンドルを取得する
	IntPtr hWndDesktop; 
	hWndDesktop = FindWindow("Progman", "Program Manager");
	hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SHELLDLL_DefView", null);
	hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SysListView32", null);

        if (hWndDesktop == IntPtr.Zero)
        {
            // 壁紙を変更した場合等Program Manager→SHELLDLL_DefView→SysListView32ではなく
            // WorkerW→SHELLDLL_DefView→SysListView32になることがあるので、両方試す。
            // WorkerWは複数あるのでループして目的の物が見つかるまで探す。
            IntPtr hWorkerW = IntPtr.Zero;
            IntPtr hShellViewWin = IntPtr.Zero;

            do
            {
                hWorkerW = FindWindowEx(IntPtr.Zero, hWorkerW, "WorkerW", null);
                hShellViewWin = FindWindowEx(hWorkerW, IntPtr.Zero, "SHELLDLL_DefView", null);
            } while (hShellViewWin == IntPtr.Zero && hWorkerW != IntPtr.Zero);

            hWndDesktop = FindWindowEx(hShellViewWin, IntPtr.Zero, "SysListView32", null);
        }

	if (hWndDesktop == IntPtr.Zero)
	{
		MessageBox.Show("Desktop hwnd could not be retrieved.", "Error");
		return;
	}

	// アイコンの数を取得
	int iconCount = SendMessage(hWndDesktop, LVM_GETITEMCOUNT, 0, 0);

	// デスクトップ(explorer.exe)のプロセスIDを取得する
	uint dwProcessId;
	GetWindowThreadProcessId(hWndDesktop, out dwProcessId);

	// 取得したプロセスIDをオープンする
	IntPtr hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessId);
	if (hProcess == null)
        {
		MessageBox.Show("Desktop process could not be retrieved.", "Error");
		return;
        }

	// hProcessに関連するメモリーを確保する
	IntPtr pProcInfo = VirtualAllocEx(hProcess, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

	for (int i = 0; i < iconCount; i++)
	{
		byte[] iconNameBytes = new byte[256];

		LVITEM[] vItem = new LVITEM[1];
		vItem[0].mask = LVIF_TEXT;
		vItem[0].iItem = i;
		vItem[0].iSubItem = 0;
		vItem[0].cchTextMax = iconNameBytes.Length;
		vItem[0].pszText = (IntPtr)((int)pProcInfo + Marshal.SizeOf(typeof(LVITEM)));	// LVITEMの後ろの領域を指す領域とする
		uint vNumberOfBytesRead = 0;

		// vItemに情報を書き込む
		// Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0)は配列vItemの0番目を意味する
		WriteProcessMemory(hProcess, pProcInfo, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead);

		// インデックスiのアイテムを取得する
		SendMessage(hWndDesktop, LVM_GETITEMW, i, pProcInfo.ToInt32());
		ReadProcessMemory(hProcess, (IntPtr)((int)pProcInfo + Marshal.SizeOf(typeof(LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(iconNameBytes, 0), iconNameBytes.Length, ref vNumberOfBytesRead);

		// byte配列からアイコンの名前を取得する
		string vText = Encoding.Unicode.GetString(iconNameBytes, 0, (int)vNumberOfBytesRead);
		// \0以降にもデータがある可能性があるため最初の\0(=文字列の末尾)まで抜き出してそれをアイコン名とする
		int endOfTextIndex = vText.IndexOf('\0');
		string IconName = vText.Substring(0, endOfTextIndex);
		
		// アイコン位置を取得する
		SendMessage(hWndDesktop, LVM_GETITEMPOSITION, i, pProcInfo.ToInt32());
		Point[] vPoint = new Point[1];
		ReadProcessMemory(hProcess, pProcInfo, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(typeof(Point)), ref vNumberOfBytesRead);

		string IconLocation = vPoint[0].ToString();

		// DEBUG:アイテム情報をすべて取得してみる
		SendMessage(hWndDesktop, LVM_GETITEM, i, pProcInfo.ToInt32());
		ReadProcessMemory(hProcess, pProcInfo, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead);

		// リストボックスに情報を追加する
		listBox1.Items.Add("location:" + IconLocation + "  name:" + IconName + "   iItem:" + vItem[0].iItem);
	}

	// hProcessに関連するメモリーを解放する
	VirtualFreeEx(hProcess, pProcInfo, 0, MEM_RELEASE);

	CloseHandle(hProcess);

        // 最後にアイコン描画が更新されないことがあるため
	SendMessage(hWndDesktop, (uint)WindowMessage.WM_KEYDOWN, VK_F5, 0);
}



デスクトップのアイコンを移動させる

事前に[デスクトップのアイコン情報の取得]を参考にしてアイコン情報を取得しておいてください。
デスクトップのウィンドウハンドル(hWndDesktop)およびアイコンのインデックス(i)が必要になります。
ここでは例としてアイコン名がabcだったら座標(350, 50)へ移動させるものとします。

IconName = IconName.Replace("\0", "");
if (IconName.Equals("abc"))
{
    SendMessage(hWndDesktop, LVM_SETITEMPOSITION, i, MakeLParam(350, 50));
}



懸案

アイコン名をキーに位置を記憶しておき、それをもとにアイコン位置を復元する方法を考え付くと思いますが、Windowsはショートカットであれば同名のファイルを作成できてしまいます。
そうなると復元するときに異なる2つのアイコンを同じ場所に移動させることになり、おかしな挙動をすることになります。まぁほとんどないと思うので同名のファイルを作らないでといった注意書きをする程度でいいと思います。



Windows版のGoogle Chromeからの通知を切る方法

Windows版のChromeを使っていて、Youtubeなどからライブ開始の通知がぽろろーんという音ともにポップアップされるのがうざったいときがありますよね。この記事ではWindowsの設定で、Chromeからの通知を切る方法をご紹介します。

通知オフの手順

1.Windowsスタートボタン→設定(歯車マーク)を選ぶ
2.[システム]を選ぶ
3.[通知とアクション]を選ぶ
4.[送信元ごとの通知の受信設定]からGoogle Chromeのスイッチを「オフ」に設定する

時間帯で通知をオフにする方法

1.Windowsスタートボタン→設定(歯車マーク)を選ぶ
2.[システム]を選ぶ
3.[集中モード]を選ぶ
4.時間帯等で通知を受け取るかどうかの条件を設定する

bluetoothデバイスが不明なデバイスとして認識されてしまった場合の対処方法

Windows10の大型アップデート等でこの現象になることがあるようです。
ドライバーがインストールされない(コード28)、OSに互換性のあるドライバーがないと言われ、デバイスが使用できない状態に。

以下を実施することで解決できました。

1.デバイスマネージャーを開く
2.不明なデバイスを右クリックしてドライバーの更新を選ぶ
3.「コンピューターを参照してドライバーを検索」を選ぶ
4.「コンピューター上の利用可能なドライバーの一覧から選択します」を選ぶ
5.「Broadcom」の「BCM2033 Bluetooth 2.4....」を選んで「次へ」
6. ドライバーに互換性がないうんぬん言われるかもしれないが無視してインストールする

5.で選択するドライバーはそれっぽいのを選んでいますが、ダメな場合はいくつか試してみてください。Bluetoothは本来OSに元から入っているドライバーで十分動作するはずなので、おそらくはこの対処方法で解決すると思います。

ちなみに自分が持っているbluetoothバイスはUSB接続の↓です。
不明なデバイスは「BCM20702A0」という名前でした。
そのため上記5.でも頭にBCMが付いたドライバーを選択したのでした。
www.amazon.co.jp

突然Windows PCがお亡くなりなったときのレスキュー作業など

12年間使用していたマザーボードがお亡くなりになりました…。
突然のことだったのでディスクのバックアップはあまりとっていなかったのでここにレスキュー作業について書いていきたいと思います。適宜追記します。

ここでは新しいシステムドライブをCドライブ、レスキュー対象をDドライブとします。



Google Chromeのお気に入りの移行

1.まずChromeをインストールします。
2.以下のフォルダーをリネームします。

C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default
 ↓
C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default.old

3.以下の通りフォルダーをまるまるコピーします。

D:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default
 ↓
C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default



CLIP STUDIO PAINTの設定の移行

1.まずCLIP STUDIO PAINTをインストールして、起動&ライセンス認証を完了させます。
2.CLIP STUDIO PAINTを終了します。
3.以下のフォルダーをリネームします。

C:\Users\Tatsuro\Documents\CELSYS
 ↓
C:\Users\Tatsuro\Documents\CELSYS.old

4.以下の通りフォルダーをまるまるコピーします。

D:\Users\Tatsuro\Documents\CELSYS
 ↓
C:\Users\Tatsuro\Documents\CELSYS

ただこれだけだと、クリスタ内のコンポーネントの位置などが復元できていないような…。



ドラゴンクエスト11(Steam)のセーブデータ移行

1.Steamでドラゴンクエスト11をインストールしておく
2.以下のフォルダーをリネームします。

C:\Users\taiyakisun\Documents\My Games\ドラゴンクエスト XI S
 ↓
C:\Users\taiyakisun\Documents\My Games\ドラゴンクエスト XI S.old

3.以下の通りフォルダーをまるまるコピーします。

D:\Users\Tatsuro\Documents\My Games\ドラゴンクエスト XI S
 ↓
C:\Users\Tatsuro\Documents\My Games\ドラゴンクエスト XI S



スタートアップに起動したいアプリケーションのショートカットを置く

C:\Users\taiyakisun\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup



「送る」に置きたいアプリケーションを追加する(自分の場合は秀丸)

以下のいずれかをエクスプローラーのパスに入力する。

shell:sendto
C:\Users\taiyakisun\AppData\Roaming\Microsoft\Windows\SendTo



Windows Updateに関するトラブルシューティング

Windows Update(Microsoft Update)にて自分がぶつかった問題と解決方法を記載していきます。
Windows Updateは本っっっ当にトラブルが多いので、記事は適宜追加していきます。

なおシステムフォルダを操作する場合、はシステムを破壊する可能性があるため、十分に注意して行ってください



「再起動の保留中」(Pending restart)が消えず、OS再起動後もまた再起動を求められる

Windows Updateトラブルシューティングツールを実行する

1. [スタートボタン]→設定(歯車マーク)を選択する
2. [更新とセキュリティ]を選ぶ
3. [トラブルシューティング]を選ぶ
4. [追加のトラブルシューティングツール]を選ぶ
5. [Windows Update]を選ぶ
6. ツールを実行する
7. もう一度Windows Updateを更新してみる

Software Distributionフォルダをリネームする

Windows Updateトラブルシューティングツールで効果がなかった場合、これを試してみてください。
Software Distributionフォルダをリネームすると解決することがあります。
まずWindows Updateサービスを停止します。

Windowsキー + R → services.mscと打ち込んで実行

出てきたウィンドウからWindows Updateサービスを停止します。

その後、以下のフォルダをリネームしてください。(※1)(※2)

%SystemRoot%\SoftwareDistribution
 ↓
%SystemRoot%\SoftwareDistribution.old

その後、OSを再起動すると問題が解決する場合があります。

(※1) フォルダのリネームができない場合はセーフモードから行う

フォルダが使用中のためリネームできない、と言われた場合はセーフモードでリネームを行いましょう。
セーフモードとは必要最小限のプログラムだけでWindowsを起動させるモードのことを言います。

セーフモードの入り方は以下の通りです。
1. [スタートボタン]→設定(歯車マーク)を選択する
2. [更新とセキュリティ]を選ぶ
3. [回復]を選ぶ
4. [今すぐ再起動]を選ぶ
5. Windows起動中に「続行」や「トラブルシューティング」の画面が表示されたら[トラブルシューティング]を選ぶ
6. [詳細オプション]を選ぶ
7. [スタートアップ設定]を選ぶ
8. 再起動後「スタートアップ設定」という画面になるので、「セーフモードを有効にする」に該当するファンクションキー(自分の場合はF4でした)を押下する
9. セーブモードでWindowsが起動されます。

(※2) エクスプローラーで「%SystemRoot%フォルダ」が見られない場合の対処方法

エクスプローラーでシステムファイルの表示設定がオフになっているからと思われます。
エクスプローラーで以下の設定を行ってください。

1. エクスプローラーを開く
2. [表示]タブ→[オプション]を選択する
3. フォルダーオプションのダイアログが開いたら[表示]→[保護されたオペレーティング システム ファイルを表示しない(推奨)]のチェックを外す。

Windows Module Installerサービスを起動してからOSを再起動する

SoftwareDistributionフォルダのリネームでうまくいかなかった場合はこちらを試してみてください。
まずサービスのウィンドウを開きます。

Windowsキー + R → services.mscを打ち込んで実行

1.Windows Module Installerサービスのスタートアップ種類が「手動」になっているはずなので、これを「自動」に変更します。
2.Windows Module Installerサービスを開始します
3.Windows Installerサービスを開始します
4.コンピューターを再起動します
5.Windows Module Installerサービスのスタートアップ種類を「手動」に戻しておきます



よく言われる対処法だけど、ほとんど効果がないもの

自分はこれで解決したことがありませんが、よく言われるのでとりあえず書いておきます。

DISM

Windows Updateの破損を検出するツールのようです。
管理者権限でコマンドプロンプトを起動して以下のコマンドを実行します。

DISM.exe /Online /Cleanup-image /Restorehealth

システム ファイル チェッカー ツール (SFC.exe)

保護されたファイルに整合性エラーがないか検出するツールのようです。
管理者権限でコマンドプロンプトを起動して以下のコマンドを実行します。

sfc.exe /SCANNOW



WindowsUpdate.logの出力方法

中身を見てもよくわかりませんがとりあえず出力方法について。
以前は%SystemRoot%\WindowsUpdate.logにずらずらと出力されていましたが、今はファイル内に出力方法しか書いていません。以下にWindowsUpdate.logをデスクトップに出力する方法を示します。
1. Windowsキー + Xを押し、[Windows PowerShell (管理者)]を選択する
2. 表示されたPowerShellでGet-WindowsUpdateLogを実行する
3. デスクトップにWindowsUpdate.logが出力されます



エラーコード

0x80248007

Windows Update Centerにファイルが存在しない場合にこのエラーコードが出るようです。
古くてサポート切れになったOfficeなどがこのエラーになり、アップデートすることはできません。あきらめましょう。
自分の環境ではOffice XPでこのコードが表示されます。



約14kgの減量に成功したので7700kcal消費で1kg痩せるのか検証結果

2020/11/01~2021/04/30でダイエットを行いましたので、その記録を公開したいと思います。
すみませんが、後半カロリー記録はなく、体重記録のみとなります。

ポイントとしては、当たり前ですが摂取カロリー<消費カロリーにすること!
ですが、その他にも食事前にウェイドダウンのプロテインを飲んだり、野菜を先に食べたり、
朝を多めに食べて夜を軽めにしたり、夜は18時までに食べたり等など色々と工夫するべき点がありましたよ!

で、肝心の7700kcalで1kg痩せるのか?という点ですが、カロリー記録してある11/1~2/28の4か月で検証してみます。
摂取カロリー - 消費カロリーの差し引きカロリーは106,061kcalでした。

106,061 ÷ 7700 = 13.77kg

実際に減った体重は

88.50 - 77.65 = 10.85kg

という結果になりました!
しかし実際にはコーヒーに入れる牛乳を計上してなかったり、プロテインも少量だと計上していなかったりしているので、その分はカロリー摂取として計上漏れがありそうなので、まぁおおまかにはあってるんじゃないでしょうか。

自分はもう40歳に近いのですが、この通り7700kcalでだいたい1kgは痩せているので年を取ると痩せにくくになるということはなさそうです。あくまで「摂取カロリー<消費カロリー」がすべてだと思いますよー。

日付 体重 摂取カロリー 消費カロリー 差し引きカロリー
2020/11/01 88.50 2600 200 -150
2020/11/02 88.50 3080 350 -480
2020/11/03 88.50 1500 0 750
2020/11/04 88.50 1525 800 1525
2020/11/05 88.90 1909 944 1285
2020/11/06 88.25 3440 300 -890
2020/11/07 88.90 2363 400 287
2020/11/08 88.90 1715 0 535
2020/11/09 88.90 1600 0 650
2020/11/10 88.90 1747 500 1003
2020/11/11 87.65 2420 210 40
2020/11/12 87.75 1452 880 1678
2020/11/13 87.50 1782 200 668
2020/11/14 87.50 1545 0 705
2020/11/15 87.20 1414 0 836
2020/11/16 86.92 1430 0 820
2020/11/17 86.25 1500 350 1100
2020/11/18 85.95 1370 0 880
2020/11/19 86.30 1200 0 1050
2020/11/20 85.90 1278 713 1685
2020/11/21 85.90 1103 0 1147
2020/11/22 85.35 1798 0 452
2020/11/23 85.50 1798 0 452
2020/11/24 85.10 1543 0 707
2020/11/25 85.10 1280 400 1370
2020/11/26 84.20 1250 740 1740
2020/11/27 84.35 1644 472 1078
2020/11/28 84.50 788 0 1462
2020/11/29 83.75 1690 0 560
2020/11/30 84.20 1450 0 800
2020/12/01 83.50 2032 0 218
2020/12/02 83.85 1268 0 982
2020/12/03 83.95 1250 0 1000
2020/12/04 84.10 1820 772 1202
2020/12/05 83.55 1500 0 750
2020/12/06 83.75 1240 0 1010
2020/12/07 83.60 1400 0 850
2020/12/08 82.95 934 275 1591
2020/12/09 82.90 1700 0 550
2020/12/10 82.60 1750 100 600
2020/12/11 83.10 1650 0 600
2020/12/12 82.75 1750 300 800
2020/12/13 83.45 988 0 1262
2020/12/14 82.80 1635 0 615
2020/12/15 82.30 1258 550 1542
2020/12/16 82.45 1696 100 654
2020/12/17 81.85 1783 800 1267
2020/12/18 82.10 2093 1000 1157
2020/12/19 81.85 1393 1300 2157
2020/12/20 81.95 1470 0 780
2020/12/21 81.85 1803 0 447
2020/12/22 82.45 1394 700 1556
2020/12/23 82.10 1649 980 1581
2020/12/24 81.60 2606 1250 894
2020/12/25 81.60 1660 300 890
2020/12/26 81.85 915 1192 2527
2020/12/27 81.65 1203 0 1047
2020/12/28 81.35 783 0 1467
2020/12/29 81.05 1610 300 940
2020/12/30 80.80 1729 1050 1571
2020/12/31 80.75 2083 0 167
2021/01/01 80.65 1810 1230 1670
2021/01/02 80.85 2138 0 112
2021/01/03 81.15 1170 1150 2230
2021/01/04 80.8 2150 100 200
2021/01/05 81.65 1603 100 747
2021/01/06 81.1 1673 300 877
2021/01/07 80.75 1870 440 820
2021/01/08 80.25 1525 750 1475
2021/01/09 79.9 1347 0 903
2021/01/10 80.5 2911 0 -661
2021/01/11 81.05 1294 0 956
2021/01/12 80.5 1150 0 1100
2021/01/13 79.75 1580 0 670
2021/01/14 79.95 1678 400 972
2021/01/15 80.15 1258 520 1512
2021/01/16 80.05 2756 0 -506
2021/01/17 79.85 1100 0 1150
2021/01/18 79.65 1675 0 575
2021/01/19 79.5 1358 500 1392
2021/01/20 79.1 1852 330 728
2021/01/21 79.35 1650 0 600
2021/01/22 79.45 1450 0 800
2021/01/23 79 3190 0 -940
2021/01/24 79.25 2350 0 -100
2021/01/25 79.5 1170 0 1080
2021/01/26 79.7 1516 0 734
2021/01/27 79.2 1565 0 685
2021/01/28 79.4 2035 0 215
2021/01/29 79.5 1055 933 2128
2021/01/30 79.55 2876 770 144
2021/01/31 79.75 1879 100 471
2021/02/01 79.9 2456 1050 844
2021/02/02 80.15 2545 1689 1394
2021/02/03 79.9 1899 1384 1735
2021/02/04 79.4 1828 1191 1613
2021/02/05 79.65 1890 1505 1865
2021/02/06 79 1451 1288 2087
2021/02/07 78.4 1450 1561 2361
2021/02/08 78.55 1844 1150 1556
2021/02/09 78.95 2117 789 922
2021/02/10 78.9 1902 1583 1931
2021/02/11 78.45 1533 0 717
2021/02/12 78.3 1778 1150 1622
2021/02/13 78.35 1650 0 600
2021/02/14 78.1 1450 0 800
2021/02/15 78.4 1500 66 816
2021/02/16 77.9 2050 1235 1435
2021/02/17 77.7 1647 0 603
2021/02/18 77.8 2427 0 -177
2021/02/19 78 1780 950 1420
2021/02/20 78.1 1850 0 400
2021/02/21 78.5 1890 0 360
2021/02/22 78.5 1901 0 349
2021/02/23 78.25 1900 0 350
2021/02/24 78 1850 0 400
2021/02/25 77.6 1800 0 450
2021/02/26 77.65 1600 0 650
2021/02/27 77.65 2500 0 -250
2021/02/28 77.65 2200 0 50
2021/03/02 77.55
2021/03/03 77.45
2021/03/04 77.20
2021/03/05 77.10
2021/03/06 77.00
2021/03/07 76.90
2021/03/08 76.80
2021/03/09 76.70
2021/03/10 77.25
2021/03/11 77.30
2021/03/12 77.20
2021/03/13 77.20
2021/03/14 76.45
2021/03/15 76.45
2021/03/16 76.45
2021/03/17 76.65
2021/03/18 76.65
2021/03/19 76.65
2021/03/20 76.65
2021/03/21 76.65
2021/03/22 76.85
2021/03/23 76.20
2021/03/24 76.75
2021/03/25 76.75
2021/03/26 76.75
2021/03/27 76.40
2021/03/28 75.80
2021/03/29 75.80
2021/03/30 75.80
2021/03/31 75.80
2021/04/01 75.60
2021/04/02 75.60
2021/04/03 75.60
2021/04/04 75.60
2021/04/05 75.60
2021/04/06 75.90
2021/04/07 75.90
2021/04/08 75.35
2021/04/09 75.10
2021/04/10 74.30
2021/04/11 74.25
2021/04/12 74.20
2021/04/13 74.10
2021/04/14 74.80
2021/04/15 74.80
2021/04/16 74.40
2021/04/17 74.40
2021/04/18 74.40
2021/04/19 75.15
2021/04/20 75.15
2021/04/21 73.15
2021/04/22 73.40
2021/04/23 73.40
2021/04/24 74.10
2021/04/25 74.35
2021/04/26 74.35
プライバシーポリシー お問い合わせ