布団が俺を呼んでいる

丘山大一のぶろぐ

ブログの移行のご案内

長らくご愛顧いただきました当ブログですが、この度移行することにいたしました。

移行先



なぜ移行するのか

このブログ、BlogEngine.NETを使っていたのですが、正直使いにくいところがありました。
ただ個人的な要件があり、それらを満たすものがコレくらいしか見つからなかったということもあり、なんだかんだ だましだまし使ってまいりました。
ですがさすがに限界が来ており、この度Github pagesを利用したブログを開設することにしました。

専用のブログサービスを使わず、Github pagesを使う理由ですが「手元のソースをプッシュして公開する」という形にしたかったからです。
ブログサービスに乗せてしまうと、どうしても記事や構成がサービスに依存してしまい、再度移行したいときに不便そうなのと、サービスの方針に振り回されてしまうのが怖いので、それを避けたいという理由があります。
まあそれはGithub pages を使っても同様なのですが、影響は最小限ですむかなーと考えております。


このブログの今後について

削除する予定は当面ありません。
というより、記事を出力できなかったので移行できない=>削除もできない の流れです。
がっでーむ。
時間が経てば考慮しますが、すくなくとも一年やそこらで削除するつもりはありません。


別ブログで、ということになりますが、今後ともよろしくお願いいたします。

PowerShell ディスクサイズの使用状態をログで吐き出したい

自分メモ。
ディスクサイズの使用状態を日時のログで吐き出す。
実際使う時はタスクスケジューラあたりで呼び出す。

Get-PSDrive -Name C | Select-Object @{Name='datetime'; Expression={Get-Date -Format('yyyy/MM/dd')} } , Used, Free | ConvertTo-Csv -NoTypeInformation |Select-Object -Skip 1 |Out-File -FilePath 'Drive_C.txt' -Append

もっと簡単なやり方があったはずだが、「Windows Server 2008R2で動く」という本来あってはならない要件があり、試行錯誤してた結果こんなんを書いていた。


SSMSで既定の言語を表示した結果とSQLで表示した時に結果が違うことがある

SSMSの表示が正しくないとき(時々あるよね)案件。


問題

SSMSでログインのプロパティを覗いていたら、既定の言語が「Arabic」になっているものがあった。


Arabicかー、珍しいなー、と思ったが引っかかったのでSQLを投げて確認。

select name, default_language_name from sys.server_principals


う~ん、ひとつだけ浮いている方がいますね。
一人だけ素のenglish。ハイ、これがArabicだったログインです。

そしてログインを作っているSQLの中身を見てみたら既定のデータベースを「english」で指定していました。
多分us_englishで指定すべきところをenglishで指定した結果、ログインは作成されたけど言語の一覧にないのでプロパティ画面のコンボボックスがセット処理が正しく走らず、一番上の「Arabic」になったと思われます。
https://docs.microsoft.com/ja-jp/sql/relational-databases/system-compatibility-views/sys-syslanguages-transact-sql?view=sql-server-ver15
※記事投稿時点ではリンク先の表示が崩れてます

ちなみに、他のログインは既定の言語を指定しなかったのでデータベースの規定値を引っ張ってきて正しく設定された模様。


似たようなバグもあったけど

最初、コレかな?と思ったSSMSのバグもあったけどタブン違う。
* https://docs.microsoft.com/ja-jp/sql/ssms/release-notes-ssms?view=sql-server-ver15
* https://feedback.azure.com/forums/908035/suggestions/38236363


教訓

経験上、既定のデータベースの表示がおかしくなることもあるよ!
SSMSは便利だけど、疑問解消・原因調査の際はSQLで!

VBAのプロシージャ呼び出しの括弧のまとめ

VBAでプロシージャ呼び出しの際、引数に括弧をつけるのかつけないのか・つけたらどうなるのかが異様に分かりづらかったので真面目に調べました。
というか自分の整理のためにまとめました。
参考にさせて頂いたのは下記ブログです。
先人の知恵はありがたや~


