CSIDL_LOCAL_APPDATAフォルダに保存したファイルがExcelで編集出来ない

解決


take  2020-01-29 15:06:40  No: 148504

Delphiの質問から少し外れるのですがUACでやっかいな現象が出ているので教えてください。
プログラムから csv の値を取得する処理自体は正常に動作するのですが
配布用にデータを

C:\Users\[ユーザー名]\AppData\Local\[アプリ名]
にインストールして
データフォルダ名取得として下記のように

var
  s : string;
  csid,i : Integer;
begin;
  SetLength(s, MAX_PATH);                           // Pathの最大長分メモリ確保
  csid := CSIDL_LOCAL_APPDATA;                      // ローカルユーザーフォルダの取得を指定

  SHGetFolderPath(0, csid or                        // フォルダ名の取得
                  CSIDL_FLAG_CREATE,0,0,PChar(s));
  i := Pos(#$0,s);                                  // ヌルの位置を取得
  SetLength(s,i-1);                                 // 文字列長を実際の長さに合わせる

これでインストールした csvを読むことまでは正常に動作します。

ですがこの csvをExcelで開いて修正するとUACの機能が働いているのか編集出来ません。

1.内容を修正する
 プログラムからは修正前の状態が取得される
 更新日時に変化無し

2.別のドライブで作ったファイルを上書き
 更新日時はコピー元に更新される
 プログラムからは修正前の状態が取得される

3.ファイル名を削除する
 プログラムからはファイルが無いと認識される

4.管理者権限で実行する
 変化無し

Excelの名前を付けて保存で表示されるフォルダ内の状態と
エクスプローラーで表示されるC:\Users\[ユーザー名]\AppData\Local\[アプリ名]
が不一致になります。

メモ帳で開く分は問題無いのですが原因がなにか考えられますでしょうか?


HFUKUSHI  2020-01-29 19:45:32  No: 148505

まず問題の切り分けのため、ファイルのフルパス名をSHGetFolderPathから作るのをやめて、固定のパス名にしてみてはいかがでしょう?
その上でC:\Users\[ユーザー名]\AppData\Local\[アプリ名]以下にファイルを置く場合と、それ以外の場所に置く場合で振る舞いが異なるかどうかですね。


take  2020-01-30 09:14:45  No: 148506

ありがとうございます。
簡単な方法で現象が再現出来たので説明しますと

エクスプローラーから
C:\Users\[ユーザー名]\AppData\Locol
のフォルダを開きます。

フォルダ内でテスト用フォルダ
UACTest
を作ってそのフォルダ内に移動します。

新規ファイルでExcel ファイルを作成します。
デフォルト名 新規 Microsoft Excel ワークシート.xlsx が完成
出来たファイルをExcelで開きます。

セル内に「Ver1」と入力して上書き保存します。

名前を付けて保存で同じフォルダ内に別名
Microsoft Excel ワークシート2.xlsx
で保存します。

これでExcelからは
Microsoft Excel ワークシート2.xlsx
があるのに
エクスプローラーからは見えないというおかしな事になります。

今度は 新規 Microsoft Excel ワークシート.xlsx を開きます。
セル内の「Ver1」を「Ver2」に書き換えます。
上書き保存して閉じます。
そして新規 Microsoft Excel ワークシート.xlsx を開くと
セル内は「Ver2」となってるので更新は正常です。

次にエクスプローラーから
新規 Microsoft Excel ワークシート.xlsx
を名前変更して 見えないはずの
Microsoft Excel ワークシート2.xlsx
に変更してから開くと 開いたファイルのセルは「Ver1」の表示になります。

フォルダ名付きファイル名がUACかなにかで管理されていて
仮想フォルダ方でなにかが行われているようなイメージです。

この現象はExcelで発生しますが メモ帳では発生しません。


take  2020-01-30 11:32:33  No: 148507

アプリケーションのローカルデータフォルダがだめなら
マイドキュメントへおいてということで

CSIDL_LOCAL_APPDATA を CSIDL_PERSONAL に変更
インストールもドキュメント内のフォルダへ置くように変更

実行してみると今まで悩んでいたことが嘘のように改善されてすべて正常
Delphi側からも Excel側からも同じファイルが参照されるようになりました。

でもこのやり方って正しいのでしょうかね?


HFUKUSHI  2020-01-30 11:42:44  No: 148508

あまり詳しくはないのですが、Excelって開いているファイルに細工してませんっけ?
# 共有においてあるファイルを別々のPCのExcelから開くと2つめは読み込み専用で開きますか?とか聞かれるやつです。開くだけでファイルの中身を書き換え、保存しないで閉じると元の内容に戻してタイムスタンプも戻すような、そんな動作をしてると思います。


take  2020-01-30 11:57:48  No: 148509

PC-A で編集したExcelを PC-B に持っていって編集するときも
最初になにか警告が出て編集出来ないことがありますね。

こうやってExcel1 を Excel2 に変換するだけなのですが

これでユーザーに編集させる
s := 'Excel1.xls';
ShellExecute(Handle, nil, 'explorer.exe', PChar(s), nil, SW_SHOW);

これで変換
ExcelConvert('Excel1.xls','Excel2.xls');

変換後のを開く
s := 'Excel2.xls';
ShellExecute(Handle, nil, 'explorer.exe', PChar(s), nil, SW_SHOW);

いくら編集しても、変換に反映されないのはちょっと頭痛いですね。


take  2020-02-03 08:56:17  No: 148523

Excel形式で編集する可能性があるファイルはマイドキュメントフォルダの下に設置するということで
解決とさせていただきます。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加