[C#] Excelを使ったプログラムとインストーラの作成

C#でExcelファイルを読み書きするプログラムと、そのプログラム(exe)を配布するためのインストーラを作ってみた。

C#でExcelファイルを読み書きするプログラム
何故態々インストーラを作成するのか?

それは、作成したExcelを使ったプログラムは、exeの配布だけでは他のPCでは動かないため。
Excel関連のDLLも一緒に配布する必要がある。

例えば、前に作成したサンプルアプリの場合、配布時は以下のDLLが必要。

  • Microsoft.Office.Interop.Excel.dll
  • Microsoft.Vbe.Interop.dll
  • office.dll
  • stdole.dll

 

⇒これ、後から気づいたけど実は認識誤り(.NET Framework 3.5までの話)。
 .NET Framework 4以降ではDLL配布を不要にする方法がある。
 説明も後記するので最後までちゃんと読んでね。

 

昔のVisual Studioではセットアッププロジェクト(Windows ベースのアプリケーションのmsiインストーラ)を作成する際、必要なDLLを自動で抽出してくれていた。

インストーラ付きで配布するのが嫌という場合、exeと抽出されたDLLだけを他PCにコピーしても動作する。
ただ、インストーラ無しで、抽出されたDLLを勝手に再配布するのはNGかも知れない。
あと、勿論、配布先PCにもMicrosoft Excelをインストールしておく必要はある。

じゃぁ、昔みたいにインストーラを作ればいい。

と、思ったら、、
Visual Studio 2012以降では、セットアップ プロジェクトが無くなり、ウィザードでインストーラ作成(ディプロイメント)することが出来なくなってしまったらしい。

・・・それは困った。

必要なDLLはMSDNとかに載っているかもしれないけど、前と同じような方法ができないか調べてみた。

 

すると、従来のセットアッププロジェクトに代わり、InstallShield Limited Editionを使ってインストーラを作れることが分かった。
でも、InstallShieldって有料じゃなの?

と思ったけど、このLimited Editionってのは簡易版で無料らしい。

ただ、無料版のVisual Studio Expressでは使えず、Visual Studio Professional以降じゃないと、InstallShield Limited Editionは使えないようだ。

 

という事で、おさらいも兼ねてVisual Studio 2013を使ってExcelを使ったプログラムと、インストーラをInstallShieldで作ってみることにした。

 
 

Excel用のプログラム作成

まずは、C#でExcelを使ったプログラムを作成。
exeの作成方法は、ほぼ前回と同じ。

  1. Visual Studio 2013を起動。
  2. [ファイル]→[新規作成]→[プロジェクト]メニュー選択。
    [ファイル]→[新規作成]→[プロジェクト]メニュー選択

  3. [新しいプロジェクト]ダイアログが開くので、左側ツリーで[テンプレート]→[Visual C#]を選択し、右側リストから[Windows フォーム アプリケーション]を選択し[OK]ボタン押下。
    [新しいプロジェクト]ダイアログ

  4. 画面右上の[ソリューション エクスプローラー]ペインにある「参照設定」を右クリックし、ポップアップメニュー「参照の追加」を選択。
    ポップアップメニュー「参照の追加」

  5. [参照マネージャー]ダイアログの左側ツリーから[COM]→[タイプ ライブラリ]を選択し、右側リストから[Microsoft Excel *.* Object Library]のチェックボックスをONにし[OK]ボタン押下。
    [Microsoft Excel *.* Object Library]

  6. ソリューション エクスプローラーの[参照設定]配下に、以下のオブジェクトが追加されたことを確認する。
    • Microsoft.Office.Core
    • Microsoft.Office.Interop.Excel
    • VBIDE

    参照設定

  7. Form1のGUI編集で、TextBoxとButtonコントロールを以下のような感じで配置する。
    GUI編集

  8. フォーム(Form1)と、実行ボタン(button1)をそれぞれダブルクリックし、空のForm1_Loadと、button1_Clickイベントを作成しておく。
    private void Form1_Load(object sender, EventArgs e)
    {
    
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
    
    }
    
  9. Form1.csを編集し、以下のようなコードを書く。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            private static string fileName = 
                Directory.GetCurrentDirectory() + "\\sample.xlsx";
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                textBox1.ReadOnly = true;
                textBox1.Text = fileName;
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                this.Cursor = Cursors.WaitCursor;   // マウスカーソルを砂時計
                Excel.Application oExcelApp = null; // Excelオブジェクト
                Excel.Workbook oExcelWBook = null;  // Excel Workbookオブジェクト
                try
                {
                    oExcelApp = new Excel.Application();
                    oExcelApp.DisplayAlerts = false; // Excelの確認ダイアログ表示有無
                    oExcelApp.Visible = false;       // Excel表示有無
                    // Excelファイルをオープンする(第一パラメタ以外は省略可)
                    oExcelWBook = 
                        (Excel.Workbook)(oExcelApp.Workbooks.Open(
                            fileName,      // Filename
                            Type.Missing,  // UpdateLinks
                            Type.Missing,  // ReadOnly
                            Type.Missing,  // Format
                            Type.Missing,  // Password
                            Type.Missing,  // WriteResPassword
                            Type.Missing,  // IgnoreReadOnlyRecommended
                            Type.Missing,  // Origin
                            Type.Missing,  // Delimiter
                            Type.Missing,  // Editable
                            Type.Missing,  // Notify
                            Type.Missing,  // Converter
                            Type.Missing,  // AddToMru
                            Type.Missing,  // Local
                            Type.Missing   // CorruptLoad
                    ));
                    Excel._Worksheet oWSheet = 
                        (Excel._Worksheet)oExcelWBook.ActiveSheet;
                    // セルA1の値を取得
                    MessageBox.Show("セルA1の値:" + oWSheet.Cells[1, 1].Value);
                    // セルA2に更新時刻を書き込み
                    oWSheet.Cells[2, 1] = DateTime.Now.ToString("HH時mm分ss秒");
                    Excel.Range oRange = oWSheet.Cells[2, 1];   // セル選択
                    oRange.Font.Size = 8;
                    oRange.Font.Name = "MS 明朝";
                    oRange.Font.Color = 0xFF0000;
                    oRange.Interior.Color = 0x44FFFF;
                    // [Microsoft Excel - 互換性チェック]ダイアログの表示有無
                    oExcelWBook.CheckCompatibility = false;
                    oExcelWBook.SaveAs(fileName);    // Excel保存
                    MessageBox.Show(
                        "保存しました。",
                        Application.ProductName,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }
                catch (FileNotFoundException ex)
                {
                    MessageBox.Show(
                        "Excelファイルの操作に失敗しました。\n\n" +
                        ex.Message,
                        Application.ProductName,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                }
                catch (System.Runtime.InteropServices.COMException ex)
                {
                    MessageBox.Show(
                        "Excelファイルの操作に失敗しました。\n\n" +
                        ex.Message,
                        Application.ProductName,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                }
                finally
                {
                    if (oExcelWBook != null)
                    {
                        oExcelWBook.Close(Type.Missing, Type.Missing, Type.Missing);
                        oExcelApp.Quit();
                    }
                }
                this.Cursor = Cursors.Default;  // マウスカーソルを戻す
            }
        }
    }
    

    ソースコード

  10. 読み込み&書き込みするためのExcelファイルを用意。
    Excelで”sample.xlsx”を新規作成し、セルA1に適当な文字を書いて保存しておく。
    Excelファイルを用意

  11. プログラムをビルドして実行。(exeと同じフォルダにsample.xlsxを用意)
    プログラムをビルドして実行

  12. 実行すると、バックグラウンドでExcelが起動され、セルA1に書いた値が表示される。
    セルA1に書いた値が表示される

  13. 再び”sample.xlsx”を開いてみると、セルA2が黄色(青文字)になり、日時が書きこまれている。
    "sample.xlsx"を開いてみる
    これで、サンプルプログラムは完成。

 

で、今回は更にアプリ配布用のインストーラも作ってみる。

 
 

InstallShield Limited Editionのインストール

インストーラ作成のために、まずはInstallShieldのインストールを行う。

  1. 上記サンプルプログラムを開いておく。
    (サンプルじゃなくてもいいので、インストーラ作成したい何かしらのソリューションを開いておく)

  2. [ファイル]→[追加]→[新しいプロジェクト]メニュー選択。
    [ファイル]→[追加]→[新しいプロジェクト]メニュー選択

  3. [新しいプロジェクトの追加]ダイアログで、左側ツリーから[その他のプロジェクトの種類]→[セットアップと配置]を選択。
    更に、”InstallShield Limited Edition の有効化”を選択し[OK]ボタン押下。
    [新しいプロジェクトの追加]ダイアログで、左側ツリーから[その他のプロジェクトの種類]→[セットアップと配置]を選択

  4. Webページが開かれるので、そのページ内の「手順 2: ダウンロード Web サイトにアクセスします。」リンクをクリック。
    「手順 2: ダウンロード Web サイトにアクセスします。」リンクをクリック

  5. 下記入力フォームに必要な情報を入力し[Download Now]をクリック。
    [Download Now]をクリック

  6. シリアルナンバーが表示されるのでメモっておく。メールでも届くけど。
    シリアルナンバー

  7. [Download]ボタンをクリック。
    ファイルサイズは約60MB。
    [Download]ボタンをクリック

  8. ダウンロードした”InstallShield2013LimitedEdition.exe”を実行。
    ウィザードの指示通りインストール。
    InstallShield2013LimitedEdition

    ウィザード

    ウィザード

    ウィザード

    ウィザード

    ウィザード

  9. インストール完了。
    インストール完了

  10. Visual Studioを起動中の場合は一旦終了してから、再びサンプルプログラムのソリューションを開く。
  11. 再び[ファイル]→[追加]→[新しいプロジェクト]メニュー選択。
    [ファイル]→[新規作成]→[プロジェクト]メニュー選択

  12. [新しいプロジェクトの追加]ダイアログが開かれる。
    今度はリストに”InstallShield Limited Edition Project”が追加されているので、これを選択し[OK]ボタン押下。
    [新しいプロジェクトの追加]ダイアログ

  13. 評価を続けるか、トライアルライセンスをアクティベートするか聞かれるので、
    “Activate or Register for free copy of InstallShiled”を選択し[Next]ボタン押下。
    トライアルライセンスをアクティベート

  14. さっきダウンロード時にメモったシリアルナンバーを入力し[Activate]ボタン押下。
    [Activate]ボタン押下

    待ち。
    待ち

    完了。
    完了

  15. 完了すると、Visual Studioの方にセットアップのプロジェクトが追加される。
    セットアップのプロジェクトが追加される

インストーラの作成

で、いよいよアプリ配布用のインストーラを作成してみる。

上記の続きから。

  1. 基本的に、インストーラーの作成は、この画面下にあるアイコンを左から順に設定していくことになる。
    インストーラーの作成

  2. まずは、”Application Infomation”をクリック。
    "Application Infomation"をクリック

  3. ついでに、インストーラを日本語化するため、左側メニューの[General Infomation]をクリック。
    [General Infomation]をクリック

    [Yes]を選択。
    [Yes]を選択

  4. 一覧の[Setup Language]で”Japanese: 日本語”を選択。
    そして[General Infomation]タブを閉じる。
    [Setup Language]で"Japanese: 日本語"を選択

  5. アプリケーションの情報(会社名、アプリケーション名、アプリケーションのバージョン、Webアドレス)を入力する。
    アプリケーションの情報

  6. 次、”Installation Requirements”をクリック。
    インストール要件を指定する。
    "Installation Requirements"をクリック

  7. 次、”Installation Architecture”をクリック。
    アーキテクチャを設定するらしいが、InstallShield Limited Editionでは変更不可っぽい(鍵アイコン)のでそのまま。
    "Installation Architecture"をクリック

  8. 次、”Application Files”をクリック。
    追加するファイルを指定する。
    まずは、アプリ本体を追加するため、[Add Project Outputs]ボタンを押下し、”プライマリ出力”をチェックし[OK]押下。
    "Application Files"をクリック

  9. あと、今回のサンプルではExcelファイルを使うので、これを追加するため、[Add Files]ボタンを押下。
    ファイルを開くダイアログで、”sample.xlsx”を選択。
    [Add Files]ボタンを押下

  10. [INSTALLDIR]配下に、2つのファイルが追加されたことを確認する。
    [INSTALLDIR]配下に、2つのファイルが追加されたことを確認

  11. 次、”Application Shortcuts”。
    "Application Shortcuts"

  12. [New]ボタンを押下し[Browser for a Destination File]ダイアログを開く。
    [Browser for a Destination File]ダイアログを開く

  13. 以下のファイルを選択し[Open]ボタン押下。
    ProgramFilesFolder
     OsadaSoft
      Excelサンプルプログラム
       WindowsFormsApplication1.プライマリ出力
    [Open]ボタン押下

  14. 今回はスタートメニューとデスクトップにショートカットを作成することにする。
    一覧に追加された”Built”を選択し、[Create shortcut in Start Menu]と、[Create shortcut on Desktop]をチェックする。
    スタートメニューとデスクトップにショートカットを作成

  15. 次、”Application Registry”。
    今回はレジストリ操作しないため変更なし。
    "Application Registry"

  16. 最後、”Installation Interview”。
    "Installation Interview"

  17. そしてプロジェクトをビルドする。
    プロジェクトをビルドする

    って、ビルドエラーが出る。
    ビルドエラー

    ISEXP : error : -3204: Cannot extract icon with index 0 from file ~\WindowsFormsApplication1\WindowsFormsApplication1\bin\Release\WindowsFormsApplication1.exe.
    

    どうも作成したサンプルプログラム側に、アイコンを設定していないことが原因らしい。
    プロジェクトエクスプローラーから、、サンプルプログラム(WindowsFormsApplication1)を右クリックし[プロパティ]ポップアップメニューを選択。
    そして、以下の[アイコンとマニフェスト]を選択し、[アイコン]欄に適当なアイコンを指定する。
    [アイコン]欄に適当なアイコンを指定する

    上記設定後、ソリューションをリビルド。
    ソリューションをリビルド
    するとビルドエラーが消える。

    ビルドが完成し、以下のフォルダ配下に”setup.exe”が作成されている。
    ¥WindowsFormsApplication1¥Setup2¥Setup2¥Express¥SingleImage¥DiskImages¥DISK1
    "setup.exe"が作成されている

 
 

インストールしてみる

出来上がったインストーラがちゃんと動くかテストしてみる。

  1. setup.exeを実行。
    setup.exeを実行

  2. 起動中。
    ちゃんとInstallShield形式だ。

    インストールの準備
    インストールの準備をしています。

  3. InstallShield ウィザードへようこそ
    InstallShield ウィザードへようこそ

  4. 使用許諾契約
    使用許諾契約

  5. ユーザー情報
    ユーザー名、所属の入力欄表示されてる。
    ユーザー情報

  6. [インストール]ボタンを押下。
    [インストール]ボタン

  7. 完了。
    完了

ちゃんとデスクトップのショートカットも作成されていて、実行もちゃんとできている。
デスクトップのショートカット

# サンプルアプリは固定フォルダしかアクセスできない作りだったため、ホントは修正する必要があるけど、とりあえず、インストーラ作成の話と直接関係ないので修正は割愛。

これで、一応、他のPCでも動作する。

これでOKじゃん。

…って、

あれ?

なんで?

そういやぁ、Office関連のDLLって配布しないとダメじゃん。

  • Microsoft.Office.Interop.Excel.dll
  • Microsoft.Vbe.Interop.dll
  • office.dll
  • stdole.dll

↑これらDLLはインストーラの中に含まれていないみたいだけど、何で動いてんの?

というか、そもそもDLLは4つだけでいいのか?
調べてみると、

http://msdn.microsoft.com/ja-jp/library/15s06t57.aspx

Office プロジェクトから Microsoft Office アプリケーションの機能を使用するには、アプリケーションのプライマリ相互運用機能アセンブリ (PIA: Primary Interop Assembly) を使用することが必要です。

で、そのPIAはどこにあるかというと、どうやら以下のフォルダに存在するらしい。

例)
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Visual Studio Tools for Office\PIA
\Common
	adodb.dll
	Extensibility.dll
	Microsoft.mshtml.dll
	microsoft.stdformat.dll
	msdatasrc.dll
	stdole.dll
\Office14
	ja\
		Microsoft.Office.Interop.Excel.xml
		Microsoft.Office.Interop.Outlook.xml
		Microsoft.Office.Interop.Word.xml
		office.xml
	IPDMCTRL.dll
	Microsoft.Office.InfoPath.Permission.dll
	Microsoft.Office.interop.access.dao.dll
	Microsoft.Office.Interop.Access.dll
	Microsoft.Office.Interop.Excel.dll
	Microsoft.Office.Interop.Graph.dll
	Microsoft.Office.Interop.InfoPath.dll
	Microsoft.Office.Interop.InfoPath.SemiTrust.dll
	Microsoft.Office.Interop.InfoPath.Xml.dll
	Microsoft.Office.Interop.MSProject.dll
	Microsoft.Office.Interop.OneNote.dll
	Microsoft.Office.Interop.Outlook.dll
	Microsoft.Office.Interop.OutlookViewCtl.dll
	Microsoft.Office.Interop.PowerPoint.dll
	Microsoft.Office.Interop.Publisher.dll
	Microsoft.Office.Interop.SharePointDesigner.dll
	Microsoft.Office.Interop.SharePointDesignerPage.dll
	Microsoft.Office.Interop.SmartTag.dll
	Microsoft.Office.Interop.Visio.dll
	Microsoft.Office.Interop.Visio.SaveAsWeb.dll
	Microsoft.Office.Interop.VisOcx.dll
	Microsoft.Office.Interop.Word.dll
	Microsoft.Vbe.Interop.dll
	Microsoft.Vbe.Interop.Forms.dll
	Office.dll
\Office15
	ja\
		Microsoft.Office.Interop.Excel.xml
		Microsoft.Office.Interop.Outlook.xml
		Microsoft.Office.Interop.Word.xml
		office.xml
	Microsoft.Office.InfoPath.Permission.dll
	Microsoft.Office.interop.access.dao.dll
	Microsoft.Office.Interop.Access.dll
	Microsoft.Office.Interop.Excel.dll
	Microsoft.Office.Interop.Graph.dll
	Microsoft.Office.Interop.InfoPath.dll
	Microsoft.Office.Interop.InfoPath.SemiTrust.dll
	Microsoft.Office.Interop.InfoPath.Xml.dll
	Microsoft.Office.Interop.MSProject.dll
	Microsoft.Office.Interop.OneNote.dll
	Microsoft.Office.Interop.Outlook.dll
	Microsoft.Office.Interop.OutlookViewCtl.dll
	Microsoft.Office.Interop.PowerPoint.dll
	Microsoft.Office.Interop.Publisher.dll
	Microsoft.Office.Interop.SharePointDesigner.dll
	Microsoft.Office.Interop.SharePointDesignerPage.dll
	Microsoft.Office.Interop.SmartTag.dll
	Microsoft.Office.Interop.Visio.dll
	Microsoft.Office.Interop.Visio.SaveAsWeb.dll
	Microsoft.Office.Interop.VisOcx.dll
	Microsoft.Office.Interop.Word.dll
	Microsoft.Vbe.Interop.dll
	Microsoft.Vbe.Interop.Forms.dll
	Office.dll

それで、これらDLLのうち、どれを配布すればいいのか?

http://msdn.microsoft.com/ja-jp/library/15s06t57.aspx
にExcelの場合はコレとかいろいろ書いてある。

調べてみると、やっぱ4つのDLLだけで良さそうだ。

でも、なんでインストーラでDLL入れてないのに他のPCで動くんだ?

再び調べてみた。

すると、こんな記事も。
http://msdn.microsoft.com/ja-jp/library/ee317478.aspx

COM オブジェクトを参照するアプリケーションに型情報を埋め込むと、プライマリ相互運用機能アセンブリ (PIA: Primary Interop Assembly) を使用する必要がなくなります。

ん?
なんか、この方法だとDLL配布しなくても動くということ?

「アプリケーションに型情報を埋め込む」ってのがよく分からないんで、今回作ったC#プロジェクトを確認してみる。

相互運用機能型の埋め込み
参照追加のときに追加された以下の以下の3つのオブジェクトについて、それぞれプロパティを見てみると「相互運用機能型の埋め込み」なんてのがある。
・Microsoft.Office.Core
・Microsoft.Office.Interop.Excel
・VBIDE

しかも、3つとも「True」だ。

ってことは、DLL配布要らないってことなのか。

素晴らしい!

でも何で?

昔、こんな感じでExcelにアクセスするプログラムを作ったとき、DLLが無いと動かなかった筈。
で、そのために、態々面倒なmsiのインストーラを作って配布していたのに。

どうやら、.NET Framework 4以降から使える「相互運用機能型の埋め込み」プロパティが
使えるようで、これをTrueに設定しておけば、DLLなしで配布できるようだ。

念のため、対象の.NET Frameworkを調べてみる。
プロジェクトを右クリックし「プロパティ」を選択し、「アプリケーション」タブで「対象フレームワーク」を確認。
「.NET Framework 4.5」となっている。
対象フレームワーク

ちなみに、Visual Studio 2013ではフレームワークを「.NET Framework 2.0」~「.NET Framework 4.51」の範囲で選べる。
対象フレームワーク

フレームワークとOS、IDEの関係は以下のような感じ。
http://msdn.microsoft.com/ja-jp/library/bb822049(v=vs.110).aspx

.NET Framework OS標準 IDE
4.5.1 Windows 8.1
Windows Server 2012 R2
Visual Studio 2013
4.5 Windows 8
Windows Server 2012
Visual Studio 2012
4   Visual Studio 2010
3.5 Windows 7 SP1
Windows Server 2008 R2 SP1
Visual Studio 2008
3.0 Windows Vista SP2
Windows Server 2008 R2 SP1
Windows Server 2008 SP2
Visual Studio 2005
2.0 Windows Server 2008 R2 SP1
Windows Server 2008 SP2
Windows Server 2003
Visual Studio 2005
1.1   Visual Studio .NET 2003
1.0   Visual Studio .NET

今回のExcel用プログラムの場合、.NET Framework 4以降からDLL配布なしで使えるということと、
今回のプログラムでは、.NET Framework 4.5の新機能を使用していないため、.NET Framework 4で作って配布した方が良さそう。

もうサポート外なので使っている人はいないと思うけど、Windows XPでも.NET Framework 4までならインストール可能。

あと、もう1つおまけ。
IDEとFrameworkとOfficeのバージョン関係について、以下のサイトが参考になるかも。
http://blogs.msdn.com/b/office_client_development_support_blog/archive/2012/05/23/offica.aspx

基本的に古いバージョンのExcelで開発した方が互換が保てそうだけど、最新のExcelでも新機能を使わないように注意すれば問題なく使えそう。

いずれにしても、ここら辺はより多くの環境で動作確認した方が良さそうだ。

 
 

まとめ

一生懸命InstallShieldの記事を書いたけれども、結局、C#でExcelを使ったプログラムを作って配布する場合、

  • .NET Framework 4を対象
  • 参照設定で、Microsoft.Office.Core、Microsoft.Office.Interop.Excel、VBIDEを追加
  • 「相互運用機能型の埋め込み」をTrueに設定
  • できれば古いExcel環境で開発 or 新Excel環境の場合は新機能を使用しない

これで、DLL無しで簡単にexe作成&配布がでそう。

 
 


Leave a comment

メールアドレスが公開されることはありません。

CAPTCHA


*