VBAプロシージャの引数の基本

  • 基本は参照渡し
  • 戻り値を使わないプロシージャ呼び出しは括弧不要
  • 戻り値を使うプロシージャ呼び出しは括弧が必要
  • Call を使う時は括弧が必要
  • Call を使った時は参照渡し
  • 個別に括弧をつけると値渡し


実際の呼び出し


下記のhogeとhoge2という二つのFunction プロシージャの呼び出しパターンとその時の引数の渡し方で試します。
実際にコピペして動作させた方が分かりやい(と思います)。

Option Explicit

' 呼び出すFunction

Function hoge(x As Integer) As Integer
  x = x * 2
  hoge = x + 1
End Function

Function hoge2(x As Integer, y As Integer) As Integer
  x = x * 2
  y = y * 2
  hoge2 = x + y
End Function

' 以下、呼び出し側

Sub fuga()
  Dim a As Integer
  Dim b As Integer
    
  ' 戻り値を使用しない・括弧をつけないで呼び出す。引数は参照渡し。
  a = 3
  hoge a
  MsgBox a ' message 6
  
  ' 戻り値を使用しない・括弧をつけて呼び出す。個別に括弧をつけているので引数は値渡し。
  a = 3
  hoge (a)
  MsgBox a ' message 3
   
  ' Callで呼び出す・引数は参照渡し。
  a = 3
  Call hoge(a)
  MsgBox a ' message 6
  
  ' Callで呼び出す・個別に括弧をつけているので引数は渡し。
  a = 3
  Call hoge((a))
  MsgBox a ' message 3
    
  ' 戻り値を使用する。引数は参照渡し。
  a = 3
  b = hoge(a)
  MsgBox a ' message 6
  MsgBox b ' message 7
  
  ' 戻り値を使用する。個別に括弧をつけているので引数は渡し。
  a = 3
  b = hoge((a))
  MsgBox a ' message 3
  MsgBox b ' message 7
        
  ' Callで呼び出す・引数内部で計算してしまっているので……これは値渡し?
  a = 3
  b = 2
  Call hoge(a + b)
  MsgBox a ' message 3
  MsgBox b ' message 2
  
  ' 戻り値を使用しない・括弧をつけないで呼び出す。引数は参照渡し。
  a = 3
  b = 2
  hoge2 a, b
  MsgBox a ' message 6
  MsgBox b ' message 4
  
  
  ' 戻り値を使用しない・第一引数は括弧をつけているので値渡し。・第二引数は括弧をつけていないので参照渡し。
  a = 3
  b = 2
  hoge2 (a), b
  MsgBox a ' message 3
  MsgBox b ' message 4
    
  ' Callで呼び出す・引数は参照渡し。
  a = 3
  b = 2
  Call hoge2(a, b)
  MsgBox a ' message 6
  MsgBox b ' message 4
  
  a = 3
  b = 2
  ' Callで呼び出す・第一引数は括弧をつけているので値渡し。・第二引数は括弧をつけていないので参照渡し。
  MsgBox a ' message 3
  MsgBox b ' message 4
  
  ' hoge2(a, b) ' 戻り値を使わないのに括弧をつけているので構文はエラー
  ' Call hoge2 a, b  ' Callで呼んでいるのに括弧がないので構文エラー
  
End Sub


ハマりそうなところ


個別に括弧をつけた場合、値渡しになるわけですが、これプロシージャの定義がByRef でも上書きされるんですよね。
これは参考元の方に書かれていますが、単に先に評価しているからなのでしょうね。

という理屈は分かった気になりましたが、やっぱり分かりづらいです。


2020/2/19 :間違いがあったので修正

.Net Core で GetObject したいのですが

どうすればいいざんしょ?


経緯

.Net Core がWPF 対応したことだし、手元の古いアプリの移行可能性を検討しようと思い立つ。
で、そのアプリはサードパーティのComライブラリを呼び出している。
で、既存の動きに合わせてMicrosoft.VisualBasic.Interation からGetObjectを呼び出そうとしたら……あれ、無い?
ドキュメントにあたると、たしかに.Net Core の記述がない。


