FileMaker+Pluginによるファイルリスト作成
ちいさな事からコツコツと、西川きよし系エンジニア丸山です!
FileMaker を拡張したい方向けの内容となっています。
今回のブログでは Windows で FileMaker の機能を拡張するプラグインの開発方法について、ファイルリストを取得するサンプルを作成する事ができたので、そちらを簡単にまとめてご紹介したいと思います。
プラグインってなに?
プラグインは、FileMaker にインストールする事によって機能を拡張する事ができます。
プラグインはC++言語で作成されているため、
色々な業務システムや、人工知能(AI)、ロボットの制御技術やさまざまな機械の制御や、
IoTなどのデバイスなどと連携出来る事が期待されます。
目的にあったプラグインを作成する事で、より自由に色々な事ができてきます。
プラグイン開発用のSDKをダウンロードする
プラグインの作成に必要なSDKをダウンロードします。SDKとはプラグインを開発するために必要なプログラムや技術文書をまとめたものです。
https://www.claris.com/ja/resources/downloads/ の右下のプラグインのサポートからダウンロードします。
ダウンロードしたSDKの中には、以下の物が入っています。
「Headers」ヘッダーファイル
「Libraries」ライブラリファイル
「MiniExample」サンプルプロジェクト
「README.txt」説明文書
README.txtに開発に必要な環境の記載があります。
・macOS:Xcode12.4を搭載した macOS 11.1
・iOS:Xcode12.4を搭載した iOS 13.2
・Windows:Visual Studio 201715.8を搭載した Windows10
・Linux:CentOS7.7またはUbuntu18とCode :: Blocks 20
今回は、Windows10 のPCを使用して作業を行いますので Visual Studio 2017 をインストールしてみます。
開発環境のインストール
それでは、Visual Studio 2017 をマイクロソフトのサイトからダウンロードします
tps://visualstudio.microsoft.com/ja/vs/express/ からダウンロードします。
無償版の Visual studio Express でも開発できますので、はじめての方はそれでも良いかと思います。
ダウンロードしたインストーラーで Visual Studio 2017 をインストールしてください。
プログラムファイルの作成
ダウンロードしたSDKからサンプルプロジェクトを利用してプログラムを作成していきます。
とりあえず「FMTestPlugIn」の名前で作成したいと思います。
ファイル名、フォルダー名の中の「Mini」の部分を「Test」に変更していきます。
例:「MiniExample」→「TestExample」
「MiniExample」の説明
プラグインを作成するベースとして提供されるプロジェクトファイルです。
処理に必要な基本的なコードが記述されています。
例として、数字を二進数変換するソースが提供されています。
次に「FMTestPlugIn.cbp」以外のファイルをメモ帳で開いて
「FMMiniPlugIn」の所を→「「FMTestPlugIn」に変更していきます。
単純に名称を変えているだけの作業です。なんか良い方法があれば教えてください。
これで Visual Studio で開く準備ができましたので、開いて行きましょう。
ファイル名を変更した、「FMTestPlugIn.sln」を VisualStudio で開きます。
「FMTestPlugIn.sln」をダブルクリックしても、開く事ができるかと思います。
プログラムを修正していきますので、画面右側の「ソリューション エクスプローラー」ウインドウから
「FMTestPlugIn.cpp」をダブルクリックすると、ソースが表示されます。
38行目 「// Exported plug-in ~」の次の行にプログラムを追加していきます。
以下のプログラムを追加します。
#include <filesystem> using std::endl; using std::string; using std::filesystem::directory_iterator; static const char* kFMpi("FMpi"); enum { kFMpi_GetFileListID = 102, kFMpi_GetFileListMin = 1, kFMpi_GetFileListMax = 1 }; static const char* kFMpi_GetFileListName("FMpi_FileList"); static const char* kFMpi_GetFileListDefinition("FMpi_FileList( ファイルパス )"); static const char* kFMpi_GetFileListDescription("指定されたパスのファイル一覧を作成します"); static FMX_PROC(fmx::errcode) Do_FMpi_FileList(short /* funcId */, const fmx::ExprEnv& environment, const fmx::DataVect& dataVect, fmx::Data& results) { fmx::errcode errorResult(960); fmx::TextUniquePtr outText; if (dataVect.Size() >= 1) { const fmx::Data& dat(dataVect.At(0)); char para01[1024]; memset(para01, 0x00, sizeof(para01)); dataVect.AtAsText(0).GetBytes(para01, sizeof(para01)); string filelist = ""; for (const auto & file : directory_iterator(para01)) { if (filelist.empty()) { filelist.append(is_directory(file) ? "dir. " : "file "); filelist.append(" "); filelist.append(file.path().string()); } else { filelist.append("\r\n"); filelist.append(is_directory(file) ? "dir. " : "file "); filelist.append(" "); filelist.append(file.path().string()); } } outText->Assign(filelist.c_str()); results.SetAsText(*outText, dat.GetLocale()); errorResult = 0; } return errorResult; }
プログラムの内容を簡単に説明します。
40~42行 プログラムで使用する関数などを使用できるための宣言文を読み込んだりしています。
44~49行 処理を追加する時に必要な名前などの記述になります。
51~91行 指定されたパスのファイル一覧を作成するプログラム(関数)になります。
57行 引数に何か入っていた場合に処理を行う分岐命令です。
60行~63行 引数からテキストを抽出しています。
67行 引数(ファイルパス)で指定されたフォルダー内のファイル名を取得しています。
69行~81行 変数「filelist」にフォルダーかファイルかの種別とファイル名を入れています。
84行~86行 ファイルリストを実行結果用の変数に格納しています。
90行 戻り値にエラーコードを入れます。正しく取得できた時は87行目で「0」が設定されます。
プログラムを変更したら、次に208行目ぐらいにある
「static fmx::ptrtype Do_PluginInit( fmx::int16 version )」 の変更を行っていきます。
この部分は、FileMaker がプラグインを認識する為にプラグインの機能を登録している部分になります。
この部分を以下の内容に変更してみましょう。
static fmx::ptrtype Do_PluginInit( fmx::int16 version ) { fmx::ptrtype result( static_cast<fmx::ptrtype>(kDoNotEnable) ); const fmx::QuadCharUniquePtr pluginID( kFMmp[0], kFMmp[1], kFMmp[2], kFMmp[3] ); fmx::TextUniquePtr name; fmx::TextUniquePtr definition; fmx::TextUniquePtr description; fmx::uint32 flags( fmx::ExprEnv::kDisplayInAllDialogs | fmx::ExprEnv::kFutureCompatible ); if (version >= k150ExtnVersion) { name->Assign(kFMpi_GetFileListName, fmx::Text::kEncoding_UTF8 ); definition->Assign(kFMpi_GetFileListDefinition, fmx::Text::kEncoding_UTF8 ); description->Assign(kFMpi_GetFileListDescription, fmx::Text::kEncoding_UTF8 ); if (fmx::ExprEnv::RegisterExternalFunctionEx( *pluginID, kFMpi_GetFileListID, *name, *definition, *description, kFMpi_GetFileListMin, kFMpi_GetFileListMax, flags, Do_FMpi_FileList) == 0) { result = kCurrentExtnVersion; } } else if (version == k140ExtnVersion) { name->Assign(kFMpi_GetFileListName, fmx::Text::kEncoding_UTF8 ); definition->Assign(kFMpi_GetFileListDefinition, fmx::Text::kEncoding_UTF8 ); if (fmx::ExprEnv::RegisterExternalFunction( *pluginID, kFMpi_GetFileListID, *name, *definition, kFMpi_GetFileListMin, kFMpi_GetFileListMax, flags, Do_FMpi_FileList) == 0) { result = kCurrentExtnVersion; } } return result;
プログラムの内容を簡単に説明します。
219行、227行 APIのバージョンによって登録方法を変えています。
220行 プラグイン名「FMpi_FileList」を変数に設定しています。
219行 プラグインの説明「FMpi_FileList( ファイルパス ) 」を変数に設定しています。
222行 RegisterExternalFunctionExを使用して、関数をアプリケーションに登録します。
*pluginID プラグインのIDでユニークな4桁の識別子である必要があります。
kFMpi_GetFileListID 作成した関数のIDでユニークな識別子である必要があります。
*name 計算式に表示される関数の名前です。
*definition 計算式に表示される関数の説明文です。
kFMpi_GetFileListMin 関数に必要な最小の値です。
kFMpi_GetFileListMax 関数に必要な最大の値です。
flags 「FMXCalcEngine.h」に説明が記載されているので必要に応じて設定します。
Do_FMpi_FileList 追加する関数名
227行 バージョンが「k140ExtnVersion」の時の関数登録処理です。
「k150ExtnVersion」との違いは、「description」が無い事と「RegisterExternalFunctionEx」が「RegisterExternalFunction」になっている所です。
最後に「FMTestPlugIn.rc」ファイルをメモ帳などで修正します。
「FMTestPlugIn.rc」を選択した状態で右クリック⇒「ファイルを開くアプリケーションの選択」を選びます。
「プログラムを開く」ダイアログから「C++ソースコードエディター」を選択します。
内容が表示されるので
必要に応じて、1.会社名、2.プラグインの説明、4.著作権の表記、5.プラグインファイル名、6.プラグイン名
を変更してください。
3.「InternalName」は44行目「static const char* kFMpi(“FMpi”);」で指定した「FMpi」に変更してください。
これでプログラムの修正は終わりましたので、このプログラムを FileMaker が読み込める様に変換(ビルド)
していきます。
メニューの「プロジェクト」→「FMTestPlugInのプロパティ」を選択します。
「構成プロパティ」→「C/C++」→「言語」を選択して表示される項目の中の「C++言語標準」を「ISO C++17 標準 (/std:c++17)」を選択します。
これは、ファイル一覧を作成する時に必要な設定となり通常は必要ないかもしれません。
赤枠部分が「Release」, 「x64」である事を確認します。
ビルドを行います。メニューより「ビルド」→「FMTestPlugInのリビルド」を選択します。
VisualStudio の出力ウインドウにエラーの表示がなく「正常終了」の文字があればビルド完了です。
ビルドが終了すると「Release」フォルダーの中に「FMTestPlugIn.fmx64」が作成されています。
これがプラグイン本体です。
プラグインに署名を行う方法は以下のブログを参照して設定してください。
https://www.troi.com/plug-in-development/code-signing-filemaker-plugins/
http://fmplugins.idma.nz/index.php?title=Code_Signing
プラグインを次のフォルダにコピーします。
Windows: C:¥users¥ユーザ名¥AppData¥Local¥FileMaker¥FileMaker Pro¥19.0¥Extensions¥
これでプラグインを動かす準備ができました。実際にリストを表示するスクリプトを作成してみます。
FileMaker でリスト表示してみる
FileMaker で新しいファイルを作成します。
作成したプラグインを使える様にするためにメニューバーから「編集」→「環境設定」を選択し、環境設定ダイアログを表示させます。
「プラグイン」タグを選択し「FMTestPlugIn」にチェックを付けます。
「スクリプトワークスペース」を表示し、新規スクリプトを作成します。
「カスタムダイアログを表示」の「計算式の指定」ダイアログを表示させます。
プログラムで指定した「FMpi_FileList( ファイルパス )」が表示されていればOKです。
FileMaker のフォルダーを指定して、結果を表示してみたいと思います。
スクリプトを実行すると、「FileMaker」フォルダーの一覧が取得できている事がわかるかと思います。
まとめ
今回のブログではプラグインをC++言語で作成し、指定したパスのファイル一覧を表示する方法を紹介しました。
難しい部分や分りにくい部分も多かったかもしれませんがC++言語はハードウェアに近い言語ですので色んな可能性が開けるかもしれません、ぜひチャレンジしてみてください。
南九州では焼酎を飲む晩酌の事を、「だれやめ」と言います。
「疲れた」を「だれた」と言いますが、そのだれをやめる(止める)ために一杯
それがだれやめです。宮崎には美味しい焼酎がいっぱいあるので皆さんも宮崎の焼酎で疲れを癒してみてください。
参考
1. プラグイン開発用のSDK
https://www.claris.com/ja/resources/downloads/
2. Visual Studio 2017
https://visualstudio.microsoft.com/ja/vs/express/
3プラグインに署名を行う方法
https://www.troi.com/plug-in-development/code-signing-filemaker-plugins/
http://fmplugins.idma.nz/index.php?title=Code_Signing