InstallShield Windows Installer 形式 DLLの利用方法 [InstallShield]
InstallShieldバージョン: 2010
プロジェクトタイプ: 基本のMSIプロジェクト
InstallShieldからWin32の機能を利用するため、DLL作成方法とそれを利用する方法を説明する。DLLの機能としてインストーラが管理者権限で起動しているか確認し、通常権限で起動している場合、インストールを中止する機能を作成する。
1.Windows Installer 形式 DLL ファイルの作成
① Visual Studioを起動し、プロジェクトの新規作成から「Visual C++」、「Win32」、「Win32プロジェクト」を選択し、プロジェクトの名前を「AdminCheck」として「OK」ボタンを押す。
② アプリケーションの設定
アプリケーションの種類: DLL
追加のオプション: 空のプロジェクト
でプロジェクトを作成する。
③ ファイルの作成
以下二つのファイル「AdminCheck.cpp」「AdminCheck.def」を作成します。
ファイル「AdminCheck.cpp」
// link to MSI library
#pragma comment(lib, "msi.lib")
// include standard Windows and MSI headers
#include < windows.h >
#include < msi.h >
#include < msiquery.h >
UINT __stdcall IsAnAdmin(MSIHANDLE hInstall) {
BOOL b = FALSE;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
if(b) {
if (!CheckTokenMembership( NULL, AdministratorsGroup, &b)) {
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
switch(b) {
case TRUE:
MessageBox(GetForegroundWindow( ), TEXT("管理者権限で起動しました"), TEXT("Custom Action"), MB_OK | MB_ICONINFORMATION);
b = FALSE;
break;
case FALSE:
MessageBox(GetForegroundWindow( ), TEXT("通常権限で起動しました"), TEXT("Custom Action"), MB_OK | MB_ICONINFORMATION);
b = TRUE;
break;
}
return(b);
}
// Windows Installerと情報の受け渡しをプロパティを利用して行うサンプル
UINT __stdcall SecondAction(MSIHANDLE hInstall) {
// max. USERNAME size, from CustomerInformation panel
const DWORD MAX_USERNAME_LEN = 50;
// initialize empty string and size buffer
TCHAR UserName[MAX_USERNAME_LEN + 1] = {0};
DWORD Buffer = MAX_USERNAME_LEN + 1;
// read and display the initial value of USERNAME
MsiGetProperty(hInstall, TEXT("USERNAME"), UserName, &Buffer);
MessageBox(GetForegroundWindow( ), UserName, TEXT("USERNAME"), MB_OK | MB_ICONINFORMATION);
// change the value of USERNAME
MsiSetProperty(hInstall, TEXT("USERNAME"),
TEXT("Valued Customer"));
return ERROR_SUCCESS;
}
ファイル「AdminCheck.def」
LIBRARY CustomAction
EXPORTS
IsAnAdmin
④ ビルドします。
2.カスタムアクションの作成
① カスタムアクションウィザードの起動
「動作とロジック」、「カスタム アクションとシーケンス」と選択し「カスタム アクション」を右クリックし「カスタムアクションウィザード」を選択する。
② 基本情報
名前: CheckUserAdmin
コメント: Windows Installer 形式DLLを利用して管理者権限か確認する
③ アクションの種類
種類: Windows Installerのダイナミックリンクライブラリの関数を呼び出す
場所: Binary テーブルに保存する
④ アクションのパラメータ
ソース: AdminCheck.dllを指定する。
ターゲット: 関数名 IsAnAdmin を指定
ターゲットは設定済みで、修正する場合はウィザードから戻って設定を変更する。
⑤ 追加オプオション
戻り値の処理: 同期(終了コードを確認)
⑥ 応答オプション
スクリプト内実行: 即時実行
実行スケジュール: 1プロセスにつき1回実行
⑦ シーケンスに挿入する
インストールUIシーケンス: 次の後:AppSearch
インストール実行シーケンス: <シーケンスになし>
⑧ シーケンス確認
「AppSearch」の後に「CheckUserAdmin」が設定されています。
ビルドして完了です。
3.動作確認
出来上がったsetup.exeを通常権限で実行します。
と表示され、以降のインストールウィザードは完了します。
次に管理者として実行します。
と表示され、以降のインストーウィザードも進めることができます。
WordPressによるサイト運営[4-4] [WordPress]
「同じ表示となる部分を共通化する」
5.footer.phpのテンプレート化
フッターでは、フッターウィジェットエリア、フッターナビゲーション、コピーライトの表示をテンプレート化する。フッターウィジェットエリアの中は、4つのウィジェットエリアが利用できる。
①フッターウィジェットエリアの条件分岐
4か所のウィジェットエリアの場所を配列で定義します。次にis_active_sidebar_areaタグで複数のエリアにウィジェットの登録があるか判別し条件分岐を行う。
<?php
$area_widgets = array(
'first-footer-widget-area',
'second-footer-widget-area',
'third-footer-widget-area',
'fourth-footer-widget-area'
);if ( is_active_sidebar_area( $area_widgets ) ) :
?>
<div id="footer-widget-area" class="widgets <?php wp_area_widget_num_class( $area_widgets ); ?>">
<?php if ( is_active_sidebar( 'first-footer-widget-area' ) ) : ?>
<section id="first" class="widget-area">
<?php dynamic_sidebar( 'first-footer-widget-area' ); ?>
</section>
<?php endif; ?>
<?php if ( is_active_sidebar( 'second-footer-widget-area' ) ) : ?>
<section id="second" class="widget-area">
<?php dynamic_sidebar( 'second-footer-widget-area' ); ?>
</section>
<?php endif; ?>
<?php if ( is_active_sidebar( 'third-footer-widget-area' ) ) : ?>
<section id="third" class="widget-area">
<?php dynamic_sidebar( 'third-footer-widget-area' ); ?>
</section>
<?php endif; ?>
<?php if ( is_active_sidebar( 'fourth-footer-widget-area' ) ) : ?>
<section id="fourth" class="widget-area">
<?php dynamic_sidebar( 'fourth-footer-widget-area' ); ?>
</section>
<?php endif; ?>
<!--/* ▼ #footer-widget-area 終了 */-->
</div>
<?php endif; ?>
②表示されるウィジェットのエリア数に応じたclassを出力
wp_area_widget_num_classタグで表示されるエリア数に応じたCSSのclassが出力され、エリアの幅が自動的に調整される。
<div id="footer-widget-area" class="widgets <?php wp_area_widget_num_class( $area_widgets ); ?>">
③フッターのウィジェットエリアをテンプレート化
is_active_sidebarとdynamic_sidebarタグで、ウィジェットエリアの表示が反映されるようにする。
<?php if ( is_active_sidebar( 'first-footer-widget-area' ) ) : ?>
<section id="first" class="widget-area">
<?php dynamic_sidebar( 'first-footer-widget-area' ); ?>
</section>
<?php endif; ?>
④すべてのフッターウィジェットエリアをテンプレート化
残り3つのウィジェットエリアもテンプレート化する。
<?php if ( is_active_sidebar( 'second-footer-widget-area' ) ) : ?>
<section id="second" class="widget-area">
<?php dynamic_sidebar( 'second-footer-widget-area' ); ?>
</section>
<?php endif; ?>
<?php if ( is_active_sidebar( 'third-footer-widget-area' ) ) : ?>
<section id="third" class="widget-area">
<?php dynamic_sidebar( 'third-footer-widget-area' ); ?>
</section>
<?php endif; ?>
<?php if ( is_active_sidebar( 'fourth-footer-widget-area' ) ) : ?>
<section id="fourth" class="widget-area">
<?php dynamic_sidebar( 'fourth-footer-widget-area' ); ?>
</section>
<?php endif; ?>
⑤フッターナビゲーションを表示
wp_nav_menuで置き換える。
<?php wp_nav_menu(
array(
'container' => 'nav',
'container_id' => 'footer-nav',
'theme_location' => 'footer',
'fallback_cb' => null
)
); ?>
⑥コピーライトを表示
bloginfoなどのテンプレートタグでテンプレート化する。
<p id="copyright">
<small>Copyright © <?php echo date_i18n( 'Y' ); ?>
<a href="<?php echo home_url( '/' ); ?>"><?php bloginfo( 'name' ); ?></a>
All rights reserved.</small>
</p>
⑦「Page Top」の画像パスを合わせる
get_default_imageタグでブラウザでスクロールした際にページ最上部まで移動するリンクの画像のパスを合わせる。
<p id="go-top"><a href="#header" onclick="scrollup(); return false;">
<img src="<?php echo get_default_image( 'go-top.png' ); ?>" alt="go top">
</a></p>
⑧スクロール用JavaScriptへのパスを合わせる
ブラウザーのスクロールの最上部までの移動を滑らかにするJavaScriptファイルへのパスを合わせる。
<script src="<?php bloginfo( 'template_url' ); ?>/js/scroll.js"></script>
⑨wp_footerパグを記述
wp_footerタグで管理バーの表示に必要なソースがこのタグを通じて表示される。
<?php wp_footer(); ?>
⑩表示
参考資料
WordPressによるサイト運営[4-3] [WordPress]
「同じ表示となる部分を共通化する」
4.sidebar.phpのテンプレート化
ウィジェットアリアを2か所設け、1つ目のウィジェットに登録がない場合、固定ページのリスト、月別アーカイブの表示を行う。
①上部サイドバーウィジェットを設定
dynamic_sidebarタグを利用して設置する。ウィジェットが登録されていないときは、テンプレートタグのwp_list_pagesで「ページリスト」、wp_get_archivesで「月刊アーカイブ」を表示する。
<div id="primary" class="widget-area">
<?php if ( ! dynamic_sidebar( 'primary-widget-area' ) ) : ?>
<aside id="pages" class="widget-container">
<h3 class="widget-title">Menu</h3>
<ul>
<?php wp_list_pages( 'title_li=&depth=2' ); ?>
</ul>
</aside>
<aside id="archives" class="widget-container">
<h3 class="widget-title">Archives</h3>
<ul>
<?php wp_get_archives( 'type=monthly' ); ?>
</ul>
</aside>
<?php endif; ?>
</div>
②下部サイドバーウィジェットを設定
is_active_sidebarタグでウィジェット登録の有無を判別し、ウィジェットの登録が無い場合は、secondaryのボックス自体を非表示とする。
<?php if ( is_active_sidebar( 'secondary-widget-area' ) ) : ?>
<div id="secondary" class="widget-area">
<?php dynamic_sidebar( 'secondary-widget-area' ); ?>
</div>
<?php endif; ?>
③表示
参考資料
WordPressによるサイト運営[4-2] [WordPress]
「同じ表示となる部分を共通化する」
ページの表示や設定によって、変化する部分をテンプレートタグで置き換える。
3.header.phpのテンプレート化
①言語属性の設定
文字の表示方法と言語を表す
<html <?php language_attributes(); ?>>
②文字コードの設定
「表示設定」の「ページとフィールドの文字コード」の設定
<meta http-equiv="Content-Type" content="text/html; charset=<?php bloginfo( 'charset' ); ?>">
③titleタグの設定
「現在のページ | サイトのタイトル | キャッチフレーズ | ページ送り数」のルールで表示する
<title><?php
wp_title( ' | ', true, 'right' );
bloginfo( 'name' );
echo ' | ';
bloginfo( 'description' );
global $page, $paged;
if ( $paged >= 2 || $page >= 2 ) {
echo ' | ' . max( $paged, $page ) . 'ページ';
}
?></title>
④iPhone/iPad向けアイコンの設定
iPhone/iPad向けのホーム画面用アイコンの設定
<link rel="apple-touch-icon" href="<?php echo get_default_image( 'apple-touch-icon.png' ); ?>" />
⑤wp_headの追加
RSSフィードのリンクやツールバーのCSSなどのタグをhead内に自動的に出力する。
<?php wp_head(); ?>
⑥body_classの追加
トップページやカテゴリーなどの表示状態をCSSのclassとして出力する。状況によってCSSで表示スタイルを変更可能にする。
<body <?php body_class(); ?>>
⑦サイトタイトル画像の表示
サイトタイトル画像が設定されている場合はその画像を表示し、設定されていなければサイトのタイトルをテキストで表示する。
<h1 id="site-id">
<a href="<?php echo home_url( '/' ); ?>">
<?php
if ( get_theme_mod( 'site_title_image' ) ) : ?>
<img src="<?php echo get_theme_mod( 'site_title_image' ); ?>" alt="<?php echo get_bloginfo( 'name' ); ?>" />
<?php else :
bloginfo( 'name' );
endif; ?>
</a>
</h1>
⑧キャッチフレーズの表示
サイトタイトルの下に表示する文章「設定」、「一般設定」のキャッチフレーズの内容を表示させる。
<h2 id="description"><?php bloginfo( 'description' ); ?></h2>
⑨ヘッダーメニューの表示
「外観」、「メニュー」で設定されたナビゲーションメニューを表示する。メニューの内容については別途後術する、カスタムメニューを使用して構成する。
<?php wp_nav_menu(
array(
'container' => 'nav',
'container_id' => 'utility-nav',
'theme_location' => 'header',
'fallback_cb' => null
)
); ?>
⑩検索フォームのウィジェット化
管理画面で設定したウィジェットを表示する。
<div class="widget-area" id="header-widget-area">
<?php dynamic_sidebar( 'header-widget-area' ); ?>
</div>
⑪メインナビゲーションの表示
メインナビゲーションもヘッダーナビゲーションと同様にwp_nav_menuタグを使用する。
<?php wp_nav_menu(
array(
'container' => 'nav',
'container_id' => 'global-nav',
'theme_location' => 'global'
)
); ?>
⑫ヘッダー画面の表示
カスタムヘッダー設定画面で指定したヘッダー画像のURLを出力する。
<?php if ( get_header_image() ) : ?>
<div id="branding">
<img src="<?php header_image(); ?>" width="<?php echo HEADER_IMAGE_WIDTH; ?>" height="<?php echo HEADER_IMAGE_HEIGHT; ?>" alt="" />
</div>
<?php endif; ?>
⑬パンくずナビの表示
パンくずナビを表示するカスタムテンプレートタグ。
<?php if ( ! is_front_page() && ! is_404() ) {
bread_crumb( 'elm_class=bread-crumb&home_label=Home' );
} ?>
⑭表示
参考資料
WordPressによるサイト運営[4-1] [WordPress]
「同じ表示となる部分を共通化する」
1.共通化できる部分を見いだす
一般的なWebサイトではすべてのページを通じて同じ表示となる部分がある。ここを1つのテンプレートとして共有する。これをモジュールテンプレートと呼んでいる。
下図を見てみると、青線で囲った「ヘッダー」「サイドバー」「フッター」が共有化できる部分となる。
2.モジュールテンプレートを作成
①header.php、sidebar.php、footer.php ファイルを作成
index.phpをコピーしheader.php、sidebar.php、footer.phpを作成する。
②header.phpの編集
header.php、sidebar.php、footer.php の不要な部分を削除する。
-
- <!—/* ### header.php 開始 ### */—> ~ <!—/* ### header.php 終了 ### */—> 以外を削除する
- <!—/* ### sidebar.php 開始 ### */—> ~ <!—/* ### sidebar.php 終了 ### */—> 以外を削除する
- <!—/* ### footer.php 開始 ### */—> ~ <!—/* ### footer.php 終了 ### */—> 以外を削除する
3.テンプレートタグへの置き換え
①インクルードのテンプレートタグの代わりに追加
get_header, get_sidebar, get_footerタグを使って, index.php内のモジュールテンプレート化下部分を、それぞれのテンプレートに置き換える。
例:
<?php get_header(); ?>
②表示
変更後のWebサイトを表示。
参考資料
Visual Studio 2010 ビルド後イベントの設定方法 [開発環境]
DLL用プロジェクトの動作確認やデバッグ時に、ビルド後のDLLファイルを呼び出し側のEXEプロジェクトフォルダにコピーする機能について調べた。この機能はVisual Studioの持つ機能を利用して実現できるらしいので、その設定方法について説明する。
1.「プロパティ ページ」ダイアログ
メニューから「プロジェクト」、「プロジェクトのプロパティ」を選択し、プロジェクトのプロパティ ページダイアログを起動する。
2.コマンドラインの選択
「構成プロパティ」、「ビルド イベント」、「ビルド後イベント」、「コマンド ライン」と選択する。
3.「コマンドライン」ダイアログ
コマンドラインを選択し、「[▼]ボタン」、「<編集…>」を押し、コマンドラインダイアル後を表示する。
4.コマンドの生成
「マクロ」ボタンを押すと現れるマクロと入力で以下のコマンドライン文字列を作成する。
copy "$(TargetPath)" "..\..\UserCheck\Release"
5.確認
メニューからビルドを実行すると生成されたDLLファイルが、EXE用プロジェクトのReleseフォルダーにコピーされた。
Debug側にも下記コマンドラインを登録しておくこと。
copy "$(TargetPath)" "..\..\UserCheck\Debug"
注意:
パスをダブルクォーテーションで囲むことが重要、付けないと ”error MSB3073 exited with code 1”エラーで苦しむことに!
参考サイト
- https://forums.embarcadero.com/thread.jspa?threadID=74898
- http://kronoseed.blog43.fc2.com/?mode=m&no=42
- http://suzume.nemuly.net/programming/%E3%82%82%E3%81%A3%E3%81%A8visual%20studio
管理者権限を持っているか確認[C/C++] [開発環境]
管理者権限の有無によって処理を変える処理を行いたいので、管理者権限を持っているか確認する方法を調べた。
検索するとIsUserAnAdminを使う例がたくさん出てきたが自分の環境(Windows7)では管理者権限を確認できなかった。そこでCheckTokenMembershipを使う以下のコードを使ったら管理者権限を確認できた。
#include "stdafx.h"
#include <Windows.h>
BOOL IsAnAdmin(VOID)
{
BOOL b = FALSE;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;b = AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdministratorsGroup);
if(b) {
if (!CheckTokenMembership( NULL, AdministratorsGroup, &b)) {
b = FALSE;
}
FreeSid(AdministratorsGroup);
}return(b);
}int _tmain(int argc, _TCHAR* argv[])
{
if(IsAnAdmin())
printf("管理者権限で起動しました\n");
else
printf("通常権限で起動しました\n");
getchar();return 0;
}
セキュリティ識別子(SID)を割り当て、最大8つの副権限(サブオーソリティ)を使って初期化します。
指定した SID(セキュリティ ID)がアクセストークン内で有効になっているかどうかを調べます。
「SID(Security Identifier。セキュリティ識別子)」と呼ばれる一意のID番号列を使用して管理されている。
参考サイト
- http://sideseeker.hateblo.jp/entry/2012/08/26/201846
- http://togarasi.wordpress.com/2009/02/25/administrator-%E6%A8%A9%E9%99%90%E3%82%92%E6%8C%81%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B%E7%A2%BA%E8%AA%8D%E3%81%97%E3%81%9F%E3%81%84/
- http://www.atmarkit.co.jp/fwin2k/win2ktips/307sid/sid.html