調査する

でがらし会で情報を持っている人募集。で、この人https://twitter.com/kowillmから情報がくる。

実装自体は進んでいるような感じ。
ただ、Not Tested ともある通り、完成していない感じはある。

実装もある程度進んでいる雰囲気はある。

しかし手元の.Net Framework の dllの中身と比較すると実装が異なる、というか足りない感じ。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll


さてどうしよう

VisualBasic.dll の実装自体は(こう言ってはなんですが)意外と活発に見えます。
しかし最新のパッケージが2018/12/3と一年以上前であり、リリースできる状態までこぎつけていないのか、あるいはリリースを一時中断する理由があるのか判別がつかない。
というのも、ない理由が「仕掛りなだけ」ならいいのですが、「他のdllにメソッドを移植した」「.Net Core では別実装を検討中」「問題が見つかった」「.Net Coreで実装すべき機能ではない」などの理由だと(検証的に)困っちゃうんですよね。
.Net Core へのVB関連の取り組みがあまりされていない感じもあり、またWinFormに依存する部分は含めない的な方針もあるようで……Windowsのための実装のcom系に使われる機能はどういう取り扱いになるのか不透明&不透明。
Marshal.GetActiveObject がないから、というのも理由の一つな気もしますが。

無ければ作ればいいじゃないの精神で、必要な部分だけ引っこ抜いて個別実装してもいいのですが、「まだ無い」理由が分からないと徒労に終わる可能性も高いので、なかなか踏ん切りがつきません。
該当部分は.Net Frameworkで作れ! が正しいとも考えられますし。

どういう状況なんでしょ。

コミックマーケット C97 参加はしないけど書いたよ

宣伝宣伝。

今回は行きませんが、原稿は書きました。
サークル代表が頒布しているはず。

火曜日 南地区”リ” ブロック 26a
だそうです。

よろしくお願いします。

Oracle DBリンク関連の情報を取得

自分メモ。
DBリンクを呼び出す処理を見ることになったのですが、機能が独特でよく分からん。
基本的にデータベース同士を密結合する機能なのであまり使うべきではないかな、という感じもしている。

色々取得


1.DBリンクの取得

SELECT * FROM ALL_DB_LINKS

2.DBリンクのパッケージ確認

SELECT * FROM ALL_OBJECTS@DBリンク名 WHERE OBJECT_TYPE = 'PACKAGE'


3.パッケージの中身を確認

SELECT TEXT FROM all_source@DBリンク名 WHERE NAME = 'パッケージ名' ORDER BY LINE

PowerShell 二行を一行にまとめる

自分メモ。
うまく言えないんですが、
aaa
bbb
ccc
ddd
というテキストを
aaa bbb
ccc ddd
に変換してファイル出力する感じ。


こんなん

$originalFilePath="hogehoge.txt"
$filePath = "fugafuga.txt"
[int]$count=0
Get-Content $originalFilePath | ForEach-Object {
  $count+=1
  If($count % 2 -eq 0){
    Write-Output($_) | Out-File -FilePath $filePath -Append -Encoding utf8
  }else{
    Write-Output($_ + "`t") | Out-File -FilePath $filePath -Append -NoNewline -Encoding utf8
  }
}

管理者ユーザなのにexeファイルのファイル操作できなくなる現象

exeファイルのプロパティのセキュリティにアクセスできなくなる現象とも。
実害が出るレベルではまりました。


現象

ファイルを削除しようとすると、
「このファイルを削除するには管理者の権限が必要です」→「続行」→
「この操作を実行するアクセス許可が必要です」→「再試行」→
以降ループするので「キャンセル」せざるをえなくなる

リネームしようとすると、
「このファイルの名前を変更するには管理者の権限が必要です」→「続行」→
「この操作を実行するアクセス許可が必要です」→「再試行」→
以降ループするので「キャンセル」せざるをえなくなる

