先日、@muu000 さんが、このような問題で困っていたそうです。
しかし私は問題なくインストールできます、他の方も問題なかったようです。
どうやら原因は、ユーザーフォルダが2byte文字 = 日本語だったようです。
原因はユーザー名の2バイト文字でした
— 導かれしむー (@muu000) October 26, 2013
今回は、2byte 文字のユーザーフォルダができてしまった時に、「ユーザーフォルダのパスだけ変更」してみましょう。
目次
そもそも2Byte文字になぜなったのか
Windows 8やWindows8.1 は、Microsoftアカウントでログインが可能です。(Windows 8.1 は必須)
muu000 さんは、MSアカウントでこのようにしていたようです。
ちなみにMicrosoftアカウント名前表示のところな。これは騙されるでしょ pic.twitter.com/XThNLzXj3O
— 導かれしむー (@muu000) October 26, 2013
そうすると、入力した名前 = 日本語名だったら日本語フォルダでユーザーフォルダが初回ログイン時に生成されます。
対処方法
2Byte文字でのパス解釈が問題になる事例は、古くは石器時代から Windows 8 まで言われており、Windows 8.1 でも防げていません。
Microsoft アカウントを日本語で作らない
色々しょうがないと思いますが、そもそも Microsoft アカウントで OSログオン = Microsoftアカウントに日本語を入れないのがベストでしょう。
と、いうと辛いので以下の方法があります。
ユーザーフォルダの参照とフォルダ名を変更する
ようは、以下を求めています。
- ローカルアカウントで管理者を別途用意する
- 変更対象のユーザーはサインアウトする
- 変更作業のため、対象とは別の管理者でログオン
- 対象ユーザーのフォルダを、新たに利用したいユーザーフォルダ名に変更
- レジストリ
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\
のProfileImagePath
にユーザーフォルダパスが入っているので、変更したいユーザーフォルダ名に変更
決まりきった作業のために、マウス操作とか辛いですね。
PowerShell で自動実行しましょう。
PowerShell コード
GitHub
PowerShellUtil / Set-NewUserProfileImagePath / Set-NewUserProfileImagePath.ps1
対象 PowerShell バージョン
PowerShell 4.0*1
コード
#Requires -RunAsAdministrator #Requires -Version 4.0 function Set-NewUserProfileImagePath { <# .Example # change username share's userFolder from c:\users\share to c:\users\hoge Set-NewUserProfileImagePath -user share -currentUserFolderName share -newUserFolderName hoge -Verbose .Example # evenif userfolder name not same as username, you can change username share's userFolder from c:\users\hoge to c:\users\share Set-NewUserProfileImagePath -user share -currentUserFolderName hoge -newUserFolderName share -Verbose .Example # with -force switch, you can force input desired imagepath c:\users\share to registry for user share. This never depend on how userfolder is set Set-NewUserProfileImagePath -user share -currentUserFolderName hoge -newUserFolderName share -Verbose -Foce #> [CmdletBinding()] param ( # enter username to be changed [parameter( mandatory, position = 0)] [string] $user, # enter current user folder name to be changed [parameter( mandatory, position = 1)] [string] $currentUserFolderName, # enter new user Folder name change to [parameter( mandatory, position = 2)] [string] $newUserFolderName, # enter new user Folder name change to [switch] $force ) begin { # get foler information $private:usersFolder = Split-Path $env:USERPROFILE -Parent $private:currentUserFolder = Get-ChildItem $usersFolder | where PSISContainer | where Name -eq $currentUserFolderName $private:newuserFolder = Join-Path $usersFolder $newUserFolderName # get registry information $private:registryPath = "registry::HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $private:users = Get-CimInstance Win32_UserAccount $private:sid = $users.Where({$_.Name -eq $user}).SID # set registry information $private:regSidDetail = Get-ItemProperty -Path (Join-Path $registryPath $sid) $private:currentProfileImagePath = $regSidDetail.ProfileImagePath $private:newProfileImagePath = if ($force) { $newuserFolder } elseif($currentProfileImagePath -eq $currentUserFolder.FullName) { $newuserFolder } else { $null } } process { if ($user -ne $env:USERNAME) { # userFolder change Write-Verbose ("Start changing user Folder '{0}' to '{1}'" -f $currentUserFolder.FullName, $newuserFolder) if($currentUserFolder.FullName) { if ($currentUserFolder.FullName -ne $newuserFolder) { Rename-Item -Path $currentUserFolder.FullName -NewName $newuserFolder -PassThru -Confirm } else { Write-Warning ("newUserFolder '{0}' detected as same as currentUserFolder '{1}'." -f $newUserFolder, $currentUserFolder.FullName) } } else { Write-Warning ("currentUserFolder '{0}' detected as null." -f $currentUserFolder.FullName) } # registry change Write-Verbose ("Start changing Registry from '{0}' to {1} , for user '{2}' with sid '{3}'" -f $currentProfileImagePath, $newProfileImagePath, $user, $sid) if ($newProfileImagePath) { if ($newProfileImagePath -ne $currentProfileImagePath) { Set-ItemProperty -Path "registry::HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid" -Name ProfileImagePath -Value $newProfileImagePath -Confirm -PassThru } else { Write-Warning ("newProfileImagePath '{0}' detected as same as currentProfileImagePath '{1}'" -f $newProfileImagePath, $currentProfileImagePath) } } else { Write-Warning ("newProfileImagePath '{0}' detected as null." -f $newProfileImagePath) } } else { Write-Warning ("Current user '{0}' is same as target user '{1}'. Please execute this command with other user who have admin priviledge"-f $env:USERNAME, $user) } } end { } }
-Verboseについて
つけなくても動作は変わりませんが、付けると今どのような操作を行っているかが表示されます。
利用する前に
最低この手順だけは必要ですの。ファイル共有制限で処理できない場合があるので。
- ローカルアカウントで管理者を別途用意する
- 変更対象のユーザーはサインアウトする
- 変更作業のため、対象とは別の管理者でログオン
- スクリプト実行
利用例.1
例えば、 ユーザー名 share
が存在して、ユーザーフォルダを c:\users\share
からc:\users\hoge
に変えたい場合は以下のようにします。
Set-NewUserProfileImagePath -user share -currentUserFolderName share -newUserFolderName hoge -Verbose
利用例.2
例えば、 ユーザー名 share
が存在して、ユーザーフォルダが c:\users\hoge
だった時、c:\users\share
に変えたい場合は以下のようにします。
Set-NewUserProfileImagePath -user share -currentUserFolderName hoge -newUserFolderName share -Verbose
利用例.3
例えば、 ユーザー名 share
が存在して、ユーザーフォルダが c:\users\hoge
だった時、c:\users\share
に変えたい場合。
さらにすでに ユーザーフォルダが、c:\users\hoge
で、レジストリのみc:\users\share
だった場合は、以下でレジストリを強制的に変更可能です。
Set-NewUserProfileImagePath -user share -currentUserFolderName hoge -newUserFolderName share -Verbose -Foce
muu000さんの事例の対応
muu000 さんの事例の場合は、以下のやり方で自由に変更可能です。
Set-NewUserProfileImagePath -user loginUserName -currentUserFolderName 日本語フォルダ名 -newUserFolderName 変更したいフォルダ名 -Verbose -force
対処できない事例
ちなみに、これは、%userProfile% 対策なので、この変更前にインストールしたアプリケーションで、絶対パスで ユーザーフォルダを見てるアプリケーションには通じません。
この場合は、シンボリックリンクでリダイレクトさせます。
例えば、hogehogeユーザーのフォルダc:\users\hogehogeを、c:\users\hogeにするなら
Set-NewUserProfileImagePath -user hogehoge -currentUserFolderName hogehoge -newUserFolderName hoge -Verbose mklink /d C:\users\hoge C:\users\hogehoge
こうすることで、%userprofile% と 絶対パスの両方に対して手が打てます。
まとめ
なんというか、ニッチなスクリプトを作ってしまいました。
OSインストール直後でもない限り、よほどの理由がない場合はユーザー作り直す方が安全だと思いますよ。
*1:PowerShell3.0で動作するように書き換えが可能ですが、せっかくなので