locked
引数を取得@Windows8 RRS feed

  • 質問

  • VisualC# 2012 ExpressEditionで、Windows8で開発しています。デスクトップ用のソフトです。
    従来の
    VisualC# 2010 ExpressEditionで、Windows7までの環境では、
    string[] args = Environment.GetCommandLineArgs();
    で起動時の引数を取得できました。
    2012では、これがエラーとなります。
    どのようして取得したらよいのでしょう?
    よろしくご教示ください。
    • 移動 星 睦美 2013年6月13日 2:48 Visual C# フォーラムから移動
    2013年6月10日 6:01

回答

  • > 引数を渡す手段がないとは、…。

    はい、ありません。
    Windows ストア アプリでそのような動作に使える機能としては、File activation (ファイル アクティベーション)やProtocol activation (プロトコル アクティベーション)といった「コントラクト」が用意されています。

    ご参考までに:
    「コントラクト」でMetroスタイル・アプリのサンドボックスを乗り越える!  ―― アプリを連携させる新しい仕組みを理解しよう! ――
    http://www.atmarkit.co.jp/fdotnet/chushin/readyforwin8app_02/readyforwin8app_02_01.html


    biac [ http://bluewatersoft.cocolog-nifty.com/ ]

    2013年6月13日 3:50

すべての返信

  • 何のエラーが発生したのでしょうか?
    2013年6月10日 6:26
  • ご参考ですが、下記のコードを win8 pro, 64bit で正常な動作を確認できました。

    このような簡単なコードでもエラーが発生しますか?

    using System;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication12
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string[] args = Environment.GetCommandLineArgs();
    
                foreach (var item in args)
                {
                    // Windows 8 Pro 64bit にて検証済み
                    // xxx.exe a b とコマンドプロンプトより実行すると、
                    // "xxx.exe", その次に "a", その次に "b" のメッセージが表示される
                    MessageBox.Show(item);  
                }
            }
        }
    }
    • 編集済み kentahoga 2013年6月10日 8:33 文章修正
    2013年6月10日 8:32
  • たいへん失礼しました。
    まず大きな事実誤認がありました。

    質問していたのはストアアプリでした。
    区別がついていませんでした。

    エラーは、
    System.EnvironmentにGetCommandLineArgsの定義がありません、でした。

    もうすこし詳しくお話しすると次のようになります。
    田中達彦のブログ
    http://blogs.msdn.com/b/ttanaka/
    で、縦書きの電子書籍ビューアーを配布していらっしゃいます。
    これは、テキストを決め打ちで読み込んでいるので、起動時に引数で異なるデータを読み込みたいと考えました。

    ただ、これでコンパイルしたexeは、単純にデスクトップから起動しようとすると、(これまでは、デバッグモードでしか起動していなかったので、区別できていませんでした)、
    「このアプリケーションはアプリコンテナーのコンテキストでのみ実行できます」と表示して実行できません。
    とすると、ひょっとして、引数での実行はそもそもできないものなのかも。

    これのデータの読み込み部分は、

            public async Task<bool> LoadText()        {
                StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("test.txt");
          HonbunText = await FileIO.ReadTextAsync(file, Windows.Storage.Streams.UnicodeEncoding.Utf8);
                // これを入れると、ファイルをちゃんと読めないことが激減する
                TestText.Text = HonbunText.Substring(0, 1);
                return true;
            }

    というところなので、この"test.txt"に、argsで引数を入れれば任意のファイルを読み込むことができるかと思いましたが、そういうものではないのでしょうか。

      string[] args = System.EnvironmentにGetCommandLineArgs();
                StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(args[0]);

    2013年6月10日 11:19
  • 利用条件をきちんと読んでいますか?

    - 作成するアプリは1作品ごとに作成し、複数の作品をまとめたアプリを作成しないこと。(判定基準としては、1つのテキストファイルの内容のみを表示させるアプリであること)
    - 本テンプレートまたはプロジェクト ファイルを使用または応用、または改変し、汎用的なビューワーを作成しないこと。すなわち、ユーザーが任意のファイルを選択し、表示させることができる機能を実装しないこと。


    アプリの起動引数・コントラクトなども、前者の条件も踏まえて考えればアウトだと、私は思っています。
    学習目的で外からファイルをもらいたいという趣旨だけであれば、新たに自作されるか、そういった縛りのないテンプレートを使ってください。逆に、このテンプレートを汎用化させたいと考えていたのなら今すぐ取りやめてください。
    2013年6月10日 13:06
    モデレータ
  • アプリを作る前に、ストアアプリを使用した経験はあるのでしょうか? 引数を渡す手段はありません。
    2013年6月10日 22:27
  • Azuleanさん、コメントありがとうございます。

    ちゃんと条件には目を通しています。
    Azleanさんは恣意的な部分を引用されていますが、その下に、
    - 上記の条件に合致していれば、本テンプレートまたはプロジェクトファイルを使用または応用、または改変してアプリを作成し、無償、有償を問わず公開できます。
    http://blogs.msdn.com/b/ttanaka/archive/2013/04/11/windows-vol-1.aspx
    とあります。
    この文章は、読みにくいですが、主となる述語は「公開できます。」にあると考えられます。
    いまのところこのソフトを「公開」するつもりはまったくありません。
    いまのところ作っているのが、個人的な範囲の内容だからです。

    そもそもストアアプリのための登録もしていませんし、(標準以外の)ストアアプリを使うのも作るのもはじめてで、作りながら勉強しているところだからです。
    とても公開するようなレベルではない、と考えています。

    学習目的です。
    外からファイルをもらいたい、という意味を理解できません。
    このテンプレートを汎用化させるかどうかとは、無関係だと思います。

    Azuleanさんがご自分のお考えをもつのはご自由ですが、わたしとは考えが違います。強制されるいわれはありません。


    2013年6月13日 0:07
  • 佐祐理さん、コメントありがとうございます。
    (標準以外の)ストアアプリを使うのも作るのもはじめてです。
    Windows8の使用時間は、けっして長くないので、まだぜんぜん経験がありません。3時間×20日くらいとして、ざっくり60時間以下程度です。
    引数を渡す手段がないとは、…。
    驚きました。
    それってすごく不便じゃないのでしょうか?
    2013年6月13日 0:13
  • 質問文を読んだ人が学習目的という意図を読み取れるとでも思っているのでしょうか? 学習目的でも商用目的でも混在しているフォーラムです。未然に警告されて当たり前でしょう。

    「強制されるいわれはありません。」などと書く前に、質問文にきちんと明記すべきです。そもそもストアアプリだとすら書かれていませんし、エラー内容も書かれてません。どれほど酷い質問の仕方をしたのか自覚がないのでしょうか?

    2013年6月13日 0:27
  • ストアアプリ以外でも iOS / Android / Windows Phone などの操作経験はないでしょうか? これらも別段、任意文字列の引数の指定はないと思います。
    # アプリケーションの作成経験がなくても使用経験があればわかるかと。

    ストアアプリでもファイルの関連付けから開かれた場合などは、GetCommandLineArgs() ではなく、ファイルを受け取ることはできます。

    • 回答の候補に設定 佐祐理 2013年6月13日 15:48
    2013年6月13日 0:49
  • 佐祐理さん、コメントありがとうございます。
    まず、目的や意図が質問に不可欠とは思いません。
    目的や意図で、逆に、質問内容が不鮮明になることもあるからです。

    ただし、今回、質問がひどかったのは自覚しております。
    ストアアプリをデスクトッフアプリと間違えるなど、初歩の初歩といわれればそのとおりです…。
    エラー内容もきちんとすべきでした。
    すみません。とても反省しています。

    別の質問でもいただきましたが、iOSとWindows Phoneは使用したことがありません。
    Androidは3カ月ほど触ってみましたが、まだどのように動くのかの心理モデルを構築できていません(なのでほとんど使用していません)。単にカメラで撮影するくらいです。
    使用経験がほぼないので、動作イメージをもてていないのです。

    2013年6月13日 2:21
  • > 引数を渡す手段がないとは、…。

    はい、ありません。
    Windows ストア アプリでそのような動作に使える機能としては、File activation (ファイル アクティベーション)やProtocol activation (プロトコル アクティベーション)といった「コントラクト」が用意されています。

    ご参考までに:
    「コントラクト」でMetroスタイル・アプリのサンドボックスを乗り越える!  ―― アプリを連携させる新しい仕組みを理解しよう! ――
    http://www.atmarkit.co.jp/fdotnet/chushin/readyforwin8app_02/readyforwin8app_02_01.html


    biac [ http://bluewatersoft.cocolog-nifty.com/ ]

    2013年6月13日 3:50
  • 別の質問でもいただきましたが、iOSとWindows Phoneは使用したことがありません。
    Androidは3カ月ほど触ってみましたが、まだどのように動くのかの心理モデルを構築できていません(なのでほとんど使用していません)。単にカメラで撮影するくらいです。
    使用経験がほぼないので、動作イメージをもてていないのです。

    でしたら、アプリ開発をする前に、利用者の視点でスマホ・タブレットなども含めてアプリの操作感などを知っておくことをお勧めします。

    操作したことのない開発者が作ったアプリなど使いづらいだけです。

    2013年6月13日 3:59
  • このあたりの話はOSの設計というかポリシーというか
    そのあたりの概念への理解が必要かもしれません。
    かつてWindowsに限らずデスクトップ用のOSのほとんどは
    OSのシェルがコマンドラインというCUIを持ってました。
    最初はこれしかなかったわけですね。

    ところが昨今のOSはほとんどがGUIになってしまいました。
    この時点でコマンドラインを使ったCUIの重要性の大半は失われたわけですが、
    レガシー機能としてコマンドライン(シェル)は生き残りました。

    ところが、最新のOSではさらに進化して
     1.そもそもキーボードが無いのが普通。
     2.従ってコマンドラインそのものが存在しない(公開されない)。
     3.当然コマンドラインを扱うCUIシェルが無い(公開されない)。

    という状態になりました。
    では、どのようにアプリを起動するかというと、OSによって異なりますが、
     4.Windows8ストアアプリでは「コントラクト」を使ってOSに起動を要請する。
     5.Androidでは「インテント」を使ってOSに起動を要請する。

    方法になりました。これにより、起動には
     7.アプリの起動方法の宣言、
     8.OSによる許可、
     9.ユーザーによる許可

    が必要になったわけですね。
    起動時の詳細なオプションは、これらの「コントラクト」や
    「インテント」へ情報を付加するなどの手段をとる必要があるわけです。
    あたりまえですが、アプリケーションが対象OS上で動く限り、
    そのOSの仕組みへの理解が必要になるわけです。

    まぁ、C言語のmain()の引数がコマンドラインだったりしたわけで、
    今まで各OSともコマンドラインという基本的動作は同じだったのですが、
    今後は、結構な頭の切り替えが必要かもしれません。

    2013年6月13日 4:45
  • この文章は、読みにくいですが、主となる述語は「公開できます。」にあると考えられます。

    権利者側の考えを聞いていないので、私はその考え方に肯定も否定もできません。

    私は、それらが同一の記号での箇条書きで階層関係にないこと、それらの列挙の前に「以下の条件下でのみ使用を許諾します」という書き出しであることから、「公開する場合に対する限定条件」とは限らない可能性を考えていますので、抵触する恐れがある(グレー)と思っており、利用を避けるか、権利者に確認をとるべき事例だと考えています。ただし、これはあくまで私個人の考えであり、あなたの考え方を否定するものではありません。
    あなたの責任で判断し、行動された結果に対して、何の利益も損害もない立場であるため、あなたが指摘するように私の考えを強制するつもりはありません
    (先の投稿は公開目的である可能性を視野にいれたものであったため、やめるべきだと強く書きました)

    学習目的です。
    外からファイルをもらいたい、という意味を理解できません。
    このテンプレートを汎用化させるかどうかとは、無関係だと思います。

    「ファイルをもらう」という書き方で伝わらなかったのは残念です。これは「共有コントラクトで他のアプリからファイルをもらう」、「関連づけ実行でイベント引数にファイルをもらう」を意図した発言でした。
    biac さんが紹介されているリンク先を参照し、コントラクトによって何を伝達しているかを確認してみてください。ファイル名が渡ってくることはないはずです。

    デスクトップアプリと考え方がかなり異なる世界なので、デスクトップアプリでの手法を使おうとするのではなく、まずはストアアプリの開発入門書や入門者向けのサイトを読んで、どういった世界・思想なのかを学んだ方がよいと思います。
    非同期で処理するとか、ユーザーの明確な許可がなければ実行できないとか、いろいろとあります。
    (コマンドライン引数はユーザーの明確な許可なしに実行できる世界からの入力なので、受け入れていないという考え方もできます)

    2013年6月13日 13:58
    モデレータ
  • biacさん、コメントありがとうございます。
    なるほど…。勉強になります。
    2013年6月13日 14:10
  • 佐祐理さん、コメントありがとうございます。
    操作感を知っておくことはたしかにある程度必要かなとは思います。

    ただ、操作したことのない開発者が作ったアプリが使いづらいだけかどうかには、大いに異論があります。
    劇的に使いやすいかもしれませんし、すくなくとも開発者=ユーザーである限りは、使いやすいようにしか作りませんし。

    そんなこと、この質問には無関係じゃないでしょうか?

    2013年6月13日 14:14
  • 仲澤さん、コメントありがとうございます。
    おっしゃるとおりで、まだ概念を理解しようとしているところなので、そもそも論的なところで、けっこう躓いています。
    Androidはインテントがけっこうおもしろそうだなぁ、とは思いました(いちおう開発環境は構築したことがあります)。
    Windows8ではコントラクトになるのですね。
    ありがとうございます。
    2013年6月13日 14:17
  • Azuleanさん、コメントありがとうございます。
    おっしゃるとおりで、権利者の考えを確認しない段階では、わたしもグレーだと思います。別に自分の立場を正当化したくて、強弁したいわけではないです。
    公開目的かどうかを明示しなかったのをわたしの落ち度とおっしゃるのなら、それはそれで承りますが、わたし以外の質問でも、作ったソフトを公開するか非公開にするか、などを明示していらっしゃる方は、ほとんどいないと思います。

    もちろん、教えを請うている立場ですから、立場をわきまえろ、とおっしゃりたいのかもしれませんが、それは質問-回答というラインが対応してこそではないでしょうか。
    できるだけ正確に質問したいとは思いますし、今回の質問ではいろいろ間違えていて、たいへん申しわけなく思っています。
    ただ、質問以外のことで、強く出られると、わたしも強く返す以外になくなります。なにかを強制されるためにプログラムをしているわけではないからです。

    ファイルをもらう、ということの説明、ありがとうございました。biacさんのリンクや、そもそもでコントラクトについてすこしわかってきたので、本も読んでみます。
    まずはストアアプリの入門書、とおっしゃいますが、それはいちおう4冊ほど所有し、今日さらに1冊購入してぱらぱらとめくってみたところです。
    ただ、たとえば4冊のどれを見ても、目次にも索引にも「引数」というものがなく、とすると引数を使えない、引数という概念がないことはわかるものの、それに代わるものがなになのか、などに関しては、すぐには思いつきません。
    ファイルオープンダイアログを使うのかなぁ、などと考えたのですが、それだと起動してファイルオープンダイアログで選択して、二度手間でめんどうくさいなぁ、と思い、まあ作りながら理解するかとサンプルを参考に触り始めて質問してみた、という状態です。
    ぜひ、今後ともお手柔らかにお願いしたいです。

    2013年6月13日 14:32