2017年5月9日火曜日

ClickOnce がとつぜん

ClickOnece で組んであったシステムが突然以下のようなエラーを吐いて動かなくなってしまった。

複数台の端末で同じ実行環境を作ってあった内の数台でダメ。
サーバー自体で起動した場合は普通に起動する。

怪しいのは1か月ぐらい前に、ウィルス対策ソフトを入れ替えたこと。
マカフィーからカペルスキーに。

でも、すべての端末は同じ環境なのに、なぜ?
しかも、ダメな端末も朝一は正常起動していたのが、途中で端末の電源を入れなおした後からダメになったような気がする。

やはりカペルスキーか?
ということで、ダメな端末の内の1台で、カペルスキーをアンインストールして実行してみたけど、たっぱりダメ。

一晩ネットを彷徨ったら、やはりウィルス対策ソフトで ClickOnece がダメになった例が報告されていることを発見。

そこで、カペルスキーのログを確認したところ、ありましたありました。
システムの実行ファイルを隔離してやがった。

まだカペルスキーを削除していない端末は、カペルスキーのインターフェースを使って、隔離ファイルを復元し、実行ファイルのあるフォルダをスキャン対象から除外する設定を施したら、普通に起動するようになった。

カペルスキーをアンインストールしてしまった端末は、隔離されたファイルを復元する方法がないので、別の端末のログを参考に実行ファイルを本来のフォルダにコピーして復元。
ところが、この実行ファイルはカペルスキーが確実にウィルス扱いするので、コピーする際に、大元のClickOnece配信サーバーから一旦中間サーバーを経由してダメ端末にコピーしようとすると、その中間サーバーにカペルスキーが居るので即座に駆除(隔離)してしまうので、手動でコピーしようとした瞬間に駆除されるというのを数回繰り返してしまった。
別のルートを使ってなんとかコピーして、正常起動を確認。

正常起動してた端末でも同じようにカペルスキーが入っていて、同じ辞書ファイルが配信されているのに、なぜ正常起動していたのかは不明。
もしかしたら、辞書ファイルの配信が上手くいってなかったのかも。(それはそれでもっと問題ありかも)

また、配信サーバーには偶然カペルスキーを入れていなかったので、大元の構造は破壊されていなかったのはラッキーでした。

マカフィーの時はそんなことなかったのに、カペルスキーにしてから約1か月でアウトとは、カペルスキーの技術力に問題ありなんじゃないの?

今回起動しなかったのはほんの2~3台だったのと、このシステムを利用している端末が10数台だけだったので軽症で済んだけど、ネットワーク自体は100台以上規模なので、もしもっと重要なファイルをカペルスキーが勝手に駆除しちゃうと、大打撃となる可能性があります。

----------------------------- Error LOG -------------------------------------
PLATFORM VERSION INFO
Windows : 6.1.7601.65536 (Win32NT)
Common Language Runtime : 4.0.30319.18444
System.Deployment.dll : 4.0.30319.18408 built by: FX451RTMGREL
clr.dll : 4.0.30319.18444 built by: FX451RTMGDR
dfdll.dll : 4.0.30319.18408 built by: FX451RTMGREL
dfshim.dll : 4.0.41209.0 (Main.041209-0000)

SOURCES
Deployment url :serverURL
Server : Microsoft-IIS/8.5
X-Powered-By : ASP.NET
Application url :serverURL
Server : Microsoft-IIS/8.5
X-Powered-By : ASP.NET

IDENTITIES
Deployment Identity : appname.Application.app, Version=1.9.0.2, Culture=ニュートラル, PublicKeyToken=4cf906, processorArchitecture=msil
Application Identity : appname.Application.exe, Version=1.9.0.2, Culture=ja, PublicKeyToken=4cf906, processorArchitecture=msil, type=win32

