• 締切済み

WinVista UACが有効なのにProgramFilesにアクセスできてしまう

こんにちは。 WindowsVista Home Premium SP2 Visual C++ 2008 Express Edition 上記の環境で作成したアプリで、不可解な事があるので質問させていただきます。 現在、C:\Program Filesの下の同一フォルダにインストールされている2つのプログラム間で、ファイルを介してデータのやり取りを行おうと考えております。 簡略化のため、最小限のファイル構成のみ書かせていただきます。 C:\Program Files   + TargetApp ←インストール先フォルダ    + TargetApp.exe    ←データのやり取りの相手    + MyApp.exe      ←私が作ったアプリ    + Test.ini       ←データ受け渡しをするファイル さて、ここでProgram Files\Test.iniをアプリからアクセスすると、通常ですとVistaのUAC機能により、本物のTest.iniにはアクセスできず、代わりにVirtualStore内の同名ファイルに飛ばされてしまう、という理解を私は現在しております。 たとえVirtualStoreに飛ばされても、2つのアプリがお互いに飛ばされれば、結果的に同じファイルをアクセスできるものと思っておりました。 ところが、やってみますと、私の作ったMyAppは、Program Files内の本物のTest.iniに直にアクセスしてしまうようなのです。 試しに、Program Files内とVirtualStore内のTest.iniの内容を、以下のように違うものにして、簡単なテストプログラム(TestApp.exe)を走らせてみました。 [Program Files\TargetApp\Test.ini] This File is in 'Program Files' [VirtualStore\Program Files\TargetApp\Test.ini] This File is in 'VirturlStore' [TestProgram] // Tabは全角スペースに置き換えています #include <stdio.h> int  main(int argc, char *argv[]) {  FILE *fp;  int  cc;  if(argc < 2){   printf("ファイルを指定してください。\n");   return -1;  }  if(fopen_s(&fp, argv[1], "r")){   printf("ファイルが開けません。\n");   return -1;  }  while((cc = fgetc(fp)) != EOF){   printf("%c", cc);  }  fclose(fp);  return 0; } テストプログラムを実行 >TestApp "C:\Program Files\TargetApp\Test.ini" This File is in 'Program Files' このように、本物が見えてしまいます。 なお、テキストエディタでこのファイルを開くと、VirtualStoreの内容が見えますので、うっかりUACがOFFになっている等はないと思います。 Vistaの基本的な知識が抜けているだけだとは思うのですが。。。 VirtualStoreの残像拳の方にアクセスできるよう、ご教示を頂ければと思います。 よろしくお願いいたします。

みんなの回答

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

Vistaでは、アプリを管理者権限で動かすとProgram Fileの下を直接参照できます。なので、どうしてもVirtualStore側を参照したい場合は一般権限で動かしてください。 ちなみに、#1の回答者の言われるとおりそもそも管理者権限や一般権限で参照場所が変わるアプリはお行儀が悪いので、SHGetFolderPath()でLOCAL_APPDATAを取得してこのパスの下に自分のアプリ用のフォルダを作ってデータを収めるのが良いかと思いますが。

pyonmae
質問者

お礼

ご回答ありがとうございます。 いえいえ、一般権限で動かしているのにアクセスできてしまうので、困っていたのです。 お行儀は、私も悪いと思います・・・。 結果的に、#1さんの所に書いたように自己解決いたしました。 申し訳ありません。

  • chie65535
  • ベストアンサー率43% (8514/19355)
回答No.1

