一時的に作ったテキストデータをC:\に書き出して、そのファイルをShellExecuteで関連付けされたソフトを起動させるようなソフトを作ったのですがPCによっては「ファイルへのアクセスが拒否されました」というエラーが出て止まってしまいます。(特にVISTA)
実験したところ書き出すドライブをリムーバブルディスクにするとOKのようです。しかし常にリムーバブルが入っているとは限りません。このような場合どうしたらエラーを回避できるか教えてください。
C:\ は本来、一般ユーザが書き込んでよい場所ではありません。
書込可能なフォルダを別途用意しておき、そこに書くようにしましょう。
あるいは汎用的に、TEMPフォルダやマイドキュメントフォルダなどの
ユーザ別フォルダを利用するのも手かと。
Vistaの場合UACという概念により、Administoratorでログインしていても、
User権限で実行してしまいます。
(UACはVista用に開発している技術者なら必ず認識しなければならないことです。)
「C:\」はエクスプローラで右クリック-セキュリティで確認できると思いますが、
User権限では書き込めないようになっています。
(「読み取りと実行」の権限になるはず)
ですので、「書き込み」権限のあるフォルダ
たとえば、C:\Users\ユーザ名\Document\ とかに作成するようにすればいいでしょう。
一時ファイルならTEMPフォルダというものがあるのでそこでもいいでしょう。
# Vistaで
# (「読み取りと実行」の権限になるはず)
# とか確認していたらむちゃくちゃかぶった。
# 8分も後なのに。。。orz
>C:\Users\ユーザ名\Document\
は
C:\Users\ユーザ名\Documents\
でした。
特殊フォルダを取得する関数は用意されているので、それを使えば
TEMPだろうがユーザのドキュメントフォルダだろうが取得できます。
(VB.NETなのかVB6以下なのかでは記述が違いますが。)
魔界の仮面弁士様、早速のレスをありがとうございました。
不特定なソフト使用者のマシンの中にある書き込み可能フォルダーをどのように見つけることができるのでしょうか。
手元にあるXPとVISTAを見たところXPではC:\My DocumentフォルダーはあるのですがVISTAではありません。(C:\Usersならあります)
このような場合には一時ファイルを吐き出す場所をどのように決めたら良いかもう一度教えてください。
BLUE様、ご回答をありがとうございました。(前回UPの時間が前後してしまったようで申し訳ありません VBはVB6 SP6です)
当方のVISTAではC:\Users\ユーザー名\My Documentsならありました。(単にDocumentsはありませんでした) 不特定なユーザーのパスを取得する方法などあるのでしょうか? なお使用OSはW2000、XP、Vistaが考えられます。(できれば98も) このような場合にはOSを判定して、あるいは該当するフォルダーがあるかどうかを探していくのでしょうか? よろしくお願いします。
> C:\Users\ユーザー名\My Documents
あれぇ?
Vista Businessで調べたけどDocumentsでした。
98までですか。
2000以降であれば、Wscript.Shellが普通に使えるんですけど、98は微妙かも。
(Windows Host Scriptに関しては調査していないから,,,)
特殊フォルダのパス名の取得
http://www.bcap.co.jp/hanafusa/VBHLP/special.htm
APIを使う方法は、Shell32.dllが4.72以上のバージョンですので
SHGetSpecialFolderPath関数でCSIDL_PERSONAL
を指定する方法で取得可能です。
APIを使っての特殊フォルダのパス名の取得
http://www.bcap.co.jp/hanafusa/VBHLP/specialapi.htm
# Vista対応って、ここまで調査するのは普通じゃないのかなぁ?
Blue様、具体的なご回答をありがとうございました。
早速2例をテストしましたがやはりAPIを使わないとWin98ではだめでした。APIでは下記でテストしましたが書き込みもOKでした。これから更に確認のため友人のVISTAでテストしてもらう予定です。
># Vista対応って、ここまで調査するのは普通じゃないのかなぁ?
VISTA以前は特に問題なかったのですがここへきて友人からエラーの話がでてきました。今後はこの技を活用させていただきます。 ありがとうございました。
Private Declare Function SHGetSpecialFolderPath Lib "SHELL32" _
Alias "SHGetSpecialFolderPathA" (ByVal hwndOwner As Long, _
ByVal lpszPath As String, ByVal nFolder As Long, _
ByVal fCreate As Long) As Long
Private Sub SpecialFolder()
Dim Result As Long
Dim nFolder As Long
Dim lpszPath As String
Dim fnam
Dim f
'パス名を受け取るバッファを確保
lpszPath = String$(260, vbNullChar)
'関数の実行
Result = SHGetSpecialFolderPath(Me.hWnd, lpszPath, &H5, 0)
'フォルダ名の取得
Text1.Text = Left$(lpszPath, InStr(lpszPath, vbNullChar) - 1)
’書き込んでみる
fnam = Text1.Text & "\test.txt"
f = FreeFile
Open fnam For Output As #f
Print #f, "aaaaaaaaaaaaaaaaaaaaaaaaaa"
Close #f
End Sub
Private Sub Form_Load()
SpecialFolder
End Sub
ツイート | ![]() |