新規記事の投稿を行うことで、非表示にすることが可能です。
2014年08月23日
エクスプローラ再起動時におけるトレイアイコンの再登録
アプリを開発していて、タスクトレイ(現在は通知エリア?)にアイコンを登録し、右クリックでメニューを出して操作するというのは定番スタイルである
通常は困らないのだが、時折エクスプローラが死んで再起動されると、アイコンが消えてしまい、操作ができなくなってしまうという困った現象が起こることがある
それに対応するには、エクスプローラが再起動したというタイミングをとらえてアイコンを再登録する必要があるのだが、そのタイミングをどうやってとらえるかが問題だった
昔、XP時代にも何かやっていた記憶があるのだが、ソースも記憶も彼方に逝ってしまったので、改めて調べてみた
WEBを検索してみると、システムアイコンなどが消えた場合の復旧方法などばかりが引っかかり、アプリの開発方法はなかなかヒットしなかった
ようやく見つかり、わかりやすかったのはここだった
改めて自分でも整理してみた
全体の基本構造は以下のような感じである
ちなみに、アイコンの登録やアイコンの変更などは以下のような感じ
最初に作るなら、このクレジットカード!
ロリポップ!レンタルサーバー!はあなたの「やってみたい!」を応援します!
ロリポップ!なら、ホームページ、ブログ、ネットショップ…
これらが今すぐ、そして簡単にできちゃう!
マニュアルやライブチャットを完備しているので、ホームページ初心者でも安心。
これだけついてるのに月額100円(税抜)〜ととってもお得。
もちろん無料のお試し期間も10日間あるので安心ですね。
▼ロリポップ!レンタルサーバーはこちら
通常は困らないのだが、時折エクスプローラが死んで再起動されると、アイコンが消えてしまい、操作ができなくなってしまうという困った現象が起こることがある
それに対応するには、エクスプローラが再起動したというタイミングをとらえてアイコンを再登録する必要があるのだが、そのタイミングをどうやってとらえるかが問題だった
昔、XP時代にも何かやっていた記憶があるのだが、ソースも記憶も彼方に逝ってしまったので、改めて調べてみた
WEBを検索してみると、システムアイコンなどが消えた場合の復旧方法などばかりが引っかかり、アプリの開発方法はなかなかヒットしなかった
ようやく見つかり、わかりやすかったのはここだった
改めて自分でも整理してみた
全体の基本構造は以下のような感じである
UINT g_uTaskbarCreatedMessage = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_CREATE:
// ここ、あるいはプログラムメイン開始時などで以下を実行する
g_uTaskbarCreatedMessage = RegisterWindowMessage(_T("TaskbarCreated"));
break;
case WMU_NOTIFY_ICON:
switch (lParam) {
case WM_CONTEXTMENU:
{
// ここでメニュー表示処理を行う
// ここに来れるためには、NIM_SETVERSION で4を設定しておく必要がある
}
break;
}
return 0;
default:
if (uMsg == g_uTaskbarCreatedMessage) {
// ここでアイコンの再登録処理を行う
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
ちなみに、アイコンの登録やアイコンの変更などは以下のような感じ
#define WMU_NOTIFY_ICON (WM_APP+1)
#define MAX_RETRY 2
bool ReleatedlyNotifyIcon(UINT nimCommand, NOTIFYICONDATA* pnid)
{
int count = MAX_RETRY;
while (--count > 0) {
if (Shell_NotifyIcon(nimCommand, pnid) {
return true;
}
}
Sleep(100);
}
bool RegisterIcon(HWND hWnd, HICON hIcon)
{
NOTIFYICONDATA nid = {0};
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.hIcon = hIcon;
nid.uCallbackMessage = WMU_NOTIFY_ICON;
nid.uFlags = NIF_ICON|NIF_MESSAGE;
if (!RepeatNotifyIcon(NIM_ADD, nid)) {
return false;
}
// バージョン設定
nid.uVersion= 4;
return RepeatNotifyIcon(NIM_SETVERSION, nid);
}
bool ChangeIcon(HWND hWnd, HICON hIcon)
{
NOTIFYICONDATA nid = {0};
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.hIcon = hIcon;
nid.uFlags = NIF_ICON;
return RepeatNotifyIcon(NIM_MODIFY, nid);
}
最初に作るなら、このクレジットカード!
ロリポップ!レンタルサーバー!はあなたの「やってみたい!」を応援します!
ロリポップ!なら、ホームページ、ブログ、ネットショップ…
これらが今すぐ、そして簡単にできちゃう!
マニュアルやライブチャットを完備しているので、ホームページ初心者でも安心。
これだけついてるのに月額100円(税抜)〜ととってもお得。
もちろん無料のお試し期間も10日間あるので安心ですね。
▼ロリポップ!レンタルサーバーはこちら
【このカテゴリーの最新記事】
-
no image
-
no image
-
no image
-
no image
-
no image
2014年08月22日
C, C++ WIn32 標準ファイルIOライブラリでUTF入出力ができた
今までは、 CreateFile WriteFile などでファイル入出力することが多かったので、ファイル内のテキストエンコードはあまり気にしたことがなかったのだが、近ごろ、ログファイルをShiftJISではなく、UTF-8で出してほしいという要望があがってきた
今までのやり方と踏襲するなら MultiByteToWideChar を使って WriteFile の直前にUTF-8変換をすることにしていただろう
しかし、ログファイルの「出力には、よくある可変数個の引数を使って、いわゆる printf 方式で出力したいというのも人情である
また、共通ライブラリ化してあるものには、そうした標準ファイルIOを利用している箇所も多数あったため、改めて調べてみたら、fopen 時に、文字エンコードを指定できる機能があることがわかった
MSDNドキュメント
こうすると、初めてファイルを作成した際に、BOMが書き込まれて、メモ帳でもちゃんと読めるのがうれしい
※ちなみに、Windows向けのUTF-16はccs=UTF-16LEと記述すればよいようだ
※普通のCPUはx86系かx64系なのでLE(Little Endian)ということだろう
いつの間にか便利な機能が追加されていたものだ
今までのやり方と踏襲するなら MultiByteToWideChar を使って WriteFile の直前にUTF-8変換をすることにしていただろう
しかし、ログファイルの「出力には、よくある可変数個の引数を使って、いわゆる printf 方式で出力したいというのも人情である
また、共通ライブラリ化してあるものには、そうした標準ファイルIOを利用している箇所も多数あったため、改めて調べてみたら、fopen 時に、文字エンコードを指定できる機能があることがわかった
MSDNドキュメント
FILE* fp = fopen("test.txt", "a, ccs=UTF-8");
こうすると、初めてファイルを作成した際に、BOMが書き込まれて、メモ帳でもちゃんと読めるのがうれしい
※ちなみに、Windows向けのUTF-16はccs=UTF-16LEと記述すればよいようだ
※普通のCPUはx86系かx64系なのでLE(Little Endian)ということだろう
いつの間にか便利な機能が追加されていたものだ
2014年08月12日
OpenSSL 自前の CA スクリプト (2)
OpenSSL 自前の CA スクリプト
最近になって、HTTPS のテストをする機会があり、有料証明書を買うほど金と暇がなかったので、 OpenSSL に付属している CA.sh スクリプトをカスタマイズして、自前のサーバ証明書を作成した
その時のスクリプトと、設定ファイルをメモ代わりにあげておく
CA.sh
CA.cnf
その時のスクリプトと、設定ファイルをメモ代わりにあげておく
CA.sh
if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi
ROOT="$HOME/CA"
SSLEAY_CONFIG="-config $HOME/CA.cnf"
DAYS="-days 365" # 365 day
CADAYS="-days 3650" # 10 years
REQ="$OPENSSL req $SSLEAY_CONFIG"
CA="$OPENSSL ca $SSLEAY_CONFIG"
VERIFY="$OPENSSL verify"
X509="$OPENSSL x509"
RSA="$OPENSSL rsa"
CATOP="$ROOT"
CAKEY=cakey.pem
CAREQ=careq.pem
CACERT=cacert.pem
if [ -d $CATOP/tmp ]; then
cd $CATOP
fi
for i
do
case $i in
-\?|-h|-help)
echo "usage: CA -newcert|-newreq|-newca|-sign|-verify|-revoke|-rename" >&2
exit 0
;;
-newcert)
# create a certificate
$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS
RET=$?
echo "Certificate is in newcert.pem, private key is in newkey.pem"
;;
-newreq)
# create a certificate request
$REQ -new -keyout newkey.pem -out newreq.pem $DAYS
RET=$?
echo "Request is in newreq.pem, private key is in newkey.pem"
;;
-newca)
# if explicitly asked for or it doesn't exist then setup the directory
# structure that Eric likes to manage things
NEW="1"
if [ "$NEW" -o ! -f ${CATOP}/serial ]; then
# create the directory hierarchy
mkdir ${CATOP}
mkdir ${CATOP}/certs
mkdir ${CATOP}/crl
mkdir ${CATOP}/newcerts
mkdir ${CATOP}/private
mkdir ${CATOP}/tmp
echo "00" > ${CATOP}/serial
echo "00" > ${CATOP}/crlnumber
touch ${CATOP}/index.txt
fi
if [ ! -f ${CATOP}/private/$CAKEY ]; then
echo "CA certificate filename (or enter to create)"
read FILE
# ask user for existing CA certificate
if [ "$FILE" ]; then
cp $FILE ${CATOP}/private/$CAKEY
RET=$?
else
echo "Making CA certificate ..."
$REQ -new -keyout ${CATOP}/private/$CAKEY \
-out ${CATOP}/$CAREQ
$CA -out ${CATOP}/$CACERT $CADAYS -batch -extensions v3_ca \
-keyfile ${CATOP}/private/$CAKEY -selfsign \
-infiles ${CATOP}/$CAREQ
RET=$?
fi
fi
;;
-xsign)
$CA -policy policy_anything -infiles newreq.pem
RET=$?
;;
-sign|-signreq)
$CA -policy policy_anything -out newcert.pem -infiles newreq.pem
RET=$?
cat newcert.pem
echo "Signed certificate is in newcert.pem"
;;
-signcert)
echo "Cert passphrase will be requested twice - bug?"
$X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
$CA -policy policy_anything -out newcert.pem -infiles tmp.pem
cat newcert.pem
echo "Signed certificate is in newcert.pem"
;;
-verify)
shift
if [ -z "$1" ]; then
$VERIFY -CAfile $CATOP/$CACERT newcert.pem
RET=$?
else
for j
do
$VERIFY -CAfile $CATOP/$CACERT $j
if [ $? != 0 ]; then
RET=$?
fi
done
fi
exit 0
;;
-revoke)
shift
if [ -z "$1" ]; then
echo "No certificate"
else
$CA -revoke $1 -out crl/crl.pem
fi
exit 0
;;
-rename)
shift
if [ -z "$1" ]; then
echo "No name to change"
else
if [ -f newcert.pem ]; then
mv newcert.pem certs/$1.crt
fi
if [ -f newkey.pem ]; then
mv newkey.pem certs/$1.key
$RSA -in certs/$1.key -out certs/$1-nopass.key
fi
fi
exit 0
;;
*)
echo "Unknown arg $i";
exit 1
;;
esac
done
exit $RET
CA.cnf
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
#HOME = .
RANDFILE = $ENV::HOME/.rnd
#RANDFILE = /home/norish/.rnd
# Uncomment out to enable OpenSSL configuration see config(3)
# openssl_conf = openssl_init
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[openssl_init]
# Extra OBJECT IDENTIFIER info:
oid_section = new_oids
alg_section = algs
[ new_oids ]
# We can add new OIDs in here for use by any config aware application
# Add a simple OID like this:
# shortname=Long Object Identifier Name, 1.2.3.4
# Or use config file substitution like this:
# testoid2=OID2 LONG NAME, ${testoid1}.5.6, OTHER OID
[ algs ]
# Algorithm configuration options. Currently just fips_mode
fips_mode = no
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /home/norish/CA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
#x509_extensions = v3_ca # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_md = sha1
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_req # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
# we use PrintableString+UTF8String mask so if pure ASCII texts are used
# the resulting certificates are compatible with Netscape
string_mask = MASK:0x2002
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Toshima-Ku
localityName = Locality Name (eg, city)
localityName_default = Tokyo
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Office Creative Ship
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = CA Devision
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
#nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
2014年08月01日
AmaterasERD で HTML ドキュメントを出力する
しばらく前、(たぶん2010年か2011年ころ)は、 eclipse のプラグインである AmterasERD を使って、DBの設計情報を GUIから HTML ドキュメントとして出力することができた
※古い jar で試してみたら、たしかに、右クリックメニューから HTML へエクスポートすることができた
ところが、2014年7月現在、 AmaterasERD 1.0.9 では、その機能はあるはずなのに、GUI からはどうしてもエクスポートができなかった
オリジナルサイトを再度読み直してみた結果、コマンドラインツールで HTML ドキュメントが出力できることがわかった
とすることでドキュメントを生成してくれるとのこと
実際のこの jar を ここから落として試してみたら、簡単にできたのであった
開発環境の変遷がある場合、プラグインなどのメンテナンスをまめにやっていないと、やり方自体が変わっていたり、まったくできなくなっていたりと、面倒なことがよくおきるものである
※古い jar で試してみたら、たしかに、右クリックメニューから HTML へエクスポートすることができた
ところが、2014年7月現在、 AmaterasERD 1.0.9 では、その機能はあるはずなのに、GUI からはどうしてもエクスポートができなかった
オリジナルサイトを再度読み直してみた結果、コマンドラインツールで HTML ドキュメントが出力できることがわかった
java -jar htmlgen.jar 設計書.erd 出力先フォルダ
とすることでドキュメントを生成してくれるとのこと
実際のこの jar を ここから落として試してみたら、簡単にできたのであった
開発環境の変遷がある場合、プラグインなどのメンテナンスをまめにやっていないと、やり方自体が変わっていたり、まったくできなくなっていたりと、面倒なことがよくおきるものである
2014年07月29日
zlib で crc32 が計算できた
2014年07月17日
FbConsole の対話型SQLツールが、自身の提示したSQLを受け付けない
ここでも紹介したが、FbConsole は便利でもバグがあるという話なのだが、また別のやつが見つかった
プロシージャを定義し、その定義をツールのメタ情報から抜き取ったSQLを、FbConsole から流すと、なぜかエラーとなってしまう
ただし、同じSQLを isql ツールから流す場合は大丈夫なので、SQLを流すシーンによってエラーがあったりなかったりということになってしまうのであった
isqlではOKなのに、FbConsole ではダメな例)
両方で大丈夫にするためには、途中の改行をいくつか取り除く必要がある
minne
全ての写真をオンラインで管理
月額300円〜で容量無制限・無期限
●●30 days Album PRO●●
プロシージャを定義し、その定義をツールのメタ情報から抜き取ったSQLを、FbConsole から流すと、なぜかエラーとなってしまう
ただし、同じSQLを isql ツールから流す場合は大丈夫なので、SQLを流すシーンによってエラーがあったりなかったりということになってしまうのであった
isqlではOKなのに、FbConsole ではダメな例)
set term ^^;
create procedure WV_TAB_A
(
rangeMin integer,
rangeMax integer
)
returns
(
UNIQID integer,
HOSTNM varchar(64)
)
AS
BEGIN
FOR SELECT UNIQID,HOSTNM FROM TAB_A WHERE UNIQID BETWEEN :rangeMin AND :rangeMax
INTO :UNIQID, :HOSTNM
DO SUSPEND;
END
^^
set term ;^^
両方で大丈夫にするためには、途中の改行をいくつか取り除く必要がある
set term ^^;
create procedure WV_TAB_A (
rangeMin integer, rangeMax integer
) returns (
UNIQID integer,
HOSTNM varchar(64)
) AS
BEGIN
FOR SELECT UNIQID,HOSTNM FROM TAB_A WHERE UNIQID BETWEEN :rangeMin AND :rangeMax
INTO :UNIQID, :HOSTNM
DO SUSPEND;
END
^^
set term ;^^
minne
全ての写真をオンラインで管理
月額300円〜で容量無制限・無期限
●●30 days Album PRO●●
2014年07月15日
GetVersionEx が Win8.1 からは使えなくなったようだ
従来のコードをメンテナンスしている際、Win8.1 対応コードを追加しようとしたが、びっくりの結果がわかった
やろうとしていたのは以下のようなこと
ところが、上記os.dwMinorVersionの値が、Win8.1 上で実行しても Win8 を示す2が返ってきてしまったのだ(本来3が返ってきてほしかった)
MSDNで質問してみたら、すぐに回答が付き、理由がわかった
要は GetVersionEx はマニフェストに応じて異なるバージョンを返すということだった(なぜそうしたかの合理的な理由は思い浮かばなかったが、ま、しょうがない)
GetVersionEx の解説
やろうとしていたのは以下のようなこと
OSVERSIONINFOEX os = {0};
os.dwOSVersionInfoSize = sizeof(os);
GetVersionEx((OSVERSIONINFO*)&os);
switch ( os.dwMajorVersion ) {
case 6:
switch ( os.dwMinorVersion ) {
case 0: return "Vista";
case 1: return "Win7";
case 2: return "Win8";
case 3: return "Win8.1";
}
break;
}
ところが、上記os.dwMinorVersionの値が、Win8.1 上で実行しても Win8 を示す2が返ってきてしまったのだ(本来3が返ってきてほしかった)
MSDNで質問してみたら、すぐに回答が付き、理由がわかった
要は GetVersionEx はマニフェストに応じて異なるバージョンを返すということだった(なぜそうしたかの合理的な理由は思い浮かばなかったが、ま、しょうがない)
GetVersionEx の解説
FbConsole が間違ったSQLを提示する
Firebird データベース管理コンソールとして、昔からある FbConsole.exe を使い続けている
これは使いやすく重宝しているのだが、今となってはいくつかバグがあり、注意を要する
1) まず、一旦ログインし、ログアウトするとログインできなくなる (プログラムを起動し直す必要がある)
2) テーブル表示ペインで、UTF-8文字列が化けてしまう
そしてさらに今回発見したのが、メタ情報から取得できるトリガーSQLが、不正な文法になっているケースである
例えば、以下のようなトリガーを作る
これをデータベースのメタ情報SQLで見てみると以下のようになってしまう
どこがまずいかというと、2行目のACTIVE POSITION 0という部分である
この部分は正しくはACTIVE BEFORE INSERT OR UPDATE POSITION 0でなくてはならない
信用してこのまま流してしまうと、エラーとなりトリガーが作成されないままとなってしまう
プログラム自体を直すことは今となってはもう無理なので、手作業で対処するしかない
これは使いやすく重宝しているのだが、今となってはいくつかバグがあり、注意を要する
1) まず、一旦ログインし、ログアウトするとログインできなくなる (プログラムを起動し直す必要がある)
2) テーブル表示ペインで、UTF-8文字列が化けてしまう
そしてさらに今回発見したのが、メタ情報から取得できるトリガーSQLが、不正な文法になっているケースである
例えば、以下のようなトリガーを作る
CREATE TRIGGER MY_TEST_TRIGGER FOR TEST_TABLE
BEFORE INSERT OR UPDATE
AS
BEGIN
new.RecordTimestamp = current_timestamp;
END
これをデータベースのメタ情報SQLで見てみると以下のようになってしまう
CREATE TRIGGER "MY_TEST_TRIGGER" FOR "TEST_TABLE"
ACTIVE POSITION 0
AS
BEGIN
new.RecordTimestamp = current_timestamp;
END
どこがまずいかというと、2行目のACTIVE POSITION 0という部分である
この部分は正しくはACTIVE BEFORE INSERT OR UPDATE POSITION 0でなくてはならない
信用してこのまま流してしまうと、エラーとなりトリガーが作成されないままとなってしまう
プログラム自体を直すことは今となってはもう無理なので、手作業で対処するしかない
2014年06月30日
Firebird テキスト項目に入る数値でソートする (2)
インデックスの張られた項目でソートした場合と、その項目の CAST 値でソートした場合のパフォーマンスを比較してみた
最初が CAST なしで、次が CAST ありである
一目で、約4倍程度の時間を要しているのがわかる
通常は10万件を表示するなんていうことはないので、あまり気になるほどではないかもしれないが、エクスポート処理などでは、この差は大きい
1時間で終わるバッチが4時間かかるとしたら、担当者が怒り狂うだろう
やはり、CAST テクニックはデータセットが小さい場合だけに限定して使うのがいいのだろう
独自SSLが年間18,000円(税抜)。レンタルサーバー『ヘテムル』
最初が CAST なしで、次が CAST ありである
一目で、約4倍程度の時間を要しているのがわかる
通常は10万件を表示するなんていうことはないので、あまり気になるほどではないかもしれないが、エクスポート処理などでは、この差は大きい
1時間で終わるバッチが4時間かかるとしたら、担当者が怒り狂うだろう
やはり、CAST テクニックはデータセットが小さい場合だけに限定して使うのがいいのだろう
独自SSLが年間18,000円(税抜)。レンタルサーバー『ヘテムル』