http://dsas.blog.klab.org/archives/51108671.html#programfiles に ---------------- C:\Program Files フォルダ配下にプログラムの実行ファイルを配置することは一般的ですが、更新を前提とするデータファイル(.ini ファイル等)を配置すべきではありません。 ---------------- と書かれています。 なので、 C:\Program Files   + TargetApp ←インストール先フォルダ    + TargetApp.exe    ←これはOK。    + MyApp.exe      ←これはOK。    + Test.ini       ←これはNG。 この位置にTest.iniを配置してはいけません。 ここに配置してはいけない理由は「UACを有効にした時と、UACを無効にした時で、プログラムがアクセスしに行くファイルが変わってしまい、一意の決まった動作が保証されない」からです。 つまり「UACがオンでもオフでも、どっちでも正しく動かなくてはならない」ので、ここにiniファイルを置いてはならないのです。 従って「C:\Program Files配下のiniファイルを使って情報の受け渡しをする事そのものが許されない」です。 情報の受け渡しは、環境変数を使うとか、環境変数に「専用のフォルダの位置」を設定し、環境変数を介して目的のフォルダ位置とファイル名を求めるなど「C:\Program Files配下のファイルに依存しない形」で行う必要があります。 結論は「iniファイルをそこに置くのは推奨されないから、やっちゃ駄目」って事です。 なお、質問者さんのケースのように「%PROGRAMFILES%を使わない」とか「SHGetFolderPath関数を使わない」など「生で、C:\Program Files\~~と書いてしまっている、お行儀の悪いプログラムに対しては、UACは責任を持たない」です。 なので「生で、C:\Program Files\~~と書いた場合」にはVirtualStoreにはアクセスしません。

pyonmae
質問者

お礼

ご回答ありがとうございます。 丁寧なご回答を頂いたのに、申し訳ありません。 実は、質問してからさらにググっていたら、自己解決してしまいました。 プロジェクトのプロパティ  →リンカ  →マニフェストファイル  →UACを有効にする    ↑これを「いいえ」にすると、VirtualStoreにアクセスできました。 運用的にダメなのは私も承知の上なのですが、そういう仕様で決められちゃった以上、進めなければいけないのが悲しい宮仕えでして・・・。 あと、すみません。 お行儀の悪いプログラムにこそ、UACは責任もってちゃんと仕事をするべきだと思うのですが・・・。 そういうものなのでしょうか。