実行しようとすると、
「指定されたデバイス、パス、またはファイルにアクセスできません。これらの項目にアクセスするための適切なアクセス許可がない可能性があります」
で、メッセージ内容から「セキュリティが変なのか……」と考えファイルのプロパティからセキュリティを
開くと、たしかに権限がふられていない。ファイルの所有者の所有者も見えない。
しかし、権限をふろうとしても権限をふれない。

どういうこっちゃねん。


原因

他のユーザがexeファイルをロードしている状態で、さらに別ユーザがexeファイルを削除していたため。


原因詳細

エクセルファイルなんかで「別のプログラムがファイルを開いているので操作を完了できません」を見ることがあった人も
多いと思いますが、その複雑版です。共有フォルダに配置した、複数のユーザがたたくexeファイルで起きました。
登場人物は下記。

  • Aユーザ:exeファイルを実行していた人
  • Bユーザ:exeファイルを先に削除した人
  • Cユーザ:管理者であり、exeファイルを削除したい人

Aユーザは、Cユーザのマシン内の共有フォルダに入ったexeファイルを実行しています。起動後なので、exeはロードが終わった状態です。
続いて Bユーザは、そのexeファイルを削除します。Aがexe実行中でもファイル削除できます(Bのエクスプローラからは消える)
最後にCユーザが共有フォルダに入ったexeファイルを削除を実施しますが上記「現象」にはまり何もできなくなります。
Cマシン内の共有フォルダにあるexeは、Bによって削除された亡霊みたいな状態。


対応

exeにアクセスしている人を強制的に全部切断すれば解消されます。
というか先に切断しておきましょう。


泣き言

これWindowsのバグでは、という気がしなくもない。けど何かしら事情があってこうなっている気もする。

WSL でGitbucket環境構築

ちょっとした個人用リモートリポジトリが欲しい時は、Gitbucketを構築しています。
Gitbucketは動かすだけならjavaさえあればよいので、Windowsでもお手軽です。
が、逆にいえばjavaを入れなければなりません。
これが嫌だなー、という人は仮想環境を作るなりDockerで構築するのがよいと思うのですが、今回はWSLでやっていきます。

理由:現在使用中の環境のうち一つで、Dockerサービスが動かなくなったので(泣)

手順

使用環境はストアから入手したUbuntu。

まずはJavaをインストール。
sudo apt install default-jdk

インストール完了後、バージョン表示してインストール確認。
java -version

Gitbucketを入れるためのディレクトリを作成。
sudo mkdir /opt/gitbucket

Gitbucketをダウンロード。
sudo wget https://github.com/gitbucket/gitbucket/releases/download/4.32.0/gitbucket.war -P /opt/gitbucket

さて、後はgitbucketを動かせば完了なのですが、このままではWSL内にファイルを保持してしまいます。
そしてWSLの環境はリセットをすることがありますので、油断するとファイルが失われてしまいます。
これを防ぐため、Windows側でファイルの保存フォルダをあらかじめ作成しておきます。
今回は
D:\WSL\Ubuntu\GitBucket
というフォルダを作成しておきました。

さて、再びWSLに戻り、起動用ファイルを作成します。
叩きやすい場所に作るのがよいと思いますが、今回は/opt/gitbucket 内に作成しました。
sudo vi startgitbucket.sh

startgitbucket.shに、下記の内容を記述します。
java -jar /opt/gitbucket/gitbucket.war --port=8600 --gitbucket.home=/mnt/d/WSL/Ubuntu/GitBucket
ポートも指定していますが、ポートは空いている番号なら何番でもOKです。
今回はなんとなく8600番を指定しました。

最後に、実際に起動して完了。
sh startgitbucket.sh

http://localhost:8600/ にブラウザでアクセスすれば、動いているのが確認できます。



よりよい方法

この方法だと、いちいちファイルをたたいて起動しなくてはならないため、サービスとして登録した方がよいと思います。
が、そのあたりよく分からないしよけいに面倒くさいは今回触れません。あくまで「簡易のちょっとした」環境整備です。


さらによりより方法

素直にgithubなりなんなりでリモートリポジトリを用意した方が楽だよ!


独習Git

新品価格
¥3,542から
(2019/8/25 14:47時点)