APPLICATION SUMMARY
* Online only application.
* Trust url parameter is set.
ERROR SUMMARY
Below is a summary of the errors, details of these errors are listed later in the log.
* Activation of ServerURL resulted in exception. Following failure messages were detected:
+ Activation failed.
+ アクセスが拒否されました。 (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

COMPONENT STORE TRANSACTION FAILURE SUMMARY
No transaction error was detected.

WARNINGS
There were no warnings during this operation.

OPERATION PROGRESS STATUS
* [2017/04/18 10:04:40] :

ERROR DETAILS
Following errors were detected during this operation.
* [2017/04/18 10:05:12] System.Deployment.Application.DeploymentException (Activation)
- Activation failed.
- Source: System.Deployment
- Stack trace:
--- Inner Exception ---
System.UnauthorizedAccessException
- アクセスが拒否されました。 (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
- Source: System.Deployment
- Stack trace:
at System.Deployment.Application.NativeMethods.CorLaunchApplication(UInt32 hostType, String applicationFullName, Int32 manifestPathsCount, String[] manifestPaths, Int32 activationDataCount, String[] activationData, PROCESS_INFORMATION processInformation)
at System.Deployment.Application.ComponentStore.ActivateApplication(DefinitionAppId appId, String activationParameter, Boolean useActivationParameter)

2017年3月18日土曜日

sp_executesql でパラメーターを変更しながらSQL文を実行

SQLServer の話題です。

ストアドで動的に作成したSQL文を実行したい場合に有効な手段です。

Execute sp_executesql @実行したいSQL文,
                                 @SQL文の中で使うパラメーターの型宣言,
                                 @パラメーターそれぞれの内容

という構文になります。

実際には、
-------------------------------------------------------------------
Declare @strSQL nvarchar(1000)
Declare @prm nvarchar(1000)
Declare @A_MAX

Set @strSQL = 'Select @prm_MAX = MAX(ColA) as A_MAX From T_tableA Where ColB = @prm_B'
Set @prm = '@prm_MAX int OUTPUT ,@prm_B nvarchar(200)'

execute sp_executesql @strSQL,@prm,@prm_MAX = @A_MAX OUTPUT,@prm_B = '東京都'

Select @A_MAX as ColAの最大

-------------------------------------------------------------------

主となるSQL文(@strSQL)内で、パラメーターを2個使う例です。

1個は ColAの最大値を求めて、表示するための @prm_MAX、
もう1個は、条件で使用するための @prm_B

@prm は主となるSQL文内で使うため専用の宣言を行うパートです。
executesql 専用 Declare って感じですね。

この例では、@prm_MAX を外に出しますので、「OUTPUT」を付けます。

execitesql の最後のパートは、SQL文内で使うパラメーターの実際の値を書きます。
ここでも、外に出すパラメーターには「OUTPUT」を付けます。
ここで勘違いしやすいのが、赤で塗ってある部分です。
普通の変数に値を代入する感覚では、「@A_MAX = @prm_MAX」となるのですが、ここでは、SQL文内のパラメーターを中心に考えるので、逆に書くことになり、
「@prm_MAX = @A_MAX」で正解です。
これで、@A_MAX に@prm_MAX の内容が代入されます。なんか変な感じですね。

@prm_B は簡単ですね。

最終的に、SQL文内で使ったパラメーターはあくまでも内部専用のパラメーターですから、外部に出してくるための@A_MAX は事前に Declare で宣言が必要です。

当たり前ですが、SQL文内にあるパラメーターの個数と、宣言文内での個数と、実際の値を与えるパートの個数が一致しないとエラーになります。








2017年1月28日土曜日

SQLServer 2008 から Merge が使える

久しぶりに本題のSQLServer です。

今まで知りませんでした。
MERGE文が使えるんですね。

SQL と言えば、言わずもがな「Select」「Insert」「Update」「Delete」の4文が基本です。
例えば、Table_A と、ほぼ同じ構造を持った Table_B があって、
必ずTable_Aが最新になっているとします。

最新になっているというのは、

1、レコードが増えている。
2、レコードが減っている。
3、レコードが更新されている。

とうことが考えられます。

この状態をTable_Bに反映させる。
例えば、夜間バッチでTable_Bを最新状態にする必要がある場合が想定されます。

今までなら、
Table_Bに不足しているレコードを特定して、Insert文を発行。
Table_Aには無いレコードを特定して、Delete文を発行。
Table_AにもTable_Bにもあるが、更新されているレコードに対して、Update文を発行。
と3回の比較処理を走らせる必要があるので、
大量のレコードの場合に、莫大なコストが必要になることがありました。

これを1回の比較で処理してしまうのが、Merge です。
まあ、言葉の意味のままのステートメントです。

私の場合、ORACLEにあるテーブルをそのままSQLServerに毎日夜間バッチでコピーしたいのですが、総レコード数は40万件以上あるのに、更新または追加されるのは、わずか1000件程度。
その1000件を最新に保つために、 Truncate で全消し、Insert で全書きをしていましたが、あまりにも非効率なのと、ディスクにも負担をかけると思います。

そこで考えたのが、リンクサーバーでORACLEに接続して、OpenQuery を発行します。
その際、更新年月日を参照して、前回処理日以降だけに絞る Where句を付けておきます。
OpenQuery なので、条件が入っても、ORACLE側で高速に処理されて返ってきます。
これで1000件程度のレコードが返ってくる。

これを一旦 Select Into ##tempTable で仮テーブルに保管して、SQLServer 側の本来保管したいテーブルと比較して、 MERGE 処理を行うことにしました。

毎日数分かかっていた処理が、数秒で完了するようになりました。

MERGE の構文自体は、他の方がたくさん例を挙げていただいているので、私は省略です。

でも、1行で書けるといっても、結構手間の必要な構文になります。

比較は1回ですが、マッチした場合の動作(通常は UpDate になるかな。)と、アンマッチの場合の動作を(私の場合は、Insert ですが、 場合によっては、 Delete になる。)それぞれ書かないとダメです。
まあ、当たり前と言えば当たり前ですけどね。

特に、 UpDate の場合は、カラムを全部書かないと(しかも、元と先の両方を書かないと)ダメなので、カラム数の多いテーブルだと、長ーい構文になっちゃいます。







UQモバイルで SIMロック解除が必要

auからUQモバイルに乗り換えを考える場合、SIMロック解除が必要なのかどうかがよく理解できていませんでしたが、身をもって確認できました。

確認したのはXperia 限定のことです。

2016年11月ごろに中古市場で au仕様のXperia Z1 (SOL23) を購入しました。新品未使用状態です。
すぐに UQモバイルに申し込み、数日でSIMが到着。
本体にSIMをセットしてAPNを設定したらすぐに使えました。
「なーんや、SIMロック解除って必要ないやん。」

これは、au仕様の端末でUQモバイルのSIMだから解除が必要ないんだと解釈しました。

これに気をよくして、今度は2016年末に同じくau仕様の Xperia Z4(SOV31) を、これまた中古市場で、新品未使用品を購入しました。
お値段は33000円ぐらいだったと思います。

これも早速 UQモバイルの SIM を挿しましたが、今度は通信できません。
なんで?同じ au仕様で UQモバイルやから問題ないはず。
とおもったのですが、大きな勘違いでした。

au仕様の端末で UQモバイルのSIMを使う場合で、ロック解除が不要のまま使えるのは、Z1が最後の機種のようです。
Z1以降に発売された端末は SIMロック解除が必要だそうです。

20170627訂正
Z3もロック解除必要なしが確認できました。
因みに、Z2 Tablet もロック解除必要なしが確認できました。

なんか、総務省かなんかが SIMロック解除を命令したようですが、逆に邪魔臭くなってるような気がする。

おかげで、(私は)年末に買ったのに、最初の所有者が購入した後、6ヶ月間は解除できないので、私の場合、2月初旬まで解除できません。
今のところ、UQの契約はしたままなので、月額1000円を捨てているような状態。(通信していないので、月3Gの容量をどんどん持ち越していて、2月に使えるようになったら、9Gぐらいからスタートすることになります。)

20170627訂正
UQMobileの持ち越しは1ケ月分だけでした。
なので、MAXでも6Gにしかなりません。

Z4自体は前に使っていたスマホ(Xperia UL SOL22)をUQモバイルで契約して、それにBluetoothでWIFI接続して使っています。

2月になればすぐにロック解除するつもりですが、これまた、auのサイトを読んでいると、契約者でないとネット解除できないような感じ。
ということは、auショップに持ち込んで3000円払って解除してもらわないとだめなのか~。


2016年12月24日土曜日

KODI のビデオ字幕設定

KODI 活躍してます。
Raspberry PI3 にも、Windows のノートパソコンにも、Android スマホにも入れています。

ところが、先日スマホを新しくしたので、同様にKODIをインストールして、ビデオの字幕設定を OpenSubTitles.comに設定したら、「IDとパスワードを入れないと見せないよ。」というようなメッセージがでて、字幕の自動表示ができません。

Raspberry PI とかも同じ OpenSubTitlesにしているのに、そんなメッセージはでません。もちろん、OpenSubTitlesには登録していないので、IDもパスワードも持っていません。

色々彷徨ったら、KODIのAdd-On設定で、Install From Repository から入って、OpenSubTitless を選択するとこうなるようです。

代わりに、 Install From ZIP file を選択して、OpenSubTitles を選んでインストールすれば、今まで通り、字幕が自動的に表示されるようになりました。

まずは、以下のサイトからZIPファイルをダウンロードして、任意のフォルダに保管しておいて、Install From ZIP file からそのZIPファイルを指定すればインストールできます。

http://www.opensubtitles.org/addons/kodi/service.subtitles.opensubtitles_by_opensubtitles.zip

ID パスワード無しでの字幕表示なので、広告が出るのは仕方ないですね。


UQモバイルで3台目の契約ができない

先日、UQモバイルを契約するのに、エントリーパッケージを入手することで、事務手数料を安く契約することができると書きましたが、大失敗です。

というのも、私は、自分で使っている古いスマホをUQにしてから、つい先日、子供に使わせているiPhoneもUQに乗り換えました。
これでUQの契約が2台分となっています。

今回購入した Xperia Z4 をUQで契約しようとして、エントリーパッケージを購入して、いざネットで契約手続きをしたら、なんと!「総合的に判断した結果、今回の契約はキャンセルさせていただきます。」という内容の返事が返ってきた!

クレジットカードの契約じゃないんだから審査とか関係ないでしょ!と思って、UQに電話したら、「3台目以降は、最後の契約から90日を経過しないとご契約できません。」やって。
そんなんどこに書いてあるねん!

仕方ないので、嫁さんの名義で契約しました。

因みに、最大契約数は5台だそうで、同一名義では6台以上の契約はできないそうです。

2016年12月17日土曜日

UQモバイルの新規申し込み

 スマホ2台持ちで、格安SIMは一度Mineoにしましたが、どうも速度が出ないので、同じAU系のUQモバイルに変更しました。
 すでに、自分のXperia UL (SOL22)と子供のiPhone 6 の2台分契約しています。
 どちらも高速データ通信のみで、月額980円(税別)です。 

 iPhone 6 を契約する際には、iPhone 6 が対応しているかどうか不安があったので、一旦 TRY UQモバイルでお試しSIM を借りました。
 案の定、返してからはTRYからじゃんじゃん勧誘の電話がかかってきて、仕方なく電話で本契約をしました。

今回、自分用のXperia がちょっと調子が悪くなってきたので、新調することにしました。
端末は Xperia Z3 以降の機種でいろいろ探したところ、楽天で Xperia Z4 の白ロム(新品未使用)が33,000円で見つかったので、それを購入。

今使っている Xperia UL も移行作業などで UQ の回線を使うと思い、新端末用にUQ を新規契約することにしました。

他のネットショッピングで徘徊していたところ、偶然、ジョーシンWEBで UQモバイルの「エントリーパッケージ」なるものを発見。

本来、UQの新規申し込みは、3,000円の事務手数料が必要になりますが、このエントリーパッケージを買えば、事務手数料が無料になります。
ジョーシンWEBでのエントリーパッケージは1,200円で購入できますので、1,800円ほどお得になります。
もうほとんど購入ボタン押しかけていたんですが、別途送料が必要になることが分かり、他の何かと一緒に買おうと思い、一旦保留に。

そこで、はたと思いつき、ジョーシンで売ってるのなら、楽天やAmazon にもあるのでは?

検索したところ、見つかりましたよ~。

楽天で、なんと800円!しかも送料無料!
株式会社ジェイネット 88モバイル
http://www.rakuten.ne.jp/gold/hachihachimobile/wimax/wimax.html

これで、2,200円の節約になりました。

20170627追加情報
Amazonで、データ通信専用なら500円で入手できました。
BIGLOBE UQ mobile データSIM専用エントリーパッケージ au対応SIM(ナノ/マイクロ/標準SIM/VoLTE) VEK55JYV