関連するQ&A

  • ランダムアクセスができない

    C言語のランダムアクセス(fseek)で、 アクセス位置を「ファイル末尾」に設定したいのですが どうも自分で作成したソースは正常に動いてくれません。 (常にアクセス位置が先頭になってしまいます) 何かが間違ってるのは確かなのですが、 もし原因がお判りの方がいらっしゃいましたら アドバイスをお願いします。 動作としては、追記書き込みみたいな感じで どんどん同一ファイルに書きこんで行く感じです ―――――――――――――――――――――――――― #include <stdio.h> #include <string.h> // 書き込み関数 bool Write( char *fname, char *str ){ FILE *fp = NULL; int len = (int)strlen(str); fp = fopen( fname, "wb" ); if( !fp ) return false; fseek( fp, 0L, SEEK_END ); printf( "位置:%d\n", ftell(fp) ); fwrite( &str, len, 1, fp ); fclose( fp ); return true; } // メイン関数 int main(){ char *fname = "Test.txt"; Write( fname, "テスト" ); Write( fname, "教えて" ); Write( fname, "goo" ); return 0; } ―――――――――――――――――――――――――― 動作結果:   Test.txtの中身「goo」 動作してほしい結果:   Test.txtの中身「テスト教えてgoo」 (※中身はバイナリ形式です)

  • バイナリファイルでランダムアクセスを行う

    初心者です。宜しくお願いします。 下記 text.bin にランダムアクセスするサンプルコードで一部理解できない箇所があります。 下から5行目のfreadの一つ目の引数 &num です。なぜ5のポインタなのか初心者にわかりやすく解説頂けないでしょうか? 宜しくお願い致します。 ■text.bin 80 60 22 50 75 ■サンプルコード #include <stdio.h> #define NUM 5 int main(void) { FILE *fp; int num; int i; fp = fopen("/Users/Documents/test1.bin", "rb"); if (fp == NULL) { printf("ファイルをオープンできませんでした。\n"); return 1; } printf("何番目のデータを読み込みますか?(1~5)\n"); scanf("%d", &i); fseek(fp, (i-1)*sizeof(int), SEEK_SET); fread(&num, sizeof(int), 1, fp); printf("%d番目のデータは%dです。\n", i, num); printf("<#message#>"); fclose(fp); return 0; }

  • プログラミング<暗号入力プログラム>について

    はじめまして。よろしくお願いします。 現在、大学でプログラミングを習っているhayato2192といいます。 この間、ファイルを開くプログラムというのを習ったのですが、 そのプログラムを利用して何かほかのプログラムが作りたいなぁと思い、 暗号入力するとファイルが開く というプログラムをつくったのですが、 コンパイルはできても一向にファイルが開けないので、 コードをどうかえればいいか、というのを教えてください。 よろしくお願いします。 ちなみに、暗号は文字列が良いです。 コードは以下です ******************************** #include <stdio.h> int main(void) { FILE*fp; char i; int c; printf("START PROGRAM * FP\n"); printf("YOU SHOULD INPUT COAD\n"); scanf(" %s", i); if(i == "fileopen"); { if((fp = fopen("\\PROGRAM\\0123456789100.txt", "r")) == NULL) { printf("YOU CAN'T OPEN"); return 1; } while((c = fgetc(fp)) != EOF) { printf(" %c", c); } } else { printf("YOU CAN'T OPEN"); return 2; } fclose(fp); return 0; } ******************************** オープンするファイルはそんな結滞なもんじゃありません。 よろしくお願いします ただのテキストファイルです。

  • ファイルから一文字ずつ読み込む

    ファイルを読み込むfgetc()関数のところでプログラムが停止します。 以下が実行したプログラムです。 #include<stdio.h> void get_name(char name[],int a){ printf("ファイル名を入力してください。\n"); scanf("%s",name); } void open(FILE *fp2,char name[]){ if((fp2=fopen(name,"r"))==NULL){ printf("ファイルオープンエラー"); } } int count(FILE *fp3){ int ch=0; int count=0; if(fp3==NULL){ printf("error"); } while((ch=fgetc(fp3))!=EOF){ if(ch=='\n'){ count++; } } printf("TEST"); fclose(fp3); return(count); } int main (void){ FILE *fp; char fname[30]; get_name(fname,30); open(fp,fname); printf("%d",count(fp)); return(0);} ファイル名を入力してください。ファイル名を入力、プログラム停止です。 '\n'を数えれるようにしてください。御指摘お願いします。

  • C言語 単語を取得するプログラム

    ファイルからアルファベットをスペース等で区切って取得するプログラムを作成しているのですが、デバグがうまくいきません。 どの部分がプログラム的におかしいか、どうすればよいか教えていただけませんでしょうか。 テキスト I have a pen. if you have a pen, please lend me your pen. abc, def.ghi jkl mno pqr..,stu vwx .yz ソースプログラム #include<stdio.h> #include<string.h> int word(char data[],FILE *fp){ char c; int n=0; data[0]='\0'; while((c=fgetc(fp))!=EOF){ if(c!=' ' && c!=',' && c!='.'){ n=strlen(data); data[n]=c; data[n+1]='\n'; } else return(n); } return(0); } int main(){ FILE *fp; char data[30]; fp=fopen("test.txt","r"); if((fp = fopen("test.txt","r"))==NULL){ printf("no file\n"); exit(1); } while((word(data,fp)!=0)){ printf("%s \n",data); } fclose(fp); return(0); }

  • C言語 iMacでのファイル入出力

    #include <stdio.h> int main() { FILE *fp; fp=fopen("test.txt","w"); if (fp==NULL){ perror("ファイル・オープンに失敗しました\n"); return -1; }else printf("ファイルを正常に開きました\n"); fprintf(fp,"これが初めてのファイル入出力です\n"); if (fclose(fp)!=0){ perror("ファイル・クローズに失敗しました\n"); return -1; }else printf("ファイルを正常に閉じました\n"); return 0; } これを実行してもどこにもtest.txtというファイルがありません。 同じプログラムをwinでも実行してみたところ正常にファイルが作られました。 mac初心者なもんで、どうすればいいのでしょうか?

  • テキスト→配列化→ソートをしたいのですが

    テキストファイル:test.txt 内容:カンマで区切られた数値で最大20個 を読み込んで配列に組み込んでその配列を昇順ソートする。 と言うC言語の課題が内定先の企業より出題されたのですが 今まではC#やデータベース中心だったので 全く解らず困っています。 #include <stdio.h> int main(void) { /* ファイルポインタ */ FILE *fp; int f; fp = fopen( "test.txt", "r" ); if( fp == NULL ) { puts( "test.txtが開けません" ); return 1; } while( 1 ) { f = fgetc( fp ); if( ferror( fp ) ) { /* fgetc関数に対するエラーチェック */ puts( "読み込み中にエラーが発生しました" ); fclose( fp ); return 1; } else if( feof( fp ) ) { break; } printf( "%c", f ); } printf( "\n" ); fclose( fp ); return 0; } } 他のサイト等を参考にファイルを読み込むまでは出来たのですが そこから先が全くわかりません・・・・orz どうかよろしくお願いしますm(_ _)m

  • 探索アルゴリズム

    テキストファイルを読み込んで、該当する文字列を含む行を表示するというプログラムを作りたいのです。ファイルを読み込むことはできるのですが、該当する文字列を含む行を表示するやり方がわかりません。どなたか助けてもらえないでしょうか? 一応私が作ってみたプログラムはこんな感じになったんですけど・・・ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {  FILE *fp;  char ch;  if( argc != 3)  {  printf(" 使用法 : <プログラム名> <ファイル名> <文字> \n");  return -1;  }  if((fp = fopen(argv[1],"r")) == NULL)  {  printf("ファイルを開くことができません\n");  return -1;  }  while(( ch = fgetc(fp)) != EOF)  if(ch == *argv[2])  {  printf("%cが見つかりました\n",ch);  break;  }  fclose(fp);  return 0; }

  • ファイル処理について

    大学の課題なのですが、何度取り組んでもエラーになるため、間違いのご指摘、または正答を教えていただけないでしょうか。 問題は以下のものです。 【問題】 ファイルから整数を読み込み,その値によってfpの読み込み位置をかえ,何度目の読み込みで0を読み込んだかを表示するプログラムを作成せよ. ファイルの内容の例 2,4,0, fpの読み込み位置を変えるにはfseekという関数を利用する. fseekの使い方: 現在の読み取り位置xだけずらすには, fseek(ファイルポインタ, x, SEEK_CUR); と記述する. STEP 1 データを一区切りで読み取る("2,"や"-4,"などの整数とコンマの組) 2 読み取ったデータに応じてfpを移動させる("2,"なら2移動,"-4,"なら-4移動) 3 0を読むまで繰り返す +++++*+++++fseek-exercise.c+++++*+++++ #include <stdio.h> int main(void){ FILE *fp; int c; int i; int count=0; char filename[60]; printf("ファイル名 :"); scanf("%s",filename); //ファイルを開く // (* ここに解答を書き加える *) while(1){ printf("読み込み前 : %ld\n",ftell(fp)); //fpから値を読む // (* ここに解答を書き加える *) printf("読み込んだ値は%dです\n",c); printf("読み込み後 : %ld\n\n",ftell(fp)); //読み込み位置をずらす // (* ここに解答を書き加える *) } printf("%d回目です.",count); fclose(fp); return(0); } // 以上になります。 自分で作ったプログラムは以下のようになりました。 #include <stdio.h> int main(void){ FILE *fp; int c; int i; int count=0; char filename[60]; printf("ファイル名 :"); scanf("%s",filename); //ファイルを開く // fp = fopen(filename,"r"); if(fp == NULL){ printf("cannot open\n"); exit(1); } while(1){ printf("読み込み前 : %ld\n",ftell(fp)); //fpから値を読む // c = fgetc(fp); printf("読み込んだ値は%dです\n",c); printf("読み込み後 : %ld\n\n",ftell(fp)); //読み込み位置をずらす // if(c > '0' || c< '9'){ i = atoi(&c); count++; if(i == 0){ break; } fseek(fp,i,SEEK_CUR); } } printf("%d回目です.",count); fclose(fp); return(0); } // どこを訂正していいのかわかりません。 どうぞ、よろしくお願いいたします。

  • プログラムの異常終了

    TEST2とコマンドプロンプトに表示された後、異常終了します。 以下が実行したプログラムです。 #include<stdio.h> void get_name(char **f_name2){ printf("ファイル名を入力"); scanf("%s",*f_name2); } int count_num(FILE *fp){ int ch =0; int count=0; while((ch=fgetc(fp))!=EOF){ if(ch>0&&ch<9){ count++; } } return(count); } int main (void){ char *fname; FILE *fp; get_name(&fname); if((fp=fopen(fname,"r"))==NULL){ printf("ファイルオープンエラー"); }else{ printf("%d\n",count_num(fp)); } fclose(fp); printf("TEST2\n"); return(0); } textc13-7.exeは動作を停止しました。と表示があります。正常に終了したいので、 御指摘お願いします。

専門家に質問してみよう