TEMPフォルダにSSDの寿命削りをやめさせる

SSDって寿命があるじゃないですか。
まあ、HDDより短いってわけじゃなさそうなんですけど、少しでも長くしたいのが人情。
そこで気になるのが、TEMPフォルダとブラウザの作業領域。
これをRAMディスクに追い出すのです。



思想

RAM Diskに「temp」フォルダを作成する。
temp\SYSTEMをシステムのTEMPにする。
temp\%USERNAME%\tempをユーザーのTEMPにする。
temp\%USERNAME%\chromechromeの作業領域にする。


RAM Diskは起動時に作るようにするけど、できる前は元のTEMPのままにしておく。


なので、タスクスケジューラーで、ユーザーセッションの接続/切断でTEMPをいじる。
タスクスケジューラーなら特権で動かせるし。


chromeはショートカットの変更「--disk-cache-dir="R:\temp\%USERNAME%\chrome"」

苦戦したこと

例えば、PowerShell

[Environment]::GetEnvironmentVariable('Temp')
$env:Temp

とかすると、TEMPが取得できるわけですが、結果が
「C:\Users\xxxxxx\AppData\Local\Temp」
とか言われる。でも実際は、
「%USERPROFILE%\AppData\Local\Temp」
気にしなければ良いのだけど、くやしいので取得方法を探ってみた。


結論。
レジストリを展開なし指定で読む。

$e = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment')
$e.GetValue('Temp', $null, 'DoNotExpandEnvironmentNames')
$e.Dispose()

TEMPをRAM Diskに移動するアプリケーション生成

$source = @"
using System;
using System.Configuration;
using System.IO;
using System.Security.Principal;
using Microsoft.Win32;

class Program
{
	static void Main(string[] args)
	{
		string basepath = ConfigurationManager.AppSettings["Path"];
		if(string.IsNullOrEmpty(basepath)) basepath = @"R:\temp\";
		string syspath = string.Format("{0}SYSTEM", basepath);
		string userpath = string.Format("{0}{1}\\", basepath, Environment.GetEnvironmentVariable("USERNAME"));
		string usertemp = string.Format("{0}temp", userpath);
		string userchrome = string.Format("{0}chrome", userpath);
		string tempback = "TempBack";
		string temp = "TEMP";
		Directory.CreateDirectory(syspath);
		Directory.CreateDirectory(usertemp);
		Directory.CreateDirectory(userchrome);
		if((new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator)) {
			if(string.IsNullOrEmpty(Environment.GetEnvironmentVariable(tempback, EnvironmentVariableTarget.Machine))) {
				using(RegistryKey lm = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
					Environment.SetEnvironmentVariable(tempback, lm.GetValue(temp, null, RegistryValueOptions.DoNotExpandEnvironmentNames) as string, EnvironmentVariableTarget.Machine);
				}
				Environment.SetEnvironmentVariable(temp, syspath, EnvironmentVariableTarget.Machine);
				Environment.SetEnvironmentVariable("TMP", syspath, EnvironmentVariableTarget.Machine);
			}
		}
		if(string.IsNullOrEmpty(Environment.GetEnvironmentVariable(tempback, EnvironmentVariableTarget.User))) {
			using(RegistryKey cu = Registry.CurrentUser.OpenSubKey("Environment")) {
				Environment.SetEnvironmentVariable(tempback, cu.GetValue(temp, null, RegistryValueOptions.DoNotExpandEnvironmentNames) as string, EnvironmentVariableTarget.User);
			}
			Environment.SetEnvironmentVariable(temp, usertemp, EnvironmentVariableTarget.User);
			Environment.SetEnvironmentVariable("TMP", usertemp, EnvironmentVariableTarget.User);
		}
	}
}
"@

Add-Type $source -OutputAssembly 'temp2ram.exe' -OutputType WindowsApplication -ReferencedAssemblies System.Configuration

TEMPをRAM Diskからもとに戻すアプリケーション生成

$source = @"
using System;
using System.IO;
using System.Security.Principal;
using Microsoft.Win32;

class Program
{
	static void Main(string[] args)
	{
		string tempback = "TempBack";
		string temp = "TEMP";
		if((new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator)) {
			if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(tempback, EnvironmentVariableTarget.Machine))) {
				using(RegistryKey lm = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
					string org = lm.GetValue(tempback, null, RegistryValueOptions.DoNotExpandEnvironmentNames) as string;
					Environment.SetEnvironmentVariable(temp, org, EnvironmentVariableTarget.Machine);
					Environment.SetEnvironmentVariable("TMP", org, EnvironmentVariableTarget.Machine);
					Environment.SetEnvironmentVariable(tempback, null, EnvironmentVariableTarget.Machine);
				}
			}
		}
		if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(tempback, EnvironmentVariableTarget.User))) {
			using(RegistryKey cu = Registry.CurrentUser.OpenSubKey("Environment")) {
				string org = cu.GetValue(tempback, null, RegistryValueOptions.DoNotExpandEnvironmentNames) as string;
				Environment.SetEnvironmentVariable(temp, org, EnvironmentVariableTarget.User);
				Environment.SetEnvironmentVariable("TMP", org, EnvironmentVariableTarget.User);
				Environment.SetEnvironmentVariable(tempback, null, EnvironmentVariableTarget.User);
			}
		}
	}
}
"@

Add-Type $source -OutputAssembly 'temprestore.exe' -OutputType WindowsApplication