今回は、Windows パソコン において、カスタム URL スキーム を設定して、任意の アプリケーション を起動する方法を載せます。
ちなみに、"カスタム URL スキーム" は、"外部プロトコルリクエスト" とか "プロトコルハンドラ"、"Pluggable Protocol Handler"、"Asynchronous Pluggable Protocols" などの名前で掲載されいる記事が多いようです。 (…情報を探すのに苦労したので参考になれば。。)
目次
今回は、Windows パソコン において、カスタム URL スキーム を設定して、任意の アプリケーション を起動する方法を載せます。
ちなみに、"カスタム URL スキーム" は、"外部プロトコルリクエスト" とか "プロトコルハンドラ"、"Pluggable Protocol Handler"、"Asynchronous Pluggable Protocols" などの名前で掲載されいる記事が多いようです。 (…情報を探すのに苦労したので参考になれば。。)
目次
Blogger に Pocket の "pocket" ボタン を 設置、追加する方法を記載します。 各ページ (投稿) に対する ボタン です。 ここに載せる コード は ブログ テンプレート に対してコピペ で使えるようにしてあります。 表示したい位置へ コピー & ペースト して利用してください。 作業手順手としては次の通りです。
※その他の ソーシャルボタン もまとめて追加する方法は こちら。
※ソースコード は ダブルクリック すると、全選択できます。
Blogger に はてなブックマーク の "B!" ボタン を 設置、追加する方法を記載します。 各ページ (投稿) に対する ボタン です。 ここに載せる コード は ブログ テンプレート に対してコピペ で使えるようにしてあります。 表示したい位置へ コピー & ペースト して利用してください。 作業手順手としては次の通りです。
※その他の ソーシャルボタン もまとめて追加する方法は こちら。
※ソースコード は ダブルクリック すると、全選択できます。
Blogger に google の "+1" ボタン を 設置、追加する方法を記載します。 各ページ (投稿) に対する ボタン です。 ここに載せる コード は ブログ テンプレート に対してコピペ で使えるようにしてあります。 表示したい位置へ コピー & ペースト して利用してください。 作業手順手としては次の通りです。
※その他の ソーシャルボタン もまとめて追加する方法は こちら。
※ソースコード は ダブルクリック すると、全選択できます。
Blogger に facebook の "いいね" ボタン を 設置、追加する方法を記載します。 各ページ (投稿) に対する いいね ボタン です。 ここに載せる コード は ブログ テンプレート に対してコピペ で使えるようにしてあります。 表示したい位置へ コピー & ペースト して利用してください。 作業手順手としては次の通りです。
※その他の ソーシャルボタン もまとめて追加する方法は こちら。
※ソースコード は ダブルクリック すると、全選択できます。
Blogger に twitter の "ツイート" ボタン を 設置、追加する方法を記載します。 各ページ (投稿) に対する ツイート ボタン です。 ここに載せる コード は ブログ テンプレート に対してコピペ で使えるようにしてあります。 表示したい位置へ コピー & ペースト して利用してください。 作業手順手としては次の通りです。
その他の ソーシャルボタン もまとめて追加する方法は こちら。
Blogger に twitter の 「ツイート」、facebook の 「いいね」、google の 「+1」、はてなブックマーク の 「B!」、Pocket の 「Pocket」 ボタン 等、 俗に言う ソーシャルボタン を まとめて 一気 に設置する方法をここでは載せます。 いろいろと方法はあるかと思いますが・・・ここでは、 Blogger の テンプレート を編集して実現する方法です。
([2015/03/15] 本記事ではそれぞれのSNS提供モジュールを利用しています。オリジナルデザインにしたい場合、"Blooger に オリジナルデザイン の ソーシャルボタン を設置する方法" をご参照ください。)
Windows Installer XML (WiX) toolset を 利用して、Internet Explorer 向け アドオン の インストーラー を開発します。 開発した アドオン を エンドユーザー に利用してもらうために必要な処理 ──「コンポーネントの配置」「レジストリ登録」── を実行する インストーラー を作成します。 今回は以前書いた "IE の アドオン 開発" の続編になります。
サンプルコードのダウンロード
(※2013/06/26 WiX3.5 だとコンパイルエラーが起こりました。WiX3.7 以上でお試しください。)
※WiX をまだインストールされていない場合は、以下のサイトからダウンロード & インストールをお願いいたします。
→ WiX Toolset - Download
以前書いた記事 だと、IE 上で動作する ActiveX は作成、検証まではできています。 アドオンはちゃんとできているし動いているけれど、インストーラーを作ることで、次のようなことを提供できるようにしようと思います。
今回のインストーラーでは最低限の機能を提供するにとどめているため、 インストーラーは英語のままだったり、プログラムの追加と削除にアイコンがなかったり、製品名や会社名の表記が不完全だったりする部分があります。 これらはまた時間があるときに…。。
C:\Program Files\WiX Toolset v3.7\bin
"にあります。
ソリューション/プロジェクトを作成しただけだと、.NET Framework のチェック および 画面付きのインストーラーが作れないため、参照設定を追加しています。
WixNetFxExtension.dll
の参照で、 .NET Framework のインストール状況のチェックを行えるようにする拡張機能が利用できるようになります。
WixUIExtension.dll
の参照で、画面付きインストーラーが作れるようになります。
ソースコードは Product.wxs
と Components.wxs
の2ファイルだけです。
Product.wxs
はソリューション作成時にあるファイルの修正を行います。
インストーラーの画面構成、.NET Frameworkインストール状況のチェック、インストール構成(完全 or カスタム or オヌヌメ)、インストールディレクトリ構成を設定します。
Components.wxs
は WiX toolset に付属するツールを利用して自動生成したものを修正します。
実際にインストールするファイル、登録するレジストリ情報を設定します。
Product.wxs
修正前
<?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Product Id="*" Name="SetupProject" Language="1033" Version="1.0.0.0" Manufacturer="" UpgradeCode="a08f60e3-67db-4b13-bc5c-195124554fb1"> <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" /> <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> <MediaTemplate /> <Feature Id="ProductFeature" Title="SetupProject" Level="1"> <ComponentGroupRef Id="ProductComponents" /> </Feature> </Product> <Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="SetupProject" /> </Directory> </Directory> </Fragment> <Fragment> <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --> <!-- <Component Id="ProductComponent"> --> <!-- TODO: Insert files, registry keys, and other resources here. --> <!-- </Component> --> </ComponentGroup> </Fragment> </Wix>
修正後
<?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Product Id="*" Name="Sample Product" Language="1033" Version="1.0.0.0" Manufacturer="Sample Co. Ltd." UpgradeCode="a08f60e3-67db-4b13-bc5c-195124554fb1"> <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" /> <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> <MediaTemplate /> <Feature Id="ProductFeature" Title="SetupProject" Level="1"> <ComponentGroupRef Id="ProductComponents" /> </Feature> <UIRef Id="WixUI_Mondo" /> <PropertyRef Id="NETFRAMEWORK35" /> <Condition Message="This application requires .NET Framework X.Y.">Installed OR NETFRAMEWORK35</Condition> </Product> <Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="SetupProject" /> </Directory> </Directory> </Fragment> </Wix>
"修正前" の XML に対して、以下のような修正を行います。 (すべての修正を行った結果が "修正後" になります。)
//WiX/Product/@Name
//WiX/Product/@Manufacture
//WiX/Product/UIRef
<UIRef Id="WixUI_Mondo" />
//WiX/Product/PropertyRef
//WiX/Product/Condition
<PropertyRef Id="NETFRAMEWORK35" /> <Condition Message="This application requires .NET Framework X.Y.">Installed OR NETFRAMEWORK35</Condition>
//WiX/Fragment[name(child)="ComponentGroup"]
Components.wxs
自動生成結果
<?xml version="1.0" encoding="utf-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Fragment> <DirectoryRef Id="TARGETDIR"> <Directory Id="dir4DBD5D1D35BB67517C2CB9713EA6BB0E" Name="WiX" /> </DirectoryRef> </Fragment> <Fragment> <DirectoryRef Id="dir4DBD5D1D35BB67517C2CB9713EA6BB0E"> <Component Id="cmpDB54D4524917C8B707E5BBF38A699D28" Guid="PUT-GUID-HERE"> <Class Id="{234E6679-2F92-368C-ABD4-89F063D07579}" Context="InprocServer32" Description="Sample.ActiveXPlugIn.IObjectSafetyTLB" ThreadingModel="both" ForeignServer="mscoree.dll"> <ProgId Id="Sample.ActiveXPlugIn.IObjectSafetyTLB" Description="Sample.ActiveXPlugIn.IObjectSafetyTLB" /> </Class> <Class Id="{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}" Context="InprocServer32" Description="Sample.ActiveXPlugIn.MyForm" ThreadingModel="both" ForeignServer="mscoree.dll"> <ProgId Id="Sample.ActiveXPlugIn.MyForm" Description="Sample.ActiveXPlugIn.MyForm" /> </Class> <Class Id="{EBD6E54B-8223-313B-A575-110E1BA8D32C}" Context="InprocServer32" Description="Sample.ActiveXPlugIn.Form1" ThreadingModel="both" ForeignServer="mscoree.dll"> <ProgId Id="Sample.ActiveXPlugIn.Form1" Description="Sample.ActiveXPlugIn.Form1" /> </Class> <File Id="filCC77BD2DCA029040BCFF7EBD663B08E2" KeyPath="yes" Source="SourceDir\WiX\SampleActiveXPlugIn.dll" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="Class" Value="Sample.ActiveXPlugIn.IObjectSafetyTLB" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="Class" Value="Sample.ActiveXPlugIn.IObjectSafetyTLB" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="Class" Value="Sample.ActiveXPlugIn.MyForm" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="Class" Value="Sample.ActiveXPlugIn.MyForm" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="Class" Value="Sample.ActiveXPlugIn.Form1" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="Class" Value="Sample.ActiveXPlugIn.Form1" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> </Component> </DirectoryRef> </Fragment> </Wix>
修正後
<?xml version="1.0" encoding="utf-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Fragment> <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> <Component Id="cmpDB54D4524917C8B707E5BBF38A699D28" Guid="C8BA8C74-F2A4-4A53-9FC4-92CDC7897287"> <Class Id="{234E6679-2F92-368C-ABD4-89F063D07579}" Context="InprocServer32" Description="Sample.ActiveXPlugIn.IObjectSafetyTLB" ThreadingModel="both" ForeignServer="mscoree.dll"> <ProgId Id="Sample.ActiveXPlugIn.IObjectSafetyTLB" Description="Sample.ActiveXPlugIn.IObjectSafetyTLB" /> </Class> <Class Id="{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}" Context="InprocServer32" Description="Sample.ActiveXPlugIn.MyForm" ThreadingModel="both" ForeignServer="mscoree.dll"> <ProgId Id="Sample.ActiveXPlugIn.MyForm" Description="Sample.ActiveXPlugIn.MyForm" /> </Class> <Class Id="{EBD6E54B-8223-313B-A575-110E1BA8D32C}" Context="InprocServer32" Description="Sample.ActiveXPlugIn.Form1" ThreadingModel="both" ForeignServer="mscoree.dll"> <ProgId Id="Sample.ActiveXPlugIn.Form1" Description="Sample.ActiveXPlugIn.Form1" /> </Class> <File Id="filCC77BD2DCA029040BCFF7EBD663B08E2" KeyPath="yes" Source=".\SourceDir\SampleActiveXPlugIn.dll" /> <RegistryValue Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="Class" Value="Sample.ActiveXPlugIn.IObjectSafetyTLB" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="Class" Value="Sample.ActiveXPlugIn.IObjectSafetyTLB" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{234E6679-2F92-368C-ABD4-89F063D07579}\InprocServer32" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="Class" Value="Sample.ActiveXPlugIn.MyForm" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="Class" Value="Sample.ActiveXPlugIn.MyForm" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\InprocServer32" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="Class" Value="Sample.ActiveXPlugIn.Form1" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32\1.0.0.0" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="Class" Value="Sample.ActiveXPlugIn.Form1" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="Assembly" Value="SampleActiveXPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{EBD6E54B-8223-313B-A575-110E1BA8D32C}\InprocServer32" Name="CodeBase" Value="file:///[#filCC77BD2DCA029040BCFF7EBD663B08E2]" Type="string" Action="write" /> </Component> </ComponentGroup> </Fragment> </Wix>
まず、以下の手順でレジストリ登録すべき情報を抽出します。 現状はファイルが1つなので手作業で行うことも不可能ではないですが… ファイル数が多くなると手作業では難しくなるので以下の手順で自動生成がオススメです。
コマンド例
set PATH=%PATH%;C:\Program Files\WiX Toolset v3.7\bin heat file SampleActiveXPlugIn.dll -out Components.wxs
構文
heat file [dllファイル名] -out [出力ファイル名]
自動生成したファイルに対して以下の修正を行います。 すべての修正を行った結果が "修正後" になります。
//WiX/Fragment[DirectoryRef@Id="TARGET"]
//WiX/Fragment/DirectoryRef[@Id="dir4DBD5D1D35BB67517C2CB9713EA6BB0E"]
<ComponentGroup Id="ProductComponents" Direcory="INSTALLFOLDER"> |… </ComponentGroup>
//WiX/Fragment/DirectoryRef/Component/@Guid
//WiX/Fragment/DirectoryRef/Component/File/@Source
//WiX/Fragment/DirectoryRef/Component/RegistryValue
<RegistryValue Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}" Value="" Type="string" Action="write" />
//WiX/Fragment/DirectoryRef/Component/RegistryValue
<RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}" Value="" Type="string" Action="write" /> <RegistryValue Root="HKCR" Key="CLSID\{273737CB-CA7D-45C5-84F6-EF4D5A3D8C79}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}" Value="" Type="string" Action="write" />
Visual Studio を利用している場合、以下の手順でコンパイルできます。 出力先は設定によりますが… デフォルト だと bin\Debug または bin\Release の下になります。
テスト実行する前に、regedit でインストールされる予定のレジストリ情報を削除しておきます。
レジストリの削除が終わると、いざテスト実行です。 [Next] を押していって、作成した アドオン を インストール します。
インストールが完了した後、以下の2点の動作確認を行います。
ブラウザでどのようにページ遷移が行われたかを簡単に記録するためのフィルターを作成します。
このフィルターを利用することで「不適切なページ遷移を拒否できる」とか「ブラウザの戻る機能の無効化」 ができるようになることを目指します。
閲覧履歴をセッションに残すフィルターを作成します。
ここでは Filters
フォルダ & 名前空間を1つ掘って実装しています。
BrowsingHistoryAttribute.cs
namespace SampleMvcApplication.Filters { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; /// <summary> /// 閲覧履歴をセッションに記録するフィルター属性を表します。 /// </summary> public class BrowsingHistoryAttribute : FilterAttribute, IActionFilter { /// <summary> /// 直前に閲覧したURLをセッションに保存するキー文字列 /// </summary> public static string PREVIOUS_URL = "PREVIOUS_URL"; /// <summary> /// 現在要求されたURLをセッションに保存するキー文字列 /// </summary> public static string CURRENT_URL = "CURRENT_URL"; /// <summary> /// アクション結果の実行後に ASP.NET MVC フレームワークによって呼び出されます。 /// </summary> /// <param name="filterContext">フィルター コンテキスト</param> public void OnActionExecuted(ActionExecutedContext filterContext) { } /// <summary> /// アクション結果の実行前に ASP.NET MVC フレームワークによって呼び出されます。 /// </summary> /// <param name="filterContext">フィルター コンテキスト</param> public void OnActionExecuting(ActionExecutingContext filterContext) { // 必要な変数を取得 var httpContext = filterContext.HttpContext; var session = httpContext.Session; var request = httpContext.Request; // POST と Ajax リクエスト は記録しない if (request.HttpMethod == "POST" || request.IsAjaxRequest()) { return; } // リクエストURL を正規化 var url = this.GetNormalizedRequestUrl(httpContext); // 閲覧履歴を更新 session[PREVIOUS_URL] = session[CURRENT_URL]; session[CURRENT_URL] = url; } /// <summary> /// リクエストURLを正規化します /// </summary> /// <param name="httpContext">HTTP コンテキスト</param> /// <returns>正規化された リクエストURL</returns> private string GetNormalizedRequestUrl(HttpContextBase httpContext) { var routeData = System.Web.Routing.RouteTable.Routes.GetRouteData(httpContext); var controllerName = routeData.Values["controller"].ToString().ToLower(); var actionName = routeData.Values["action"].ToString().ToLower(); var queryString = httpContext.Request.QueryString.ToString(); if (string.IsNullOrEmpty(queryString)) { return string.Format("{0}/{1}", controllerName, actionName); } else { return string.Format("{0}/{1}?{2}", controllerName, actionName, queryString); } } } }
フィルターなので FilterAttribute
クラス の継承を行います。
今回のフィルターはできるだけ早いタイミングで実施したいので、IActionFilter
インターフェース の実装を行っています。
.OnActionExecuting
で セッション に対して閲覧履歴を更新しにかかります。
POST と Ajax リクエストは保存しないように処理されています。
.OnActionExecuted
は特に必要な処理がないので何も記述しない空のメソッドになります。
リクエストURLはショートカットされる場合(MapPathに登録されていたり、IndexのようにIISに登録されていたりする場合)があるので、
.GetNormalizedRequestUrl
関数を利用してキチンとしたURLへ再マッピングしなおしています。
この関数にかんする詳細は こちら の記事をご参照ください。
上記ソースコードで記述した属性を利用してみます。 以下のサンプルコードでハイライトされた部分が利用例となります。 Controller クラス に対して属性をつけることで、そのクラスのメソッドすべてに対して履歴を取るようにしています。
サンプルコード
namespace SampleMvcApplication.Controllers { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SampleMvcApplication.Filters; [BrowsingHistory] public class HomeController : Controller { public ActionResult Index() { return this.View(); } public ActionResult Login() { return this.View(); } public ActionResult Index2() { return this.View(); } } }
特定の処理だけ キャッシュ を 無効化 したいけれど、いちいち、そんな処理を書いているのが面倒… という思いから、お手軽に キャッシュ の 無効化 を実現する方法を作ってみました。
無効化する作業としては、以下のソースコードにある NoCacheAttribute
をキャッシュさせたくない操作(メソッド)の属性に設定するだけです。
キャッシュ を 無効化する 属性 NoCacheAttribute
のサンプルコードを以下に記載します。
NoCacheAttribute.cs
namespace SampleMvcApplication.Controllers { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; /// <summary> /// キャッシュを無効化するフィルター属性を表します。 /// </summary> public class NoCacheAttribute : ActionFilterAttribute { /// <summary> /// アクション メソッドの実行後に ASP.NET MVC フレームワークによって呼び出されます。 /// </summary> /// <param name="filterContext">フィルダー コンテキスト</param> public override void OnActionExecuted(ActionExecutedContext filterContext) { // 継承元の処理を実行 base.OnActionExecuted(filterContext); // レスポンスヘッダーにキャッシュ無効化を追加 var response = filterContext.HttpContext.Response; response.Cache.SetCacheability(HttpCacheability.NoCache); } } }
ActionFilterAttribute
クラスを継承した、NoCacheAttribute
クラスを作成します。
すべてのサーバー処理が終わって、クライアントへ配信する直前(OnActionExecuted
)に、キャッシュしないヘッダーを付加する処理を記載します。
この処理により、サーバーからクライアントへのレスポンスヘッダーでは次のようなヘッダーが追加されます。
Cache-Control: no-cache
Expires: -1
Pragma: no-cache
…冒頭で "いちいち、そんな処理を書いているのが面倒…" と書いていますが、実際書く処理は 1行 です。 どちらかと言うと、"コーディングがラクになる" より "可読性が良くなる" が正しいかもしれません。
上記 サンプルコード で書いた コード を利用してみます。
この コード では Test
メソッドで呼ばれる内容が キャッシュ されなくなります。
サンプルコード
[NoCache] public ActionResult Test() { // レスポンス用のサンプルデータを作成 var o = new { Message = "foo-bar", DateTime = DateTime.Now.ToString("r") }; // 作成したデータを返信 return this.Json(o, JsonRequestBehavior.AllowGet); }
この アクションフィルター では、 .cshtml 等に記述された img タグ、link タグ、script タグで後から呼び出されるファイルに対して、 キャッシュ を 無効化 させることはできません。 これらの ファイル も含めて 無効化 したい場合、 web.config の修正をご検討ください(→参考(GUI設定)、参考(XML直編集))。
今回、参考にしたサイトは以下の通りです。
業務アプリを開発していると良く遭遇するこの問題…。 基本的には HTML のトップレベルで対応することで対策が無難と思います。 いわゆるホワイトリスト方式(基本は拒否。許可するものだけリストアップ。)です。
禁止したい機能は以下のようなものを想定しています。
サンプルコード with jQuery
<html> <head> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script type="text/javascript"> // document (トップレベル) に対して処理するところが ポイント $(document).on('mousedown', function (event) { // テキスト選択処理を無効化 return false ; }).on('selectstart', function () { // テキスト選択処理を無効化 return false ; }).on('contextmenu', function (event) { // 右クリックメニュー禁止 return false ; }).on('mousewheel', function (event) { // Ctrl + wheel による拡大縮小禁止 return !event.ctrlKey; }).on('dragover', function (event) { // ドラッグ&ドロップ禁止(テキスト、画像等の D&D によるページ遷移を防ぐ) return false ; }).on('drop', function (event) { // ドラッグ&ドロップ禁止(テキスト、画像等の D&D によるページ遷移を防ぐ) return false ; }); </script> </head> <body> <h1>メロンパン。</h1> </body> </html>
各禁止項目の詳細を以下で詳しく見ていきます。
$(document).on('mousedown', function (event) { return false ; }).on('selectstart', function () { return false ; });
この処理で、必要な処理まで無効になってしまいます。 例えば、テキストボックスにおいてクリックによるキャレット移動、文字列選択が無効になります(下記デモ参照)。 キャレット移動、文字列選択を可能にするためには、有効化したいテキストボックスに対してバブルアップを禁止するようにします(下記サンプルコード参照)。
デモ (テキスト選択 禁止)
この DIV 領域内 はテキスト選択無効。 この領域外から D&D して選択は可能です。 それ故、テキスト選択を完全無効化するためには、 document に対して拒否する処理を記述する必要があります。
テキストボックスの選択可否:
選択不可
サンプルコード (キャレット移動、テキスト選択の許可)
$('#textbox').on('mousedown', function (event) { event.stopPropagation(); }).on('selectstart', function (event) { event.stopPropagation(); });
$(document).on('contextmenu', function (event) { return false ; });
右クリック メニュー (コンテキストメニュー) を明示的に禁止することで、 独自実装を行ったり、別機能を割り当てたりすることができるようになります。
$(document).on('mousewheel', function (event) { return !event.ctrlKey; });
この実装、IE では有効ですが、残念ながら Chrome は正常に禁止できませんでした。。 Firefox、Opera 等は確認していないので不明です。
$(document).on('dragover', function (event) { return false ; }).on('drop', function (event) { return false ; });
ブラウザ の テキストボックス に メモ帳 等からテキストを D&D したり、 ブラウザ 画面内に 画像ファイル を D&D したりすると、ペーストや画面遷移を起こしてしまいます。 この実装では、そうした問題に対して対策となります。
jQuery で クリック と ダブルクリック を別実行する プラグイン を作成しました。 通常 ダブルクリック すると、クリック 2回 と ダブルクリック が発生してうまく扱えません。 このプラグインを利用することで、クリック と ダブルクリック に対して別の処理を割り当てることが可能になります。
jquery.compositemouseevent プラグイン
jQuery plugins | Composite Mouse Event Performer(英語) |
---|---|
ダウンロード | jQuery.compositemouseevent v1.0.0 |
API ドキュメント | garafu / jquery.compositemouseevent Wiki(英語) |
ダウンロードした zip ファイル中 //src/jquery.compositemouseevent.js
を、jQueryを読み込んだ後に読み込むようにします。
サンプルコード
<script type="text/javascript" src="./jquery-1.9.1.js" ></script> <script type="text/javascript" src="./jquery.compositemouseevent.js" ></script>
jQuery オブジェクトに対して拡張された .mouse
関数を以下のように利用します。
サンプルコード
$('#elm').mouse(function (event) { // クリックイベント時に呼び出されます。 // この関数はダブルクリック時には呼び出されません。 window.alert('#elm has been clicked.'); }, function (event) { // ダブルクリック時に呼び出されます。 window.alert('#elm has been double clicked.'); });
.mouse(onClickCallback, onDoubleclickCallback)
内部的には setTimeout
を利用して、クリックとダブルクリックを判別実行しています。
その実装の都合上、クリックの反応が若干遅れることはご了承ください。。
IE の 右クリック メニュー(コンテキストメニュー) に独自項目を追加、実装するチュートリアルです。
コンテキストメニュー項目はレジストリに登録し、選択時に実行される実装は HTML と JavaScript で行います。 以下では、登録するレジストリ と 実行される HTML & JavaScript について、順に見ていきます。
レジストリに "キー" を追加することで コンテキストメニュー項目 が作成されます。 新規キー を作成する場所は以下の場所です。
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\[コンテキストメニュー項目名]
@="[コンテキストメニュー選択時に起動するHTMLへの絶対パス]"
"Contexts"=dword:[トリガ条件]
"Flags"=dword:[ウィンドウ起動]
キーの名称(必須)
コンテキストメニューの項目名として表示したい文字列をキーの名称にします。 コンテキストメニューの名称にアンパサンド(&)を利用すると、ショートカットキーが利用できるようになります。
@ キーの既定値(必須)
作成したキーの(既定)の値には、コンテキストメニュー項目が選択されたときに実行される HTML への絶対パスを記載します。 HTML の内容と実装は以下の コンテキストメニュー項目選択時の実装 をご参照ください。
Contexts DWORD値(オプション)
作成したコンテキストメニュー項目をどのような条件下(コンテキスト下)で表示するか指定します。 この値はビットマスクになっているので、以下の表から必要とする条件の OR を取った値を記載します。
例えば、デフォルト(0x01
)、画像(0x02
)上でコンテキストメニュー項目を表示させたい場合、
0x03
を指定します。
コンテキスト | 値 |
---|---|
デフォルト | 0x01 |
画像 | 0x02 |
コントロール | 0x04 |
テーブル | 0x08 |
テキスト選択 | 0x10 |
アンカー | 0x20 |
不明 | 0x40 |
Flags DWORD値(オプション)
0x1
を指定した場合、モーダルダイアログを起動します。
0x0
の場合、ダイアログ表示しません(既定)。
コンテキストメニューから呼び出される HTML では、以下のオブジェクトから呼び出し元の情報を探します。
window.external.menuArguments
コンテキストメニューを開いた元の window オブジェクトが保存されています。
window.external.menuArguments.event
コンテキストメニューを開いたときの イベントオブジェクト が保存されています。
上記 オブジェクト を利用することで、任意の処理を実行していきます。 以下に載せる HTML および JavaScript では、"コンテキストメニューが開かれたときの位置" と "選択文字列" を表示します。
sample.html
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="sample.js"></script> </head> <body> </body> </html>
sample.js
try { // コンテキストメニューを開いた元の Window オブジェクトを取得 var ownerWindow = window.external.menuArguments; // コンテキストメニューを開いたときのイベントオブジェクトを取得 var ownerEvent = ownerWindow.event; // 選択文字列を取得 // NOTE: 選択されていないときは空文字列になる var selectedText = ''; selectedText += '"'; selectedText += ownerWindow.document.selection.createRange().text; selectedText += '"'; // 出力するメッセージを作成 var message = ''; message += 'クリック位置: '; message += ownerEvent.screenX + ', ' + ownerEvent.screenY; message += '\r\n'; message += ' 選択文字列: '; message += selectedText; // メッセージを表示 window.alert(message); } catch ( exception ) { window.alert(exception); }
既定では モーダルダイアログ 表示しないので、スクリプトを読み込むだけで HTML には特に何も記述しません。 JavaScript は普通に扱えるので、 jQuery 等を利用すると必要な情報の取得がラクになると思います。
今回参考にしたのは、以下のサイトです。
jQuery で閲覧ブラウザ、バージョン、プラットフォーム を判別する プラグイン を作成しました。
jQuery 1.9 から browser
のサポートがなくなるので、その対応用プラグインです。
タブレットと携帯電話(モバイル)の判別も行えます。
window.navigation.userAgent
文字列を利用します。
文字列をせっせと解析して、各フラグを立てて回ります。
ダウンロード |
V1.1.8
旧バージョン
|
---|---|
API ドキュメント | GitHub - garafu / jquery.depend : Wiki(英語) |
外部リンク |
bower - jquery.depend
|
通常利用
ダウンロードした js ファイル または zip ファイル中 //src/jquery.depend.js
を、jQueryを読み込んだ後に読み込むようにします。
<script type="text/javascript" src="./jquery-1.9.1.js" ></script> <script type="text/javascript" src="./jquery.depend.js" ></script>
旧 jQuery プラグイン 互換モード 利用
古い実装の jQuery プラグイン と混在して利用する場合、うまく動作しないケースがあります。
そのような場合、以下のように __BACKWARD_COMPATIBILITY_ENABLED
グローバルフラグ を有効にすると動作する可能性があります。
ただし、このフラグを有効にすると、 $.browser.version
オブジェクト が テキスト に変更される点 (バージョンに関するメソッドが利用できなくなる点) に注意してください。
<script type="text/javascript"> window.__BACKWARD_COMPATIBILITY_ENABLED = true; </script> <script type="text/javascript" src="./jquery-1.9.1.js" ></script> <script type="text/javascript" src="./jquery.depend.js" ></script>
ブラウザ判定
基本的に jQuery 1.9 以前と同じコードが利用できます (サポートには jQuery 1.9 以上 と記載がありますが…)。 判定できる ブラウザ は、Opera、MSIE、Firefox、Chrome、Android標準ブラウザ、Safari、Silk、Mercury等。
if ($.browser.msie) { // Internet Explorer の場合 }
ブラウザバージョン判定
バージョン判定は文字列ではなく、 object になっています。 バージョン判定はメソッドを通すことで簡単に比較できるようになっています。
if ($.browser.is('msie') && $.browser.version.isOrLess(7)) { // Internet Explorer 7.0 以前のブラウザの場合 }
プラットフォーム判定
携帯電話、タブレットを判別します。
if ($.platform.mobile) { // 携帯端末(iPhone, Android, Windows Phone...)の場合 } else if ($.platform.tablet) { // タブレット端末(iPad, Android)の場合 } else { // 通常PCの場合 }
ここでは、プラグインの一部機能しか取り上げていません。 詳細は下記の wiki をご参照ください。
garafu / jquery.depend Wiki(英語)
まぁ、すでに Browser プラグイン が存在しているのですが… このプラグインは Android タブレット端末 の判定が少し厳しいような気がしました(コードでのみ確認)。 あとは何より個人的な興味もあって作ってみたという経緯です。
更新履歴
GitHub for Windows を利用しながら、GitHub 上に作成した jQueryプラグイン を公開してみます。
基本ルールは次の通り。
要するに、名前は早い者勝ちだそうです。 ただし、名前を先にとって中身がからっぽだと、警告無しに削除するそうです。
GitHub for Windows を使いながら jQueryプラグイン を公開していきます。
まずは、公開するプラグイン自体を準備します。 詳細は下記の記事または他のサイトをご参照ください。
ここでは、基本設定のみ(今回の目標に対して必要最低限のみ)を記載します。 以下の手順は GitHub のウェブページ上で行います。
jQuery Plugins Registry はレポジトリのルートディレクトリにある *.jquery.json
という名前のファイルを探します。
jQueryプラグイン レポジトリ のルートディレクトリに、パッケージマニフェスト仕様書に従った
yourplugin.jquery.json
を作成、配置します。
パッケージマニフェストファイル の サンプル
{ "name": "depend", "title": "Solution for the dependency problem", "description": "jQuery plugin for resolve of the dependency problem about client browser or/and client platform using userAgent string.", "keywords": [ "browser", "platform", "detection", "html5", "mobile", "tablet", "support" ], "version": "1.0.0", "author": { "name": "garafu", "url": "https://github.com/garafu" }, "licenses": [ { "type": "MIT", "url": "https://github.com/garafu/jquery.depend/blob/master/MIT-LICENSE.txt" } ], "bugs": "https://github.com/garafu/jquery.depend/issues", "homepage": "https://github.com/garafu/jquery.depend", "docs": "https://github.com/garafu/jquery.depend/wiki", "download": "https://github.com/garafu/jquery.depend", "dependencies": { "jquery": ">=1.9.1" } }
パッケージマニフェストファイルの検証は "Publishing Your Plugin" 中段にある "Validate Your Manifest File Here" を利用してください。
パッケージマニフェストの仕様は "jQuery Plugin Package Manifest Specification" を参照してください。 (詳細は後日気が向いたときに記載…するかも…。。)
Post-Recieve フック の設定、マニフェストファイルの作成が完了したら、いよいよ公開作業に入ります。 以下の手順は GitHub for Windows (+ PowerShell) 上で行います。
> git tag v1.0.0 > git push origin --tags
> git tag [バージョン]
で指定する バージョン番号 と、パッケージマニュフェストで指定する バージョン番号 は
一致していないと登録できません。
すでに発行済みのタグ(バージョン番号)を上書きすることはできません。
きちんと登録できたかどうかは jQuery Plugins Registry エラーログ 末尾を確認します。
jQueryプラグイン を公開する概略手順は次の通りです。
参考にしたサイトは以下の通りです。
jQuery で 独自の プラグイン を 作成、開発 しようと思ったので、その方法について少し調べてみました。 ここでは、jQuery プラグイン の 作成方法 についていくつかまとめます。
目次
まずは最もシンプルなプラグインのコード。 このままだと、 $ が jQuery である保証がなかったり、 $ が別物で $.fn が undefined だったり…
$.fn.[関数名] = function () { // 拡張するコードを実装 };
上述の コード では メソッドチェーン が利用できません。 戻り値を設定することで メソッドチェーン を利用できるようにします。
$.fn.[関数名] = function () { // 拡張するコードを実装 // メソッドチェーンの有効化 return this; };
基本形では変数がグローバルに配置されてイロイロとまずいので、無名関数に取り込んで、$ = jQuery
を保証します。
また、window
や document
をローカル変数化することで "気持ち" 高速化しています。
undefined
は上書きできるので、 変数化することで undefined
を保証します。
このコードは「各要素に対する処理はないが、何か決まった処理を行う」場合に利用できる形になります。
(function (window, document, $, undefined) { $.fn.[関数名] = function () { // 拡張するコードを実装 // メソッドチェーンの有効化 return this; }; })(window, document, jQuery);
jQuery ではメソッドチェーンを一般的に使うので、プラグインでもそのやり方にならいます。 jQuery で指定される要素は複数なので、 each 関数でそれぞれの要素に対して実装を適用していきます。
参考までに 各スコープにおける this が何かを「メモ」として記載しました…念のため。
このコードは「各要素に対して何か決まった処理を行う」場合に利用できる形になります。
(function (window, document, $, undefined) { $.fn.[関数名] = function () { // 拡張するコード(各要素に依存しないコード)を実装 // メモ:この function スコープ内の this は jQuery // メソッドチェーンの有効化 return this.each(function (index) { // 各要素に対する実装 // メモ:この function スコープ内の this は DOM要素 }); }; })(window, document, jQuery);
参考記事
今回は、Internet Explorer 上で動作する アドオン の開発を C# で実装してみます。
アドオンはページ内で ActiveX オブジェクトの生成を行う、または objectタグ を HTML に書き込むことで利用できるものです。 メニューの[ツール]-[アドオンの管理]から、現在利用できるアドオンを確認できます。
※ 本記事の更新履歴を末尾に掲載しています。
本記事 の メニュー