テンプレートテスト
ブログの説明
ブログの説明2
menu
keyboard_arrow_up
Top
search
close
home
ホーム
computer
PC一般
construction
開発環境・ツール
code
プログラミング
home
ホーム
computer
PC一般
construction
開発環境・ツール
code
プログラミング
Home
›
Archives for 2020
2020/12/14
Interop.WordDocuments.Open が null になる
update
event_note
label
Excel
label
PowerShell
label
Word
PowerShell で Word から PDF へ変換しているのですが、そのスクリプトが環境によっては動かないことがありました。
## 環境 - Windows 10 64 bit - Microsoft Word 2013 32 bit 今回、Office を 2010 から 2013 にアップグレードしており、結果的にはそれが原因だった可能性が高いです。 ## 先に結論 Office の修復を実行したら解決しました。 - https://www.google.com/search?client=firefox-b-d&q=Office+%E3%81%AE%E4%BF%AE%E5%BE%A9 これで直らなかったら次は再インストールを試そうとしてました。 ## エラーの内容と原因の特定まで エラーの内容ですが、具体的には、`Microsoft.Office.Interop.Word.Application` で `Documents.Open` を参照したときに、`null 値の式ではメソッドを呼び出せません。` というエラーが表示されました。 デバッガで止めて確認してみると、そもそも Word のインスタンスを作成する以下のコードで `$null` が返ってきているようでした。 ``` $word = New-Object -ComObject Word.Application; ``` 尚、PowerShell で上記のコマンドを直接実行すると成功しました。 あくまで ps1 ファイルに保存してスクリプトを実行した場合にのみ失敗していました。 とりあえずググってみると、似たような事例がいくつかヒットしますが、その対策として挙げられていたのは、`C:¥Windows¥SysWOW64¥config¥systemprofile` に `Desktop` という空のフォルダを作成するというものでした。 - https://stackoverflow.com/questions/10837437/interop-word-documents-open-is-null しかし、今回の場合、これでは直りませんでした。 ## レジストリの確認 もう少し調べてみると、以下のページに行き着きました。 - https://www.alkanesolutions.co.uk/2019/04/18/you-cannot-call-a-method-on-a-null-valued-expression/ どうやら、どの Office を使用するかはレジストリで確認できるようです。 というわけで、レジストリエディターを起動し、以下のキーを検索してみました。 `HKEY_CLASSES_ROOT\WOW6432Node\Interface\{00020970-0000-0000-C000-000000000046}\TypeLib` すると、正常にスクリプトが動作する環境では以下のように値が表示されるのですが、エラーが発生する環境ではキーが見つかりませんでした。
従って、レジストリの値がおかしいのではと思い、Office の再インストールをやってみようと思いました。 そして、Office の再インストール前に、Office の修復を試したところ、それで直りました。 いや、これめっちゃはまりましたわ。
## 参考 URL - https://www.alkanesolutions.co.uk/2019/04/18/you-cannot-call-a-method-on-a-null-valued-expression/ - https://support.upslide.net/hc/en-us/articles/214269046-UpSlide-Issues-when-upgrading-Office - https://elleneast.com/?p=866 - https://stackoverflow.com/questions/10837437/interop-word-documents-open-is-null - https://x6lgplfk4z24e4vc3x3qgmhzwa--superuser-com.translate.goog/questions/1361627/calling-documents-open-for-word-application-error-converting-msofalse-to-type-ob - https://python5.com/q/zescatei - https://www.ibm.com/support/knowledgecenter/ja/SS6RHZ_2.1.1/com.ibm.rational.pe.troubleshooting.doc/topics/t_macro_execution.html
Read more
2020/11/20
image
NO IMAGE
[C#] 2つのリストを結合して1つの新しいリストにする
update
event_note
label
C#
`AddRange` などでもリストの結合はできますが、片方のリストをもう片方に結合する形になるので、そうではなく、2つのリストをまとめて1つの新しいリストにする方法です。
以下のように、リストの配列を作り、`SelectMany` で平準化することで簡単にできます ``` var list1 = new[] { 1, 2, 3, 4 }; var list2 = new[] { 5, 6, 7, 8, 9 }; var newList = new[] { list1, list2 }.SelectMany(_ => _); Console.WriteLine(string.Join(",", newList)); ``` **出力結果** ```sh 1,2,3,4,5,6,7,8,9 ```
## 参考 URL
Read more
2020/11/19
image
NO IMAGE
[C#] 配列やリストが昇順 or 降順になっているかどうかを調べる
update
event_note
label
C#
`OrderBy` と `SequenceEqual` を使えば簡単にできます。
```cs list.OrderBy(x => x).SequenceEqual(list) ``` 降順の場合は `OrderByDescending` を使います。
## 参考 URL - https://stackoverflow.com/questions/23562150/linq-expression-to-validate-if-list-is-ordered-ascending-or-descending/23562239 - https://stackoverflow.com/questions/1940214/how-to-check-if-a-list-is-ordered
Read more
2020/11/18
image
NO IMAGE
gitbook のプラグインのバージョンを指定する
update
event_note
label
GitBook
gitbook のビルドが急に通らなくなったのですが、プラグインのバージョンが上がったことが原因でした。
プラグインをバージョンまで指定して追加する場合は、`book.json` で以下のように記述します。 ``` { "plugins": ["myPlugin@0.3.1", "anotherPlugin"] } ```
## 参考 URL - https://gitbookio.gitbooks.io/documentation/content/format/plugins.html
Read more
2020/10/22
image
NO IMAGE
gitlab-ci で git の submodule をアップデートしたい場合
update
event_note
label
GitLab
GitLab と gitlab-runner を使って CI を行っている場合、リポジトリをクローンしてくる際にサブモジュールのアップデートも行うにはどうすれば良いか?
参考 URL に書いてあるままですが、gitlab-runner が v1.10 以上であれば、`.gitlab-ci.yml` に以下の変数を定義すれば OK です。 ``` variables: GIT_SUBMODULE_STRATEGY: recursive ``` 古いバージョンであれば、`.gitlab-ci.yml` に以下のスクリプトを記述するそうです。 ``` before_script: - git submodule sync --recursive - git submodule update --init --recursive ```
## 参考 URL - https://docs.gitlab.com/ee/ci/git_submodules.html
Read more
2020/10/09
image
NO IMAGE
[ASP.NET Core] Form value count limit 1024 exceeded のエラーが発生した
update
event_note
label
ASP.NET Core
label
C#
`form` で `submit` した際に `Form value count limit 1024 exceeded` のエラーが表示されました。
フォームで送信する値の数が上限である 1024 を超えたために発生したようです。 ## 環境 - Visual Studio 2017 - .NET Core 2.2 ## 対処方法 フォームで 1024 以上も値を送るような設計がそもそもおかしいとか、いろいろあるとは思いますが、とりあえず上限を変更することで対応可能です。 Post を受け取る Controller に `RequestFormLimits` の属性を追加することで上限は簡単に変更できます。 ```cs [HttpPost] [RequestFormLimits(ValueCountLimit = 2048)] public IActionResult Index(Hoge hoge) { // Do something } ```
## 参考 URL - https://www.366service.com/jp/qa/0b21184f67097eff65ca439f3a833ec6
Read more
2020/10/08
image
NO IMAGE
外部 DLL を NuGet パッケージに含める方法
update
event_note
label
.NET Core
label
.NET Standard
label
Visual Studio
C/C++ で作成された外部の DLL を C# から扱うためのラッパーを作成して NuGet パッケージとして公開しようとしていたのですが、その外部 DLL 自体も NuGet パッケージに含める方法について調べてみました。
## 環境 - Visual Studio 2017 - .NET Core 2.2 ## 方法 ググってみるとまさにそのものが書いてある以下のページが見つかりました。 - https://blog.okazuki.jp/entry/2019/09/28/145646 しかし、これだけではいろいろはまったので、追記・補足しておきます。 ### PackagePath について 出力先となる `PackagePath` のディレクトリ名には `lib` を指定する必要があるようです。 指定しなかった場合、以下の警告が表示されました。 > warning NU5100: The assembly 'foo.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project. Move it into the 'lib' folder if it needs to be referenced. さらに、`lib` だけだと以下のエラーが表示されました。 > warning NU5103: The folder 'lib/foo.dll' under 'lib' is not recognized as a valid framework name or a supported culture identifier. Rename it to a valid framework name or culture identifier. `lib` の下にはフレームワーク名またはカルチャー名のディレクトリを指定する必要があるみたいです。 ```xml
``` また、 このフレームワーク名またはカルチャー名以下の階層が、作成した DLL と同じ階層に作られるようです。 例えば、作成した DLL が `sample.dll` だとして、外部の DLL を以下のように設定してパッケージに含めた場合、 ```
``` NuGet パッケージインストール後の配置は以下のようになります。 - sample.dll - foo\x64\foo.dll - foo\x86\foo.dll ### 外部 DLL を出力ディレクトリにコピー 外部 DLL を出力ディレクトリにコピーするには、Visual Studio で該当の DLL を右クリックし、`出力ディレクトリにコピー` の項目を `新しい場合はコピーする` (または `常にコピーする`) に設定しておく必要があります。 手動で `.csproj` ファイルを修正する場合は以下を追加します。 ```xml
PreserveNewest
``` ### publish 時に出力先ディレクトリに外部 DLL がコピーされない この外部 DLL を含んだ NuGet パッケージを使っているアプリケーションにおいて、`dotnet publish` コマンドを実行しても外部 DLL が出力先の `publish` ディレクトリにコピーされませんでした。 `publish` 時に出力ディレクトリに外部 DLL をコピーするためには、まずライブラリ側(NuGet パッケージにするほう)の `.csproj` ファイルに以下を追加します。 ```xml
true
``` しかし、これを `PackagePath` で `lib` を指定している箇所に指定しても上手くいきませんでした。 `PackagePath` を指定しなかった場合、該当のファイルはコンテンツとして追加されるようなので、そこに `PackageCopyToOutput` を設定すると上手くいきました。 具体的には以下のような感じです。 ```
true
true
``` これが一番はまりました。 ## 最終的に作成した設定 上記を踏まえ、最終的に `.csproj` ファイルの設定は以下のようになりました。 ```
true
PreserveNewest
true
PreserveNewest
```
## 参考 URL - https://blog.okazuki.jp/entry/2019/09/28/145646 - https://docs.microsoft.com/ja-jp/nuget/reference/msbuild-targets - https://docs.microsoft.com/ja-jp/nuget/consume-packages/package-references-in-project-files - https://stackoverflow.com/questions/42862739/how-to-copy-files-to-output-directory-from-a-referenced-nuget-package-in-net-co - https://docs.microsoft.com/ja-jp/nuget/reference/nuspec
Read more
2020/09/24
image
NO IMAGE
/platform:anycpu32bitpreferred は、/t:exe、/t:winexe、/t:appcontainerexe でのみ使用できます。
update
event_note
label
Visual Studio
xunit.runner.visualstudio をアップデートしたら以下のエラーが表示されるようになりました。
``` /platform:anycpu32bitpreferred は、/t:exe、/t:winexe、/t:appcontainerexe でのみ使用できます。 ``` ## 環境 - Visual Studio 2017 - xunit.runner.visualstudio 2.4.3 ## 対処方法 テストプロジェクトの `.csproj` ファイルをテキストエディタで開き、`
true
` の記述を削除します。
## 参考 URL - https://stackoverflow.com/questions/25528933/platformanycpu32bitpreferred-is-not-a-valid-setting-for-option-targetlibrary
Read more
2020/09/11
image
NO IMAGE
GitLab のログをローテーションに設定する
update
event_note
label
GitLab
GitLab のログが肥大化していたので、ログをローテーションするように設定しました。
GitLab は docker で動かしています。 - http://kuttsun.blogspot.com/2016/09/dockergitlab.html この `docker-compose.yml` に以下の記述を追加しました。 ```yaml GITLAB_OMNIBUS_CONFIG: | # 中略 logging['logrotate_frequency'] = "weekly" logging['logrotate_rotate'] = 10 logging['logrotate_compress'] = "compress" logging['logrotate_method'] = "copytruncate" ``` 詳細は参考 URL をご参照ください。
## 参考 URL - https://docs.gitlab.com/omnibus/settings/logs.html - http://hermesian.hatenablog.com/entry/2018/05/03/235255
Read more
2020/09/08
image
NO IMAGE
[ASP.NET Core] 前のページ(遷移元)の URL を取得する
update
event_note
label
ASP.NET Core
単純に前のページに戻りたいだけなら JavaScript でも使ったほうが楽ですが、サーバーサイドで何らかの処理を行いたい場合には以下のようにして取得できます。
## 環境 - Visual Studio 2017 - .NET Core 2.2 ## サンプルコード Controller 内で `Request.Headers["Referer"]` で取得できます。 View で使用したい場合は `ViewData` などで渡してやります。 ```cs // Controller if(Request.Headers["Referer"].Any()) { ViewData["Referer"] = Request.Headers["Referer"].ToString(); } ``` ```html @if (!string.IsNullOrEmpty(ViewData["Referer"]?.ToString())) {
Back
} ```
## 参考 URL - https://stackoverflow.com/questions/42223642/return-to-previous-page-in-asp-net-core-mvc
Read more
2020/08/21
image
NO IMAGE
wkhtmltopdf で PDF に変換した際に canvas 内の日本語だけが文字化けする
update
event_note
label
ASP.NET Core
label
wkhtmltopdf
wkhtmltopdf を使って HTML を PDF へ変換した際、日本語が文字化けしたり文字コードがそのまま表示されたりして、かなりはまったのでメモしておきます。
尚、先に言っておきますが、原因は不明です。 ただ、一応対策方法は分かったので、それについて書いています。 ちなみに、以下の記事にも書いたように以前にも wkhtmltopdf と canvas ではまりましたが、今回もめちゃくちゃはまりました。 - [wkhtmltopdf で canvas に何も描画されない](https://kuttsun.blogspot.com/2020/08/wkhtmltopdf-canvas.html) 上記記事に書いたように、前提として wkhtmltopdf は現時点で ES6 に対応していないので注意してください。 ## 環境 実際には ASP.NET Core で Rotativa.AspNetCore を使っており、その中で HTML から PDF への変換に wkhtmltopdf が使われています。 - ASP.NET Core 2.2 - [Rotativa.AspNetCore](https://github.com/webgio/Rotativa.AspNetCore) 1.1.1 - wkhtmltopdf 0.12.4 ## 現象と対策 `fillText` で文字を描画する際、日本語をそのまま指定すると `あ` のように文字コードがそのまま表示されてしまいました。 ちなみに `12354` は `あ` の Unicode です。 - https://0g0.org/unicode/3042/ いろいろ試行錯誤した結果、どうやら文字コードを直接指定してから文字に変換すると上手く描画できることが分かりました。 ```js context.fillText(String.fromCharCode(12354), 0, 0); ``` 意味不明ですが、一応これで上手くいくようなので、以下のようにして描画することにしました。 - 文字列を文字に分割 - 各文字の Unicode を取得 - `String.fromCharCode` で Unicode を指定して文字を取得 - 文字を結合して `fillText` で出力 なんか文字コードへ変換してまたそのまま文字へ戻しているだけのように思いますが、何故かこれで上手くいったのでこうしています。 ### サロゲートペアへの対応 JavaScript では文字は UTF-16 で扱われているようなので、上記のことをどんな文字でも対応できるようにするには、サロゲートペアも考慮しておく必要があります。 サロゲートペア自体についてはググればいくらでも見つかるので割愛します。 私は JavaScript のコードも Razor で出力しており、各文字の Unicode を取得するのは C# 側でやりました。 たまたま私の環境ではサーバー側の処理で事足り、C# を使ったほうが簡単だったからです。 サロゲートペアを考慮して Unicode から文字を取得するのは以下の記事を参考にさせてもらいました。 - http://liosk.blog103.fc2.com/blog-entry-162.html
## 参考 URL - https://ics.media/entry/8385/ - https://qiita.com/sounisi5011/items/aa2d747322aad4850fe7 - https://qiita.com/jkr_2255/items/38d4bfdd9071560eaf8d - https://qiita.com/mpyw/items/15a25c5fef5f4a228b61 - https://barikanblog.com/javascript-es6-babel/#toc-2 - https://qiita.com/YusukeHirao/items/2f0fb8d5bbb981101be0 - http://liosk.blog103.fc2.com/blog-entry-162.html
Read more
2020/08/20
image
NO IMAGE
[C#] 文字の Unicode を取得
update
event_note
label
C#
文字の Unicode を取得する方法です。意外と情報が見つからなかったので。
```cs using System; using System.Text; using System.Globalization; ``` ```cs var unicode = new UnicodeEncoding(true, false); var encodedBytes = unicode.GetBytes("あ"); string output = ""; for (int i = 0; i < encodedBytes.Length; i++) { output += string.Format("{0:x2}", encodedBytes[i]); } Console.WriteLine(output);// 3042 // 数値に変換 var hex = int.Parse(output, NumberStyles.HexNumber); Console.WriteLine(hex.ToString());// 12354 ``` `あ` の Unicode は以下です。 - https://0g0.org/unicode/3042/
## 参考 URL - https://www.ipentec.com/document/csharp-unicode-string-to-unicode-scalar-value-string
Read more
2020/08/19
image
NO IMAGE
wkhtmltopdf で canvas に何も描画されない
update
event_note
label
ASP.NET Core
label
wkhtmltopdf
wkhtmltopdf を使って HTML を PDF へ変換していたのですが、canvas に JavaScript で描画しているはずの内容が全く表示されず、かなりはまったのでメモしておきます。
## 環境 実際には ASP.NET Core で Rotativa.AspNetCore を使っており、その中で HTML から PDF への変換に wkhtmltopdf が使われています。 - ASP.NET Core 2.2 - [Rotativa.AspNetCore](https://github.com/webgio/Rotativa.AspNetCore) 1.1.1 - wkhtmltopdf 0.12.4 ## 原因 結論から先に書くと、現時点で wkhtmltopdf は ES6 に対応していないため、ES6 で追加されたコードを書くと正しく実行されないようです。 具体的には、私の場合、以下のようなコードを書いていたことが原因でした、 - 変数宣言で `let` を使っていた - `codePointAt` で文字コードを取得していた ## 対策 `let` ならば `var` に置き換えるとかで簡単に対応可能ですが、中には対応が難しいものもあるかと思います。 一応対策として、babel を使って ES5 以前のコードにコンパイルするという手があります。 babel のインストール方法や使い方はググればいくらでも見つかるので割愛します。 ただ、私は JavaScript のコードも Razor で出力していたため、事前コンパイルせず(できず)、以下のようにブラウザ(この場合は wkhtmltopdf) 内でコンパイルせざるを得ませんでした。 ```html ``` そして、これだと処理速度が異常に遅くて使い物にならなかったので、結局 ES6 のコードを使わないように書き直して対応しました。 ## 原因が分かるまでの経緯 「wkhtmltopdf canvas」などでググってみると、ChartJS が描画されないといった内容が多くヒットしますが、canvas を使っているのは同じはずなので、まずはそれを参考にいろいろ試してみました。 具体的には以下です。 - `canvas` を `div` で括ってサイズを同じにする - `--no-stop-slow-scripts --javascript-delay 1000` を指定する(時間は適宜変更) これらについては参考 URL やググってみるといろいろヒットするので、割愛します。 しかし、これらのことをやっても状況は変わらず、それ以上の情報はいくらググっても見つかりませんでした。 ただ、`canvas` 内の表示だけがおかしいので、JavaScript に問題があるのではないかということは推測できました。 デバッグが非常にやりづらく、仕方ないので少しずつ JavaScript コードを埋め込んで動作確認していたら、どうも途中から JavaScript のコードが実行されていないような感じでした。 そこでふと `let` を見て、比較的最近追加された仕様だったなぁと思い、`var` に変更したところ上手く描画されるようになりました。 いや、これ本当にはまった。 尚、wkhtmltopdf を現時点で最新の 0.12.6 に変更しても同様でした。 また、上述した - `canvas` を `div` で括ってサイズを同じにする - `--no-stop-slow-scripts --javascript-delay 1000` を指定する(時間は適宜変更) ですが、私の環境では前者が不要でしたが、後者は必要でした。
## 参考 URL - https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3596 - https://qiita.com/hakatakinoco/items/47ea32689096004a5b72 - https://stackoverflow.com/questions/42561036/wkhtmltopdf-does-not-render-chart-js-2-5-0-graph
Read more
2020/07/30
image
NO IMAGE
[C#] コンパイラが必要とするメンバー 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' がありません
update
event_note
label
C#
`dynamic` 型を使用した場合に以下のようなエラーが表示されました。
```sh コンパイラが必要とするメンバー 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' がありません ``` ググってみると、`Microsoft.CSharp.dll` への参照を追加すればよいとの情報を得ましたが、見つからず。 どうやら .NET Standard のクラスライブラリの場合は、NuGet で以下の2つを追加する必要があるみたいです。 - System.Dynamic.Runtime - Microsoft.CSharp
## 参考 URL - http://var.blog.jp/archives/68140817.html - http://mag.autumn.org/Content.modf?id=20190124151720
Read more
2020/07/29
image
NO IMAGE
[ASP.NET Core] Razor 構文が有効にならない?
update
event_note
label
ASP.NET Core
`.cshtml` ファイル内で Razor 構文が効かないことがあって困ってたのですが、以下のページに書いてあるのを見てやっと原因がわかりました。
- https://docs.microsoft.com/ja-jp/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-3.1#c-in-tag-helpers-attributedeclaration そのまま転載しますが、以下のようなコードは有効ではないようです。 ```cs
``` この場合、以下のように書けば良いようです。 ```cs
``` いやいや、結構はまったわー。
## 参考 URL - https://docs.microsoft.com/ja-jp/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-3.1#c-in-tag-helpers-attributedeclaration
Read more
2020/07/27
GCP で Docker を使う
update
event_note
label
Google Cloud Platform
Google Cloud Platform の無料枠内で Docker を使ってみました。
とりあえず今回使うのは GCE (Google Compute Engine) です。 本格的にやるなら GKE (Googke Kubernetes Engine) のほうがいいみたいですが、よくわかりません。 ## 無料枠の確認 以下で確認できます。 - https://cloud.google.com/free/?hl=ja 今回は GCE を使うので、2019/06/23 現在の条件は以下になります。
## 前提 以下は済んでいる前提です。 - Googleアカウントの作成 - Google Cloud Platform の利用登録 ## GCP の設定 ### プロジェクトの作成 まずは適当にプロジェクトを作成して選択します。 ### VM インスタンスの作成 サイドメニューから Compute Engine > VM インスタンスを選択します。
作成をクリックします。
以下のように設定して、作成をクリックします。 - 名前は適当に入力 - マシンタイプは f1-micro を選択 - リージョンは 無料枠対象の米リージョンを選択(ゾーンは適当) - OS は Ubuntu 19.04 Minimal を選択 - 最初は Docker コンテナの実行に最適化されている Container-Optimized OS にしていましたが、何故かスワップの設定ができなかったため断念 - ディスクのサイズを 30GB に変更 - 「HTTP トラフィックを許可する」「HTTPS トラフィックを許可する」にチェック
尚、無料枠で収まっていれば、画面の右側に以下のように表示されます。 > 今月の f1-micro インスタンス使用量は、最初の 720 時間分が無料です。
### 外部 IP アドレスの設定 VM インスタンスを再起動しても IP アドレスが変わらないように静的 IP アドレスを割り当てます。 サイドメニューから VPC ネットワーク > 外部 IP アドレスを選択します。
### ファイアウォールの設定 外部からアクセスできるように、必要に応じてポートの解放を行います。 ## OS の設定 ### SSH で接続 VM インスタンスに SSH で接続します。 いくつかやり方はありますが、手っ取り早く接続するために、ブラウザからインスタンスの SSH をクリックして接続します。
### Swap の設定 メモリ不足になるという話をよく聞くので、スワップを追加しておきます。 #### 現在のスワップを確認 ```sh $ free -m ``` #### スワップの追加 以下のコマンドを実行します。 ```sh $ sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 $ sudo chmod 600 /swapfile $ sudo mkswap /swapfile $ sudo swapon /swapfile ``` **簡単な解説** ``` $ sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 ``` dd コマンドは、if で指定したファイルを、of で指定したファイルへ、 bs に指定された入出力ブロックサイズ単位で、count に指定された回数コピーを実行するコマンドです。 `if` に `/dev/zero` を指定しているので、`/swapfile` の中身はすべて 0 で埋め尽くされたファイルとなります。 `bs=1M` で `count=4096` なので、ブロックサイズ(1M)×4096 のサイズのファイルが作成されます。 ここでは 4GB となります。 ``` $ sudo chmod 600 /swapfile ``` 作成した `swapfile` の権限を root のみに変更します。 ``` $ sudo mkswap /swapfile ``` 作成した `swapfile` をスワップ領域として設定します。 ``` $ sudo swapon /swapfile ``` スワップ領域を設定しただけではダメなので、 スワップを有効化します。 #### ブート時にスワップを有効化 ブート時にスワップを有効になるように永続化します。 ### Docker のインストール ``` sudo apt-get install docker ``` ``` sudo apt-get install docker-compose ```
## 参考 URL - https://yakoi.qrunch.io/entries/HFbmdSlpB4qyqZx7 - https://sakura-bird1.hatenablog.com/entry/2019/03/12/034009 - https://qiita.com/suzukenz/items/4ecafd341e012102a6e9 - https://gist.github.com/koudaiii/0ed6a8558aa297af463e
Read more
2020/07/17
image
NO IMAGE
[C#] Stream に対して ReadAllLines を行いたい
update
event_note
label
C#
`File` クラスには `ReadAllLines` というメソッドがありますが、`Stream` にはないので、同等の機能を実装してみます。
## 環境 - Visual Studio 2017 - .NET Core 2.2 - C# 7.1 ## サンプルコード ```cs IEnumerable
ReadAllLines(Stream stream) { var lines = new List
(); using (var sr = new StreamReader(stream)) { while (sr.Peek() >= 0) lines.Add(sr.ReadLine()); } return lines; } ``` 反復子を使うともうちょっとシンプルになります。 ```cs IEnumerable
ReadAllLines(Stream stream) { using (var sr = new StreamReader(stream)) { while (sr.Peek() >= 0) yield return sr.ReadLine()); } } ``` 非同期版です。 ```cs async Task
> ReadAllLinesAsync(Stream stream) { var lines = new List
(); using (var sr = new StreamReader(stream)) { while (sr.Peek() >= 0) lines.Add(await sr.ReadLineAsync()); } return lines; } ``` C# 8.0 以降であれば `async/await` と `yield` が共存できるそうなので、もっとシンプルになります。 あとは、これらは拡張メソッドにしておいたほうが使い勝手が良いかもしれません。
## 参考 URL - https://stackoverflow.com/questions/13312906/readalllines-for-a-stream-object
Read more
2020/07/16
image
NO IMAGE
[JavaScript] Minify 時に `Implicit property name must be identifier` というエラーが表示される
update
event_note
label
JavaScript
JavaScript ファイルを BundlerMinifier で最小化するときに `Implicit property name must be identifier` というエラーが表示されました。
具体的には、Vue.js のコードで以下のように書いていた箇所でエラーが表示されました。 ```js mounted() { // Do Something } ``` これを以下のように修正したらエラーが表示されなくなりました。 ```js mounted: function () { // Do Something } ```
## 参考 URL - https://github.com/madskristensen/BundlerMinifier/issues/337
Read more
2020/07/13
image
NO IMAGE
[C#] コンストラクタで base と this を両方使いたい
update
event_note
label
C#
コンストラクタにおいて、基底クラスのコンストラクタを指定したい場合は `base` を、同じクラス内の別のコンストラクタを指定したい場合は `this` を指定しますが、両方指定したい場合はどうすればいいのか?
結論から先に書くと、両方を指定することはできません。 恐らくですが、`base` と `this` を両方指定したいと思うということは、コンストラクタ内で行う処理を全て共通化したいということなのだと思います。 私の場合はそうでした。 そして、私の場合はデフォルト引数を使うことで解決しました。 また、`base` や `this` を指定した場合(または指定しなかった場合)に、どのようにコンストラクタが呼ばれるかをきちんと把握すれば、もしかしたらどちらかを指定するだけで事足りるかもしれません。 というわけでいろいろ試してみました。 ## 環境 - Visual Studio 2019 - .NET Core 3.1 ## サンプル1 基底クラス `SampleBase` と、派生クラス `Sample` に、それぞれ引数なしと引数ありのコンストラクタを作成しています。 ### パターン1 `base` も `this` も指定しない場合です。 ```cs public static void Main() { new Sample(); Console.WriteLine("----------"); new Sample("foo"); } ///
/// 基底クラス ///
abstract class SampleBase { public SampleBase() { Console.WriteLine("SampleBase コンストラクタ引数なし"); } public SampleBase(string foo) { Console.WriteLine($"SampleBase コンストラクタ引数あり:{foo}"); } } ///
/// 派生クラス ///
class Sample : SampleBase { public Sample() { Console.WriteLine("Sample コンストラクタ引数なし"); } public Sample(string foo) { Console.WriteLine($"Sample コンストラクタ引数あり:{foo}"); } } ``` **出力結果** ```sh SampleBase コンストラクタ引数なし Sample コンストラクタ引数なし ---------- SampleBase コンストラクタ引数なし Sample コンストラクタ引数あり:foo ``` 派生クラス `Sample` は引数の有無によって呼ばれるコンストラクタが違いますが、基底クラス `SampleBase` はいずれの場合も引数なしのコンストラクタが呼ばれています。 ### パターン2 パターン1をベースに、基底クラスの引数ありコンストラクタを使うために、派生クラス `Sample` で `base` を指定しています。 ```cs public static void Main() { new Sample(); Console.WriteLine("----------"); new Sample("foo"); } ///
/// 基底クラス ///
abstract class SampleBase { public SampleBase() { Console.WriteLine("SampleBase コンストラクタ引数なし"); } public SampleBase(string foo) { Console.WriteLine($"SampleBase コンストラクタ引数あり:{foo}"); } } ///
/// 派生クラス ///
class Sample : SampleBase { public Sample() { Console.WriteLine("Sample コンストラクタ引数なし"); } public Sample(string foo) : base(foo) { Console.WriteLine($"Sample コンストラクタ引数あり:{foo}"); } } ``` **出力結果** ```sh SampleBase コンストラクタ引数なし Sample コンストラクタ引数なし ---------- SampleBase コンストラクタ引数あり:foo Sample コンストラクタ引数あり:foo ``` 引数を指定しなかった場合は、`Sample` `SampleBase` ともに引数なしのコンストラクタがコールされます。 引数を指定した場合は、`Sample` `SampleBase` ともに引数ありのコンストラクタがコールされます。 まぁここらへんまでは当たり前ですね。 ### パターン3 パターン2をベースに、基底クラス `SampleBase` の引数ありコンストラクタで `this` を指定しています。 ```cs public static void Main() { new Sample(); Console.WriteLine("----------"); new Sample("foo"); } ///
/// 基底クラス ///
abstract class SampleBase { public SampleBase() { Console.WriteLine("SampleBase コンストラクタ引数なし"); } public SampleBase(string foo) : this() { Console.WriteLine($"SampleBase コンストラクタ引数あり:{foo}"); } } ///
/// 派生クラス ///
class Sample : SampleBase { public Sample() { Console.WriteLine("Sample コンストラクタ引数なし"); } public Sample(string foo) : base(foo) { Console.WriteLine($"Sample コンストラクタ引数あり:{foo}"); } } ``` **出力結果** ```sh SampleBase コンストラクタ引数なし Sample コンストラクタ引数なし ---------- SampleBase コンストラクタ引数なし SampleBase コンストラクタ引数あり:foo Sample コンストラクタ引数あり:foo ``` 引数を指定した場合、基底クラスのコンストラクタは両方呼ばれます。 ### パターン4 パターン3をベースに、派生クラス `Sample` の引数なしコンストラクタで基底クラス `SampleBase` の引数ありコンストラクタを呼んでいます。 ```cs public static void Main() { new Sample(); Console.WriteLine("----------"); new Sample("foo"); } ///
/// 基底クラス ///
abstract class SampleBase { public SampleBase() { Console.WriteLine("SampleBase コンストラクタ引数なし"); } public SampleBase(string foo) : this() { Console.WriteLine($"SampleBase コンストラクタ引数あり:{foo}"); } } ///
/// 派生クラス ///
class Sample : SampleBase { public Sample() : base(null) { Console.WriteLine("Sample コンストラクタ引数なし"); } public Sample(string foo) : this() { Console.WriteLine($"Sample コンストラクタ引数あり:{foo}"); } } ``` **出力結果** ```sh SampleBase コンストラクタ引数なし SampleBase コンストラクタ引数あり: Sample コンストラクタ引数なし ---------- SampleBase コンストラクタ引数なし SampleBase コンストラクタ引数あり: Sample コンストラクタ引数なし Sample コンストラクタ引数あり:foo ``` 引数を指定した場合は全てのコンストラクタが呼ばれています。 多分これが一番問題のパターン。 派生クラス `Sample` の引数の値を基底クラス `SampleBase` に渡しつつ、コンストラクタ内の処理は各クラスの引数なしコンストラクタに集約したい。 しかし、派生クラス `Sample` の引数ありコンストラクタで `base` と `this` の両方を指定することはできません。 かと言って、このパターンのようにやると `this` を指定したときに引数の情報が失われてしまいます(当たり前ですが)。 というわけで、代替案が次のサンプルです。 ## サンプル2(代替案) 派生クラス `Sample` のコンストラクタを引数ありの1つのみにし、デフォルト引数を定義する方法です。 ```cs public static void Main() { new Sample(); Console.WriteLine("----------"); new Sample("foo"); } ///
/// 基底クラス ///
abstract class SampleBase { public SampleBase() { Console.WriteLine("SampleBase コンストラクタ引数なし"); } public SampleBase(string foo) : this() { Console.WriteLine($"SampleBase コンストラクタ引数あり:{foo}"); } } ///
/// 派生クラス ///
class Sample : SampleBase { public Sample(string foo = null) : base(foo) { Console.WriteLine($"Sample コンストラクタ引数あり:{foo}"); } } ``` **出力結果** ```sh SampleBase コンストラクタ引数なし SampleBase コンストラクタ引数あり: Sample コンストラクタ引数あり: ---------- SampleBase コンストラクタ引数なし SampleBase コンストラクタ引数あり:foo Sample コンストラクタ引数あり:foo ``` 私の場合はこれで解決しました。
Read more
2020/07/02
image
NO IMAGE
[C#] xUnit で MemberData を使ったテストがテストエクスプローラーで1つのテストとして表示される
update
event_note
label
C#
label
xUnit
`xUnit` で `MemberData` や `ClassData` を使ってテストケースを作成した場合、 Visual Studio のテストエクスプローラーでは複数のテストケースが単一のテストケースとして表示されてしまいます。
これだとデバッグが非常にやりにくいので、`InlineData` と同じように複数のテストケースとして表示する方法がないか調べてみると、以下の記事が見つかりました。 - https://stackoverflow.com/questions/30574322/memberdata-tests-show-up-as-one-test-instead-of-many Visual Studio のテストエクスプローラーで各テストケースを別々の項目として表示するためには、テストケースの型に `IXunitSerializable` を実装する必要があるみたいです。 ## 環境 - Visual Studio 2017 - .NET Core 2.2 - xUnit 2.4.1 ## サンプル ### 変更前 例えば、`MemberData` を使ったテストコードは以下のような感じになっていると思います。 ```cs [Theory, MemberData(nameof(TestData))] public void TestMethod(int param1, string param2) { // Do something test } public static IEnumerable
TestData() { yield return new object[] { 0, "hoge" }; yield return new object[] { 1, "fuga" }; } ``` ### 変更後 `IXunitSerializable` を実装するためにテストデータクラス `TestCaseData` を作成します。 ```cs [Theory, MemberData(nameof(TestData))] public void TestMethod(TestCaseData testCaseData) { var param1 = testCaseData.Param1; var param2 = testCaseData.Param2; // Do something test } public class TestCaseData : IXunitSerializable { public int Param1 { get; set; } public string Param2 { get; set; } public void Serialize(IXunitSerializationInfo info) { info.AddValue(nameof(Param1), Param1.ToString()); info.AddValue(nameof(Param2), Param2.ToString()); } public void Deserialize(IXunitSerializationInfo info) { } } public static IEnumerable
TestData() { yield return new object[] { new TestCaseData{ Param1 = 0, Param2 = "hoge" } }; yield return new object[] { new TestCaseData{ Param1 = 1, Param2 = "fuga" } }; } ``` 結構面倒です。 ## もう少し汎用的になるように改良してみる 上記のままだと、テストケースの度に `IXunitSerializable` を実装する必要があり面倒なので、何とかして共通化できないかと思い、とりあえず以下の2案が思い浮かびました。 ### ジェネリックを使って汎用的に実装する `IXunitSerializable` を実装した `ValidateTestCase` を作成し、ジェネリックでテストケースクラスの型を指定してやります。 ```cs [Theory, MemberData(nameof(TestData))] public void TestMethod(ValidateTestCase
testCaseData) { var param1 = testCaseData.Param.Param1; var param2 = testCaseData.Param.Param2; // Do something test } public class ValidateTestCase
: IXunitSerializable { public T Param { get; set; } public void Serialize(IXunitSerializationInfo info) { // JSON を使う場合 info.AddValue(nameof(Param), JsonConvert.SerializeObject(Param)); // ハッシュ値を使う場合 // info.AddValue(nameof(Param), GetHashCode()); // GUID を使う場合 // info.AddValue(nameof(Param), Guid.NewGuid().ToString()); } public void Deserialize(IXunitSerializationInfo info) { } } public class TestCaseData { public int Param1 { get; set; } public string Param2 { get; set; } } public static IEnumerable
TestData() { yield return new object[] { new ValidateTestCase
{ Param = new TestCaseData(){ Param1 = 0, Param2 = "hoge" } } }; yield return new object[] { new ValidateTestCase
{ Param = new TestCaseData(){ Param1 = 1, Param2 = "fuga" } } }; } ``` `Serialize` メソッドで登録する文字列を `ToString()` から JSON でのシリアライズに変更しているのがポイントです。 クラスに対して `ToString()` するとクラス名が出力されるので、全てのテストで同じ文字列になってしまい、テストエクスプローラーでは単一のテストとして表示されてしまいました。 この文字列は一連のテストケースにおいてユニークでないとダメなようです。 なので、テストパラメーターには重複はないという前提で、JSON でシリアライズしてみました。 ただし、テストケースクラス `TestCaseData` にデリゲートを含んでいる場合は上手くいかなかったので、そういう場合はハッシュ値や GUID などを使ったほうが良いと思います。 (ハッシュ値は被ることもあるかもしれないので、GUID のほうが確実か?) ### 抽象クラスを作成して汎用的に実装する 上記だと毎回 `ValidateTestCase` と `T` の2つのクラスをインスタンス化しないといけなくてちょっと面倒なので、同じような感じで抽象クラスで実装してみました。 自クラス `this` に対してシリアライズを行っています。 ```cs [Theory, MemberData(nameof(TestData))] public void TestMethod(TestCaseData testCaseData) { var param1 = testCaseData.Param1; var param2 = testCaseData.Param2; // Do something test } public abstract class XunitSerializableBase : IXunitSerializable { public void Serialize(IXunitSerializationInfo info) { // JSON を使う場合 info.AddValue(nameof(XunitSerializableBase), JsonConvert.SerializeObject(Param)); // ハッシュ値を使う場合 // info.AddValue(nameof(XunitSerializableBase), GetHashCode()); // GUID を使う場合 // info.AddValue(nameof(XunitSerializableBase), Guid.NewGuid().ToString()); } public void Deserialize(IXunitSerializationInfo info) { } } public class TestCaseData : XunitSerializableBase { public int Param1 { get; set; } public string Param2 { get; set; } } public static IEnumerable
TestData() { yield return new object[] { new TestCaseData{ Param1 = 0, Param2 = "hoge" } }; yield return new object[] { new TestCaseData{ Param1 = 1, Param2 = "fuga" } }; } ``` ちょっとだけ記述量が減りました。 ## 他の案は? 上記のリンク先にある `DjvuTheory` が便利そうだったので試しましたが、.NET Core 2.2 だと動きませんでした。 自分で修正しようともしてみましたが、何故かうまくいかず断念。 これが使えたら `Theory` を`DjvuTheory` に置換するだけでいけそうだったのに残念です。
## 参考 URL - https://stackoverflow.com/questions/30574322/memberdata-tests-show-up-as-one-test-instead-of-many - https://darchuk.net/2019/04/12/serializing-xunit-test-cases/ - https://docs.microsoft.com/ja-jp/azure/bot-service/unit-test-bots?view=azure-bot-service-4.0&tabs=csharp - https://github.com/mysteryx93/XunitDjvuTheory
Read more
2020/06/26
image
NO IMAGE
[C#] ClassData でテストデータを作成する際に、テストクラス内のリソースにアクセスしたい
update
event_note
label
C#
label
xUnit
`xUnit` で複雑なテストデータを作成する場合、`ClassData` を使って別途テストデータ作成用のクラスを用意したりしますが、このテストデータ作成用のクラスでテストクラス内のリソースを操作したいことがあったので、思いついた案を載せておきます。
ここでいうリソースとは、例えばテスト用のデータベースだとか、外部ファイルなどです。 あくまで私が思いついた一例ですが、概要としては、以下です。 - テストメソッドの引数にデリゲートを用意し、テストメソッド内からリソースを渡す - テストデータ作成用のクラスで、リソースに対する処理を記述 ## 環境 - Visual Studio 2017 - .NET Core 2.2 ## サンプルコード `resource` がデータベースなどの外部のリソースを想定しています。 ### テスト対象のクラス 以下のようなクラスをテストしたいとします。 ```cs // テストしたいクラス public class Target { // テストしたいメソッド public int Add(IList
resource) { // 例えば、データベースなどから値を読み込んで、何か処理をした値を返すなど // ここでは全レコードを読み込んで総和を返すようなことを想定 return resource.Sum(); } } ``` ### テストコード 以下がテストコードです。 解説はコメントに書いてある通りです。 ```cs using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Xunit; using Xunit.Abstractions; namespace TestProject { // テストを行うクラス public class TestClass { ITestOutputHelper output; Target target; readonly IList
resource;// 例えば、データベースやファイルなどの外部リソース public TestClass(ITestOutputHelper output) { // デバッグ用にテストエクスプローラーに出力できるようにしておく this.output = output; // リソースの初期化(実際には IClassFixture を使うなどする) resource = new List
{ 1, 2 }; // テストクラスのインスタンスを作成 target = new Target(); } [Theory, ClassData(typeof(TestData))] public void TestMethod( // テスト前にリソースに対して行う処理(戻り値が必要なら Func にする) Action
> action, // テスト実行後の期待値 int expected ) { // テストに必要な前処理を行う action(resource); // デバッグ用にテスト前のリソースの状態を出力 output.WriteLine($"resource: {string.Join(", ", resource)}"); // テストの実行 var result = target.Add(resource); // デバッグ用に結果を出力 output.WriteLine($"result: {result.ToString()}"); // 結果の確認 Assert.Equal(expected, result); } } // テストデータを作成するクラス class TestData : IEnumerable
{ List
_testData = new List
(); public TestData() { // いくつかのパターンでテストデータを作成してみる // テストケース1(リソースの中身を書き換え) Action
> action = resource => { resource[0] = 1; resource[1] = 2; }; _testData.Add(new object[] { action, 3 }); // テストケース2(リソースに要素を追加) _testData.Add(new object[] { new Action
>(resource => resource.Add(3)), 6 }); // テストケース3(リソースをクリア) action = resource => resource.Clear(); _testData.Add(new object[] { action, 0 }); } public IEnumerator
GetEnumerator() => _testData.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } ``` ### 実行結果 **テストケース1** ```sh resource: 1, 2 result: 3 ``` **テストケース2** ```sh resource: 1, 2, 3 result: 6 ``` **テストケース3** ```sh resource: result: 0 ```
## 参考 URL
Read more
2020/06/25
image
NO IMAGE
[C#] nameof 演算子の代わりにフルネームを返すメソッドを作る
update
event_note
label
C#
`nameof` 演算子は最後の名前しか返しませんが、フルネームを取得したいことは多々あります。 そんななか、stack overflow に便利そうなコードがあったので、そのまま転載します。
- https://stackoverflow.com/questions/27898178/why-does-nameof-return-only-last-name 例えば、以下のようなクラスがあったとして、 ```cs class SpeciesFamily { public string Name { get; set; } } class Species { public SpeciesFamily Family { get; set; } public string Name { get; set; } } class Cat { public Species Species { get; set; } } ``` `Species.Family.Name` という文字列を `nameof` 演算子を使って取得しようとすると、以下のようなコードになってしまいます。 ```cs var fullName = $"{nameof(Species)}.{nameof(Species.Family)}.{nameof(SpeciesFamily.Name)}" ``` 同じクラス名やプロパティ名を何度も書くことになるので、階層が深くなればなるほど面倒です。 これに対して、フルネームを簡単に取得できるようにしたメソッドのサンプルが以下の2つです。 (階層が浅いと記述量はあまり変わりませんが・・・) ## サンプルコード1 ```cs public static string GetMemberString
(System.Linq.Expressions.Expression
> member) { if (member == null) { throw new ArgumentNullException("member"); } var propertyRefExpr = member.Body; var memberExpr = propertyRefExpr as System.Linq.Expressions.MemberExpression; if (memberExpr == null) { var unaryExpr = propertyRefExpr as System.Linq.Expressions.UnaryExpression; if (unaryExpr != null && unaryExpr.NodeType == System.Linq.Expressions.ExpressionType.Convert) { memberExpr = unaryExpr.Operand as System.Linq.Expressions.MemberExpression; if (memberExpr != null) { return memberExpr.Member.Name; } } } else { //gets something line "m.Field1.Field2.Field3", from here we just remove the prefix "m." string body = member.Body.ToString(); return body.Substring(body.IndexOf('.') + 1); } throw new ArgumentException("No property reference expression was found.", "member"); } ``` **使い方** ```cs // Will return a string containing "Species.Family.Name". var fullName = GetMemberString
(x => x.Species.Family.Name) ``` ## サンプルコード2 ```cs public static class NameOf
{ #region Public Methods public static string Full(Expression
> expression) { var memberExpression = expression.Body as MemberExpression; if (memberExpression == null) { if (expression.Body is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert) memberExpression = unaryExpression.Operand as MemberExpression; } var result = memberExpression.ToString(); result = result.Substring(result.IndexOf('.') + 1); return result; } public static string Full(string sourceFieldName, Expression
> expression) { var result = Full(expression); result = string.IsNullOrEmpty(sourceFieldName) ? result : sourceFieldName + "." + result; return result; } #endregion } ``` **使い方** ```cs // Will return a string containing "Species.Family.Name". var fullName = NameOf
.Full(c => c.Species.Family.Name); // Will return a string containing "cat.Species.Name". var fullNameWithPrefix = NameOf
.Full("cat", c => c.Species.Name); ``` `"cat"` のようにプレフィックスが指定できるので、こちらのほうがより汎用的かと思います。 また、`"cat"` の部分も `nameof` 演算子を使えば、文字列の記述を完全に無くすことができます。
## 参考 URL - https://stackoverflow.com/questions/27898178/why-does-nameof-return-only-last-name
Read more
2020/06/24
image
NO IMAGE
[ASP.NET Core] ModelState のチェックを無効化
update
event_note
label
ASP.NET Core
label
C#
ASP.NET Core において、`[Required]` などといった Attribute によるモデルのチェックを無効化する方法です。
## 環境 - Visual Studio 2017 - ASP.NET Core 2.2 ## サンプルコード `Remove` メソッドでチェックを無効化したいプロパティのキーを指定します。 ```cs ModelState.Remove("hoge"); ``` 全てのプロパティに対するチェックを無効化したい場合は、以下のようにして全てのキーを削除すれば OK です。 ```cs foreach (var key in ModelState.Keys) { ModelState.Remove(key); } ``` `Remove` メソッドでキーを削除したら、`ModelState.IsValid` の値も自動で更新されるようです。
## 参考 URL
Read more
2020/06/23
image
NO IMAGE
[C#] Null 許容型かどうかを判別する
update
event_note
label
C#
どのように判定するかは目的や用途に応じて変わりそうですが、あくまで例としてサンプルを作成してみました。
## 環境 - Visual Studio 2017 - .NET Core 2.2 ## サンプルコード ```cs public static void Main() { var personClass = new PersonClass(); var personStruct = new PersonStruct(); var persons = new List
(); IsNullable(typeof(int));// False IsNullable(typeof(int?));// True IsNullable(typeof(PersonClass));// True IsNullable(typeof(PersonStruct));// False IsNullable(personClass.GetType());// True IsNullable(personClass.Age.GetType());// False IsNullable(personClass.Name?.GetType());// True IsNullable(personStruct.GetType());// False IsNullable(personStruct.Age.GetType());// False IsNullable(personStruct.Name?.GetType());// True IsNullable(typeof(List<>));// True IsNullable(persons.GetType());// True } static bool IsNullable(Type type) { var ret = type == null || // Null条件演算子用にこの条件を入れているだけなので、場合によっては不要 !type.IsValueType || // 値型でない -> Nullable Nullable.GetUnderlyingType(type) != null;// 非Null許容型が取得できる -> Null許容演算子が指定されている -> Nullable Console.WriteLine(ret);// デバッグ用に表示 return ret; } public class PersonClass { public int Age { get; set; } public string Name { get; set; } } public struct PersonStruct { public int Age { get; set; } public string Name { get; set; } } ``` 間違いや他に良い方法があれば教えてください。
## 参考 URL - https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/nullable-value-types#how-to-identify-a-nullable-value-type - https://docs.microsoft.com/ja-jp/dotnet/api/system.nullable.getunderlyingtype - https://docs.microsoft.com/ja-jp/dotnet/api/system.type.isvaluetype
Read more
2020/06/19
image
NO IMAGE
[C#] 非同期メソッドのモック
update
event_note
label
C#
非同期メソッド (`async / await`) の戻り値は `Task` なので、`Moq` を使う場合にも `Task` を返す必要があります。
この場合、モックでは `Task.FromResult` を使って戻り値を返すようにします。 以下サンプルです。 **非同期メソッドでない場合** ```cs sample = new Mock
(); sample.Setup(x => x.Hoge(It.IsAny
())).Returns(true); ``` **非同期メソッドの場合** ```cs sample = new Mock
(); sample.Setup(x => x.HogeAsync(It.IsAny
())).Returns(Task.FromResult(true)); ```
## 参考 URL - https://stackoverflow.com/questions/21253523/how-can-i-tell-moq-to-return-a-task - https://qiita.com/TsuyoshiUshio@github/items/37d1cee9118d681db5af
Read more
2020/06/18
image
NO IMAGE
[C#] リストをデシリアライズしたときに項目が追加登録されてしまう
update
event_note
label
C#
リストの初期値が設定されているクラスのデータを Newtonsoft.Json (Json.NET) でデシリアライズすると、そのリストの項目は初期値を含んだうえでデシリアライズされた値が追加登録されていました。 シリアライズされた内容とデシリアライズされた内容が異なるので、いや、ほんとはまりました。
## 環境 - Visual Studio 2017 - .NET Core 2.2 ## サンプルコード 以下のようなクラスをシリアライズ、デシリアライズするとします。 ```cs public class SampleData { public IList
Hoge { get; set; } = new List
{ 1 }; } ``` ```cs var data = new SampleData(); // シリアライズ var serialized = JsonConvert.SerializeObject(data); Console.WriteLine(serialized); // デシリアライズ(このタイミングでリストの項目が2つになっている!) var deserialized = JsonConvert.DeserializeObject
(serialized); Console.WriteLine($"Hoge Count: {deserialized.Hoge.Count()}"); // もう一度シリアライズして確認 var serialized2 = JsonConvert.SerializeObject(deserialized); Console.WriteLine(serialized2); ``` **出力結果** ```bat {"Hoge":[1]} Hoge Count: 2 {"Hoge":[1,1]} ``` デシリアライズ時に項目が1つ増えています。 シリアライズした内容はリストを置換するではなく、リストに追加登録されるからです。 いや、これほんとにはまった。 ## ObjectCreationHandling.Replace を指定する 初期値を含めないようにするにはデシリアライズ時のオプションで `ObjectCreationHandling.Replace` を指定する必要があります。 ```cs var deserialized = JsonConvert.DeserializeObject
(serialized, new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, }); ``` こちらの動作のほうが直観的だと思うので、こちらが既定値のほうが良いと思うのですが、私だけでしょうか? ちなみに `DataContractJsonSerializer` を使った場合は既定で置換してくれました。
## 参考 URL - https://stackoverflow.com/questions/46300616/json-net-deserialize-with-collection-initialization-in-constructor?noredirect=1&lq=1 - https://ja.coder.work/so/c%23/821888
Read more
2020/06/17
image
NO IMAGE
[C#] DateTime 型を含むデータのシリアライズ
update
event_note
label
C#
DateTime 型を含むデータを Microsoft 標準の `DataContractJsonSerializer` を使ってシリアライズすると例外が発生しました。
## 環境 - Visual Studio 2017 - .NET Core 2.2 ## サンプルコード 以下のようなクラスをシリアライズしたいとします。 ```cs public class Person { public DateTime Birth { get; set; } = DateTime.Today; public string Name { get; set; } = "Name"; public int Age { get; set; } = 20; } ``` `DataContractJsonSerializer` を使ってシリアライズしてみます。 ```cs static public string Serialize
(T value) { var serializer = new DataContractJsonSerializer(typeof(T)); var serializedData = string.Empty; using (var memoryStream = new MemoryStream()) { serializer.WriteObject(memoryStream, value); serializedData = Encoding.UTF8.GetString(memoryStream.ToArray()); } return serializedData; } ``` ```cs var data = new Person(); var serialized = Serialize(data); Console.WriteLine(serialized); ``` **出力結果** ```bat {"Age":20,"Birth":"\/Date(1592319600000+0900)\/","Name":"Name"} ``` ### 例外が発生するパターン ここで、上記の `DateTime` 型である `Birth` の初期値を未設定にすると、`DateTime.MinValue` が初期値になりますが、この場合に以下の例外が発生します。 ```bat System.Runtime.Serialization.SerializationException : DateTime values that are greater than DateTime.MaxValue or smaller than DateTime.MinValue when converted to UTC cannot be serialized to JSON. ---- System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values. ``` `DataContractJsonSerializer` は `DateTime` を UTC に変換してシリアライズしようとしますが、MinValueだった場合、JST だと -9 時間することになるので、アンダーフローを起こすのが原因らしいです。 ## 対処方法 とりあえず思いついたのは以下です。 ### その1 DateTimeOffset を使う 型を変更できるなら `DateTimeOffset` に変更すればシリアライズ可能になります。 ### その2 他のパーサーを使う 例えば、Newtonsoft.Json を使うと `DateTime` が `MinValue` であっても以下のように ISO 形式で文字列に変換されるため、シリアライズ可能です。 ```cs var data = new Person(); var serialized = JsonConvert.SerializeObject(data); Console.WriteLine(serialized); ``` **出力結果** ```bat {"Birth":"0001-01-01T00:00:00","Name":"Name","Age":20} ```
## 参考 URL - https://qiita.com/Toraja/items/d0c5ada821df81de2440
Read more
2020/05/21
image
NO IMAGE
Moq で System.NotSupportedException : Unsupported expression のエラーが表示された
update
event_note
label
C#
Moq を使ってテストコードを書いているときに、以下のようなエラーが表示されました。
```sh Message: System.NotSupportedException : Unsupported expression ``` 私の場合、モックしようとしているメソッドに `virtual` を付けると解決しました。
## 参考 URL - https://github.com/moq/moq4/issues/961
Read more
2020/05/08
IIS + ARR + URL Rewrite で ASP.NET Core アプリケーションにアクセスする
update
event_note
label
ASP.NET Core
ASP.NET Core で作成した Web アプリケーションを IIS でホストする場合、ASP.NET Core Module を使う方法がありますが、諸事情により ARR と URL Rewrite でリバースプロキシを行ってアクセスできるように設定しました。
IIS はインストールされている前提です。 ## 環境 - Windows 10 - IIS 10 ## ARR と URL Rewrite のインストール ますは Application Request Routing (ARR) と URL Rewrite をインストールします。 これらは [Web Platform Installer](https://www.microsoft.com/web/downloads/platform.aspx) を使ってインストールする方法が一般的かと思いますが、諸事情により今回はインターネットに接続していない機器にインストールする必要があったため、個別にダウンロードしてインストールします。 以下からそれぞれダウンロードできます。 **Application Request Routing** - https://www.iis.net/downloads/microsoft/application-request-routing **URL Rewrite** - https://www.iis.net/downloads/microsoft/url-rewrite ※下の方に日本語版があります ## IIS マネージャーの設定 IIS マネージャーを開き、以下の設定を行います。 ### リバースプロキシの有効化 コンピューター名をクリックして、`Application Request Routing Cache` をダブルクリックします。
`Server Proxy Settings...` をクリックします。
`Enable proxy` にチェックを入れ、`適用` をクリックします。
### Web サイトの追加 コンピューター名を右クリックし、`Web サイトの追加` をクリックし、以下のように入力します。
- サイト名は適当に入力します(今回は test としました) - アプリケーションプールは最初からある `DefaultAppPool` を選択します - 物理パスには適当に空のフォルダを指定します(リバースプロキシで飛ばすので何でもよい) ### URL 書き換えルールの設定 作成した Web サイトを選択し、`URL 書き換え` をダブルクリックします。
`規則の追加` をクリックします。
`リバースプロキシ` を選択します。
`受信規則` に ASP.NET Core アプリケーションのアドレスを指定します。 通常は `localhost:5000` かと思います。
ブラウザからアクセスして確認します。 (今回の場合は http://localhost/ にアクセスして確認)
## 参考 URL - https://mslgt.hatenablog.com/entry/2019/05/11/023037 - https://teratail.com/questions/70480 - https://qiita.com/natady/items/aeff627a865b9875a1b2 - https://tetsupc.wordpress.com/tag/iis/ - http://wiki.examind.net/index.php?IIS/%E3%83%AA%E3%83%90%E3%83%BC%E3%82%B9%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7
Read more
2020/04/27
image
NO IMAGE
[C#] 文字列内の文字が全て同じかどうかをチェックする
update
event_note
label
C#
例えば `99999` や `aaaa` など、文字列内の文字が全て同じかどうかを簡単にチェックする方法です。
まず、単純に同じ文字かどうかだけを判定するなら、Linq を使えば一発です。 ```cs var str = "99999"; Console.WriteLine(str.Distinct().Count() == 1);// True ``` 重複を排除した結果、要素数が1つだけになっていれば全て同じ文字と判断できます。 特定の文字の場合のみ、文字列内が全て同じ文字かどうかを判定したいなら、フィルタリングする必要があります。 ``` var str1 = "00000"; var str2 = "00999"; var str3 = "99999"; // 文字が全て 9 の場合のみ True にしたい Console.WriteLine(!str1.Any(x => x != '9') && str1.Distinct().Count() == 1);// False Console.WriteLine(!str2.Any(x => x != '9') && str2.Distinct().Count() == 1);// False Console.WriteLine(!str3.Any(x => x != '9') && str3.Distinct().Count() == 1);// True ``` - `9` 以外の文字を抽出した結果、要素数が 0 だったならば `9` 以外の文字が含まれていない - 重複を排除した結果、要素数が1つだけになっていれば全て同じ文字 この2つの条件で判断できます。 コード自体は短いですが、毎回これを書くのも面倒なので、拡張メソッドでも作成しておくと便利かと思います。 もっと簡単に判別できる方法があれば教えてください。
## 参考 URL - https://teratail.com/questions/140064
Read more
2020/04/26
image
NO IMAGE
OpenSSL で SAN 付きの自己署名証明書を作成する
update
event_note
label
OpenSSL
サーバー証明書に自己署名証明書を使っているとブラウザが警告を表示しますが、クライアント PC に証明書をインストールしても Chrome だけは警告が消えませんでした。
Chrome はコモンネームではなく SAN(Subject Alternative Name) をチェックしているからだそうです。(Chrome 58 以降) そこで、以前 OpenSSL を使って自己署名証明書を作成しましたが、 - [OpenSSL を使って自己署名証明書を作成する](http://kuttsun.blogspot.com/2018/04/openssl.html) 今回はこれに SAN を加える方法です。 細かい説明は以前の記事(上記)に書いてあるので、ここでは実行するコマンドのみを載せたいと思います。 ## SAN 用のテキストファイルを用意 事前準備として、以下のように SAN の内容を記述したテキストファイルを用意します。 ファイル名は何でも構いません(今回は `san.txt` という名前で保存しました)。 ``` subjectAltName = DNS:*.example.com, IP:172.20.0.1 ``` DNS ではワイルドカードが使えますが、IP では使えません。 ## 自己署名証明書の作成手順 ### 秘密鍵の作成 以下のコマンドは公開鍵暗号方式として RSA を利用した 2048bit の秘密鍵 server.key を作成しています。 ```sh > openssl genrsa -out server.key 2048 ``` ### 証明書署名要求の作成 先ほど作成した秘密鍵 `server.key` を指定して証明書署名要求 `server.csr` を作成しています。 ```sh > openssl req -out server.csr -key server.key -new ``` いろいろ聞かれるので、適当に入力します。 ### サーバー証明書の作成 通常は上記で作成した証明書署名要求 `server.csr` を自分の秘密鍵 `server.key` で署名してサーバー証明書を作成します。 ここが前回と異なるところです。 SAN を付加するために `-extfile san.txt` が追加になっています。 ```sh > openssl x509 -req -days 3650 -signkey server.key -in server.csr -out server.crt -extfile san.txt ``` 尚、上記は有効期限が 10 年間のサーバー証明書 `server.crt` を作成しています。 ## 確認 SAN が付加されているか確認します。 ```sh > openssl x509 -text -in sample.crt -noout ``` `X509v3 Subject Alternative Name:` にテキストファイルに記述した SAN が追加されていれば OK です。
## 参考 URL - https://kazuhira-r.hatenablog.com/entry/20180803/1533302929 - https://teratail.com/questions/77446 - https://tech.torico-corp.com/blog/chrome58-https-ssl-cert-san-error/
Read more
2020/04/24
OpenSSL で作成したサーバー証明書を IIS にインポートする
update
event_note
label
IIS
label
OpenSSL
OpenSSL で作成したサーバー証明書(自己署名証明書)を IIS にインポートします。
OpenSSL を使用したサーバー証明書(自己署名証明書)の作成方法については以下を参照してください。 - [OpenSSL を使って自己署名証明書を作成する](http://kuttsun.blogspot.jp/2018/04/openssl.html) また、自己署名証明書を使用するとセキュリティ的に全く意味がなくなりますが、それについてもここでは議論しません。 ## 環境 - IIS 7 - OpenSSL 1.0.2 ## pfx 形式への変換 OpenSSL で作成したサーバー証明書 (crt) を IIS にインポートするには、PKCS#12 (pfx) 形式に変換する必要があります。 ```sh > openssl pkcs12 -export -inkey server.key -in server.crt -out server.pfx ``` パスワードの設定を聞かれるので、入力すると、pfx ファイルが作成されます。 ## IIS へのインポート pfx ファイルを IIS へインポートします。 スタートメニューから IIS マネージャーを起動します。 コンピューター名を選択し、[サーバー証明書] をダブルクリックします。
[インポート] をクリックします。
作成した `server.pfx` を選択します。
### サイトへのバインド 証明書をインポートしたら、サイトにバインドします。 IIS マネージャーでサイトを選択し、[バインド] をクリックします。
[追加] をクリックします。
[種類] で `https` を選択し、[SSL 証明書] から先ほどインポートした証明書を選択します。
以上で完了です。 ブラウザから `https` でサイトにアクセスし、以下のような画面が表示されれば OK です。
※上記は Firefox の画面です。 ## クライアントへのインストール `server.pfx` をダブルクリックします。 ### Firefox の場合 私は普段 Firefox を使用していますが、Firefox の場合は上記の方法ではなく、個別に証明書をインポートする必要があります。 ## 参考 URL - https://knowledge.geotrust.com/jp/support/knowledge-base/index?vproductcat=G&vdomain=GEOTRUST_JP&page=content&id=SO23603&locale=ja_JP&redirected=true - http://d.hatena.ne.jp/ozuma/20130511/1368284304 - https://blog.freedom-man.com/openssl-command/
Read more
2020/04/20
image
NO IMAGE
submit ボタンにアイコンを表示する
update
event_note
label
HTML
フォーム送信する際にクリックする `submit` ボタンにアイコンを表示する方法です。 ここでは例として Font Awesome のアイコンを表示させてみます。
`submit` ボタンにアイコンを表示させるためには `input` 要素の `value` にアイコンのコードを Unicode でセットします。 アイコンのコードは Font Awesome のサイトで確認できます。 - https://fontawesome.com/icons?d=gallery コードをセットするときは、最初に `` を、最後に `;` を追加します。 例えば、Save アイコンのコード `f0c7` を指定する場合は以下のようになります。 ```html
``` `class` には使用するアイコンのスタイルに応じて適切なものを設定します。
Read more
2020/04/15
image
NO IMAGE
[C#] バイト配列のシリアライズ
update
event_note
label
C#
Newtonsoft.json でバイト配列をシリアライズすると、BASE64 にエンコードされて出力されてしまいます。
```cs var foo = new Foo { Data = new byte[] { 0x48, 0x49, 0x1d, 0x52, 0x53, 0x1d, 0x56, 0x57, 0x00 } }; var json = JsonConvert.SerializeObject(foo); Console.WriteLine(json); ``` ```cs public class Foo { public byte[] Data { get; set; } } ``` **出力結果** ```sh {"Data":"SEkdUlMdVlcA"} ``` 個人的には以下のように出力されることを期待していました。 ```cs {"Data":[48, 49, 1D, 52, 53, 1D, 56, 57, 00]} ``` ## 解決策 配列ではなくリストを使うと解決されるという記事を見て、上記のコードを変更したら期待した出力になりました。 しかし、他のケースではリストでも BASE64 で出力される場合があったりしたので、素直に `int` に変更しました。
## 参考 URL - https://www.newtonsoft.com/json/help/html/SerializationGuide.htm - https://stackoverflow.com/questions/55153522/why-does-newtonsoft-json-serializes-byte-as-base64-but-sbyte-not
Read more
2020/04/03
image
NO IMAGE
[ASP.NET Core] TempData を使っている場合のテストコードの書き方
update
event_note
label
ASP.NET Core
label
C#
Moq を使って TempData の Mock を作成してテストコードを書く方法です。
`TempDataDictionaryFactory` を使って `TempData` を作成して、Controller に渡します。 ```cs var tempDataDictionaryFactory = new TempDataDictionaryFactory(Mock.Of
()); var tempData = tempDataDictionaryFactory.GetTempData(new DefaultHttpContext()); var controller = new ShokiSetteiController(shiyouSetteiCreator, httpContextAccessor.Object, messageLocalizer.Object, wordLocalizer.Object) { TempData = tempData, }; ```
## 参考 URL - https://stackoverflow.com/questions/55914515/how-to-test-controller-method-that-use-tempdata-in-asp-mvc-core - https://stackoverflow.com/questions/52181767/mocking-a-tempdata-in-asp-net-core-in-mstest
Read more
2020/03/26
image
NO IMAGE
dotnet コマンドでビルドする際にプライベートな NuGet サーバーを参照する
update
event_note
label
.NET Core
プライベートな NuGet サーバーを使用しているとき、Visual Studio を使用している場合はオプションで NuGet のサーバーを追加できますが、`dotnet` コマンドでビルドする場合にどうやって NuGet サーバーの設定をやるのか分からなくて悩んだのでメモしておきます。
`dotnet restore` コマンドで NuGet パッケージの復元を行うことができますが、このときに `--source` オプションを指定することで NuGet サーバーを指定できます。 ```sh dotnet restore --source http://example.com/nuget ``` ただし、上記のように指定すると、今度は公式の NuGet サーバーからの復元ができなくなったので、公式とプライベート両方の NuGet サーバーを指定してやる必要がありました。 ```sh dotnet restore --source https://api.nuget.org/v3/index.json --source http://example.com/nuget ``` 尚、.NET Core 2.0 以降であれば、`dotnet build` コマンドでも `--source` オプションが指定できるようです。
## 参考 URL - https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-restore - https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-build
Read more
2020/03/25
image
NO IMAGE
Windows10 で gitlab-runner をインストールする時に Access is denied となる
update
event_note
label
GitLab
gitlab-runner を Windows10 でインストールしようとしたとき、以下のようなエラーが出ました。
``` >gitlab-runner install Runtime platform arch=amd64 os=windows pid=2096 revision=4c96e5ad version=12.9.0 FATAL: Failed to install gitlab-runner: Access is denied ``` コマンドプロンプトを管理者として実行すればエラーが出なくなりました。
Read more
2020/03/10
image
NO IMAGE
GitLab のプライベートリポジトリを SSH Key なしで Clone する
update
event_note
label
GitLab
トークン認証を使うのが楽かもしれません。
## トークンの取得 まずはトークンを取得します。 GitLab にログインして、右上のプロフィールアカウントをクリック > `Settings` を選択します。 サイドメニューより `Access Tokens` をクリックします。 `Name` に適当な名前を入力します。 `Scopes` は、クローンするだけなら `read_repository` にチェックを入れれば OK です。 `Create personal access token` を押すと画面上にトークンが表示されるので、それをコピーします。 ## クローン コピーしたトークンを使って、以下のコマンドでクローンできます。 ```sh git clone https://oauth2:54uMLrocCpu2sUU8_4sS@gitlab.com/username/repository.git ```
## 参考 URL - https://hawksnowlog.blogspot.com/2018/02/gitlab-clone-with-token.html - https://hacknote.jp/archives/26324/
Read more
2020/03/09
image
NO IMAGE
System.Net.Sockets.SocketException: 'アクセス許可で禁じられた方法でソケットにアクセスしようとしました。'
update
event_note
label
C#
label
Windows
C# で TCP/IP による通信を行うアプリケーションを作成中に、以下のような例外が発生しました。
> System.Net.Sockets.SocketException: 'アクセス許可で禁じられた方法でソケットにアクセスしようとしました。' ## 他のアプリがポートを使用中でないか確認する まずは以下のコマンドを入力して、指定のアドレスとポートが他のアプリケーションで使用中でないかどうかを確認します。 ```sh > netstat -oan ``` もし使用中であった場合は、そのプロセス ID をもとに、タスクマネージャーなどからアプリケーションを特定すればよいようです。 今回のケースでは使用中のアプリケーションはありませんでした。 ## 他のアプリが TCP ポート除外範囲を設定しているか確認する 以下のコマンドで TCP ポートの除外範囲を確認します。 ```sh > netsh int ipv4 show excludedportrange tcp プロトコル tcp ポート除外範囲 開始ポート 終了ポート ---------- -------- 80 80 48497 48497 49892 49991 50000 50059 * 50060 50159 50160 50259 50460 50559 50560 50659 50666 50765 51162 51261 54473 54572 56110 56209 56210 56309 * - 管理されている除外ポート。 ``` 今回はこの TCP ポート除外範囲に含まれているポートを使用していることが原因でした。 ## 対処方法 とりあえずアプリケーション側で使用するポートを変更できるならそれが簡単です。 ### 除外ポートを追加 また、後日わかったことですが、Docker が原因だったようです。 コマンドプロンプトを管理者として実行し、以下を順番に実行します。 **Hyper-V を停止** ``` bcdedit /set hypervisorlaunchtype off ``` とりあえずこれだけでも再起動後はポートが解放されました。 **除外ポートを設定** ``` netsh int ip add excludedportrange protocol=udp startport=60000 numberofports=10 ``` `プロセスはファイルにアクセスできません。別のプロセスが使用中です。` と表示された場合は一度 Windows を再起動します。 **Hyper-V を ON にする** ``` bcdedit /set hypervisorlaunchtype auto ```
## 参考 URL - http://mroom.xii.jp/nikki/2013/05/post-99.html - https://docs.microsoft.com/ja-jp/advanced-threat-analytics/troubleshooting-ata-known-errors - https://social.technet.microsoft.com/Forums/ja-JP/81beb3b9-5b2a-40cd-81d8-cbe67f57df04/tcp?forum=win10itprogeneralJP - https://qiita.com/masoo/items/b73dadb0e99f9be528fe - https://qiita.com/Hideyasu_Yamazaki/items/2c4cee2c79d928565f9f - https://system2.wiki/windows/76283.html
Read more
2020/03/07
[Python] matplotlib で plot する際に "Tcl_AsyncDelete: async handler deleted by the wrong thread" というエラーがでる
update
event_note
label
Python
matplotlib を使って画像を作成する場合に、たまに以下のようなエラーが表示されます。
**エラー内容** ```sh Exception ignored in:
Traceback (most recent call last): File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 4014, in __del__ self.tk.call('image', 'delete', self.name) RuntimeError: main thread is not in main loop Exception ignored in:
Traceback (most recent call last): File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 4014, in __del__ self.tk.call('image', 'delete', self.name) RuntimeError: main thread is not in main loop Exception ignored in:
Traceback (most recent call last): File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 4014, in __del__ self.tk.call('image', 'delete', self.name) RuntimeError: main thread is not in main loop Exception ignored in:
Traceback (most recent call last): File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 4014, in __del__ self.tk.call('image', 'delete', self.name) RuntimeError: main thread is not in main loop Tcl_AsyncDelete: async handler deleted by the wrong thread ``` ググってみたところ、`matplotlib.use('Agg')` を追加すればよいそうなので、以下のようにして追加しました。 ```py import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt ``` とりあえず今のところ、このエラーは表示されなくなりました。
## 参考 URL - https://catdance124.hatenablog.jp/entry/2019/09/20/113202 - https://stackoverflow.com/questions/50848127/python-plot-image-save-error - https://qiita.com/TomokIshii/items/3a26ee4453f535a69e9e
Read more
2020/03/03
[Python] 非同期処理を完了を待たずに実行する(fire and forget)
update
event_note
label
Python
C# における `async void` と同様の処理を Python ではどうやって書くのか分からなかったので、サンプルコードをメモしておきます。
尚、完了を待たずに実行することを、英語では `fire and forget` というようです。 ## 環境 - python 3.6 ## サンプルコード ```py def foo(sec: int): print(f'start: {sec}秒待ちます') time.sleep(sec) print(f'finish: {sec}秒待ちました') loop = asyncio.get_event_loop() loop.run_in_executor(None, foo, 3) # プログラムが終了しないように待っているだけ(実際には以下は不要) print(f'wait') time.sleep(10) print(f'exit') ``` **出力結果** ```sh start: 3秒待ちます wait finish: 3秒待ちました exit ``` ## もうちょっと汎用的に ```py def fire_and_forget(task, *args, **kwargs): loop = asyncio.get_event_loop() if callable(task): return loop.run_in_executor(None, task, *args, **kwargs) else: raise TypeError('Task must be a callable') def foo(sec: int): print(f'start: {sec}秒待ちます') time.sleep(sec) print(f'finish: {sec}秒待ちました') fire_and_forget(foo, 3) # プログラムが終了しないように待っているだけ(実際には以下は不要) print(f'wait') time.sleep(10) print(f'exit') ``` 出力結果は同じなので省略します。
## 参考 URL - https://dev.classmethod.jp/etc/python-asyncio/ - http://zentoo.hatenablog.com/entry/2016/06/13/045354 - https://qiita.com/kekeho/items/2339ab36bc05d979810a - https://stackoverflow.com/questions/37278647/fire-and-forget-python-async-await
Read more
2020/02/29
[Python] ISO 8601 形式の文字列を datetime に変換する
update
event_note
label
Python
日時を表す形式はいろいろありますが、ここでは ISO 8601 形式の文字列を datetime オブジェクトに変換する方法について記載します。
## 環境 - python 3.6 python 3.7 以降では `fromisoformat()` が使えるみたいですが、今回は諸事情により python 3.6 を対象としています。 ## datetime オブジェクトへの変換 単純に変換するだけのサンプルコードです。 ```py from datetime import datetime timestamp = "2018-03-30T12:34:56.789Z" dt = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f%z') print(dt) ``` **出力結果** ```sh 2018-03-30 12:34:56.789000+00:00 ``` ## datetime オブジェクト同士で差分を計算する場合 ```py from datetime import datetime import pytz timestamp = "2018-03-30T12:34:56.789Z" dt = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f%z') utc_now = datetime.now(pytz.timezone('UTC')) tdelta = utc_now - dt print(tdelta.total_seconds()) ``` **出力結果** ```sh 60572020.293181 ```
## 参考 URL - https://docs.python.org/ja/3/library/datetime.html - https://qiita.com/kidatti/items/272eb962b5e6025fc51e - https://stackoverflow.com/questions/796008/cant-subtract-offset-naive-and-offset-aware-datetimes
Read more
2020/02/21
image
NO IMAGE
testあああああああああああああああああああああああああああああああああ
update
event_note
label
t
label
テスト
label
ぴよ
label
ラベル
label
ラベル1
tttt
Read more
続きを読む »
2020/02/19
image
NO IMAGE
test
update
event_note
label
テスト
label
ラベル
テストだよん
Read more
続きを読む »
ほげ
update
event_note
label
ぴよ
ほげほげ
Read more
続きを読む »
2020/02/18
image
NO IMAGE
タイトル
update
event_note
label
ぴよ
label
ラベル
label
ラベル1
summary
Read more
続きを読む »
2020/02/07
Grafana で凡例をフィールド名にする
update
event_note
label
Grafana
label
InfluxDB
InfluxDB のデータに対して Grafana でパネルを作成したとき、グラフの凡例は `メジャーメント名.集約関数` となりますが、これをフィールド名にする方法です。
## 問題点 通常は以下のように凡例が `メジャーメント名.集約関数` で表示されます。
一応 `alias` で任意の名前をつけることができるので、そこにフィールド名を入力すれば表示を変えることはできますが、それでもメジャーメント名は必ず先頭についてしまいます。
これを、先頭にメジャーメント名がつかないようにして、フィールド名だけを表示するようにします。 ## ALIAS BY に表示したい名前を入力する 1つのフィールドしか表示していないのであれば、これがもっとも簡単です。
### 複数のフィールドを表示している場合 1つのクエリで複数のフィールドを表示している場合、上記の方法だとすべての凡例が `ALIAS BY` で設定した名前になってしまいます。
この場合、以下のようにクエリを分けることで一応対応できます。
しかし、1つのクエリで複数のフィールドを表示している場合は、後述するように `$col` を使う必要があります。 ## ALIAS BY に $col を指定する `ALIAS BY` で指定できる置換パターンの一つに `$col` があります。 - https://grafana.com/docs/grafana/latest/features/datasources/influxdb/ ただし、`$col` を指定した場合に表示されるのは、フィールドではなく集約関数の名前です。
InfluxDB は必ず集約関数を必要とするので、集約関数をなしにすることはできません。 従って、結局全てのフィールドに `alias` を設定してやる必要があります。 そうすれば、凡例が各フィールドの `alias` で入力した値に置換されます。
うーん・・・、フィールド名を表示したいだけなのに結構面倒ですね。 普通に考えて凡例はフィールド名がデフォルトであるべきだと思うんですけどね。
## 参考 URL - https://github.com/grafana/grafana/issues/4655
Read more
2020/02/06
Grafana でダッシュボードを複製(コピー)する
update
event_note
label
Grafana
Grafana でダッシュボードを複製する方法がちょっと分かりづらかったのでメモしておきます。
コピーしたいダッシュボードの右上から `Dashboard settings` のアイコンをクリックします。
左のメニューから `Save As ...` をクリックします。
`Save` をクリックすると新しい名前でダッシュボードが保存(複製)されます。
Read more
2020/01/27
image
NO IMAGE
[JavaScript] 数値の変わった表記
update
event_note
label
JavaScript
Java Script の数値の表記で見慣れないコードに遭遇し、意味が分からなかったので調べた結果です。
数値型全般については以下の記事で詳しく解説されています。 - https://qiita.com/uhyo/items/f9abb94bcc0374d7ed23 ここでは私が戸惑った表記をピックアップしてメモしておきます。 ## 指数表記 数値の後ろに `e` を付けると、それ以降は 10 の指数と解釈されるようです。 ```js console.log(1e4) // 10000 console.log(1e-4) // 0.0001 console.log(3e3) // 3000 ``` ## 整数への変換 実数に対してビット演算を行うと 32 ビット整数に変換されるようです。 ```js console.log(1.234 | 0) // 1 ```
## 参考 URL - https://qiita.com/uhyo/items/f9abb94bcc0374d7ed23
Read more
2020/01/22
[Python] インデックス付きのループ
update
event_note
label
Python
リストなどを for で回すときにインデックスが欲しい場合は `enumerate` を使います。
## 環境 - python 3.8.1 ## サンプルコード ```py hoge = [10, 20, 30] for index, value in enumerate(hoge): print(index, value) ``` **実行結果** ```sh 0 10 1 20 2 30 ``` ## 逆順で出力するときの注意 単純に逆順で出力すると以下のようになります。 ```py hoge = [10, 20, 30] for index, value in enumerate(hoge[::-1]): print(index, value) ``` ```sh 0 30 1 20 2 10 ``` インデックスも逆順に出力したい場合は少し計算してやる必要があります。 ```py hoge = [10, 20, 30] for index, value in enumerate(hoge[::-1]): print(len(hoge) - index - 1, value) ``` ```sh 2 30 1 20 0 10 ```
Read more
2020/01/16
image
NO IMAGE
ASP.NET Core (.NET Core) でバックグランドタスクを起動する
update
event_note
label
.NET Core
label
ASP.NET Core
ASP.NET Core (.NET Core) において、アプリケーションの起動に合わせてバックグラウンドタスクを起動させる方法です。
- https://docs.microsoft.com/ja-jp/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice ## 環境 - Visual Studio 2017 - .NET Core 2.2 ## 概要 `IHostedService` を実装したサービスクラスを作成します。 `IHostedService` を使用するには、Nuget で `Microsoft.Extensions.Hosting` を追加する必要があります。 サービスクラスを `IHostedService` として DI コンテナに登録すると、Host が自動でバックグラウンドタスクとして実行してくれるようです。 Host については、作成するアプリケーションによって以下の2種類があるようです。 - ASP.NET Core で使用する Web ホスト (IWebHostBuilder) - ASP.NET Core 以外で使用する汎用ホスト (HostBuilder) ASP.NET Core の場合、テンプレートからプロジェクトを作成した段階で Web ホストが使用されている状態なので、特に意識はしなくても大丈夫そうですが、コンソールアプリなどの場合は汎用ホストを使用するように実装する必要があります。 ## ASP.NET Core の場合(Web ホスト) ASP.NET Core のほうが話が簡単なので、先に ASP.NET Core で説明します。 コンソールアプリなどでは必要となる汎用ホストについては後述します。 ### IHostedService の実装 [公式のドキュメント](https://docs.microsoft.com/ja-jp/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice)に詳しく書いてありますが、ほとんどのバックグラウンドタスクではタスクの開始や終了といった動作は同じであるため、`IHostedService` を実装した抽象クラスを作成しておくと良いようです。 サンプルコードをそのまま引用します。 ```cs // Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0. ///
/// Base class for implementing a long running
. ///
public abstract class BackgroundService : IHostedService, IDisposable { private Task _executingTask; private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource(); protected abstract Task ExecuteAsync(CancellationToken stoppingToken); public virtual Task StartAsync(CancellationToken cancellationToken) { // Store the task we're executing _executingTask = ExecuteAsync(_stoppingCts.Token); // If the task is completed then return it, // this will bubble cancellation and failure to the caller if (_executingTask.IsCompleted) { return _executingTask; } // Otherwise it's running return Task.CompletedTask; } public virtual async Task StopAsync(CancellationToken cancellationToken) { // Stop called without start if (_executingTask == null) { return; } try { // Signal cancellation to the executing method _stoppingCts.Cancel(); } finally { // Wait until the task completes or the stop token triggers await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken)); } } public virtual void Dispose() { _stoppingCts.Cancel(); } } ``` そして、この抽象クラスを継承してバックグランドで動かしたいサービスクラスを定義します。 コードの概要は以下です。 ```cs public class SampleService : BackgroundService { public SampleService() { // コンストラクタへの引数は自動で DI される } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // ここに常駐処理を定義する } } ``` `ExecuteAsync` 内では `while` で常駐処理を定義し、タスクの終了のチェックなども行います。 以下、[公式のドキュメント](https://docs.microsoft.com/ja-jp/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice)のサンプルを引用します。 ```cs public class GracePeriodManagerService : BackgroundService { private readonly ILogger
_logger; private readonly OrderingBackgroundSettings _settings; private readonly IEventBus _eventBus; public GracePeriodManagerService(IOptions
settings, IEventBus eventBus, ILogger
logger) { //Constructor’s parameters validations... } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogDebug($"GracePeriodManagerService is starting."); stoppingToken.Register(() => _logger.LogDebug($" GracePeriod background task is stopping.")); while (!stoppingToken.IsCancellationRequested) { _logger.LogDebug($"GracePeriod task doing background work."); // This eShopOnContainers method is querying a database table // and publishing events into the Event Bus (RabbitMQ / ServiceBus) CheckConfirmedGracePeriodOrders(); await Task.Delay(_settings.CheckUpdateTime, stoppingToken); } _logger.LogDebug($"GracePeriod background task is stopping."); } .../... } ``` ### DI コンテナへのサービスの追加 `Startup.cs` の `ConfigureServices` メソッドで、サービスクラスを DI コンテナに登録します。 `IHostedService` を実装したクラスを `AddHostedService` で登録していきます。 (`AddSingleton` でも可) ```cs public void ConfigureServices(IServiceCollection services) { // ... services.AddHostedService
(); services.AddHostedService
(); // または services.AddSingleton
(); services.AddSingleton
(); } ``` ## 汎用ホスト ASP.NET Core 以外(例えばコンソールアプリなど)では汎用ホストを作成する必要があります。 基本的なコードは以下です。 ```cs public static async Task Main(string[] args) { var host = new HostBuilder() .Build(); await host.RunAsync(); } ``` ### IHostedService の実装 前述の ASP.NET Core と同様のため省略します。 ### DI コンテナへのサービス追加 `IHostedService` を DI するためにも、DI コンテナにサービスを追加する必要があります。 `ConfigureServices` で行います。 ```cs var host = new HostBuilder() .ConfigureServices((hostContext, services) => { services.AddHostedService
(); services.AddHostedService
(); // または services.AddSingleton
(); services.AddSingleton
(); }) .Build(); await host.RunAsync(); ``` `ConfigureServices` の中身については ASP.NET Core と同じです。 他にもいろいろ設定可能ですが、ここでは DI コンテナしか関係ないので、省略します。 詳細は以下を参照してください。 - https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/generic-host
## 参考 URL - https://docs.microsoft.com/ja-jp/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice - https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2 - https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2
Read more
新しい投稿
前の投稿
ホーム
Translate
Popular Posts
TortoiseGit でコミットメッセージを変更する
image
NO IMAGE
TortoiseGit でブランチ間の差分を見る
image
NO IMAGE
[ASP.NET Core] 前のページ(遷移元)の URL を取得する
image
NO IMAGE
外部 DLL を NuGet パッケージに含める方法
image
NO IMAGE
[C#] SonarQube で .NET アプリケーションのコード解析を行う
image
NO IMAGE
[ASP.NET Core] Form value count limit 1024 exceeded のエラーが発生した
image
NO IMAGE
マージ元ブランチとマージ先ブランチ
TortoiseGit でリモートリポジトリのタグを削除する
image
NO IMAGE
C# で GitHub からリリースバージョンを取得する
[Jenkins] エラー 1069: ログオンに失敗したため、サービスを開始できませんでした。
Labels
.NET Core
31
.NET Framework
17
.NET Standard
2
AdminLTE
1
Apache
3
AppVeyor
2
AsciiDoc
3
ASP.NET Core
55
Atom
4
AWS
2
AWS Cloud9
4
blockdiag
1
Blogger
10
Bootstrap
3
C/C++
6
C#
106
CentOS
3
Chrome
1
Chronograf
3
Codecov
1
CSS
1
Docker
28
DokuWiki
4
Doxygen
1
draw.io
1
Electron.NET
2
Entity Framework Core
9
Excel
2
FFmpeg
2
Firefox
5
Git
12
GitBook
4
GitBucket
7
GitHub
7
GitLab
30
Go
1
Google
1
Google Cloud Platform
1
Grafana
5
HTML
5
IIS
8
InfluxDB
6
JavaScript
7
Jenkins
7
Linux
25
Log4View
1
MahApps.Metro
3
MaterialDesignInXamlToolkit
1
MVC
1
MVVM
6
NLog
3
Node.js
3
npm
1
OpenSSL
3
ownCloud
2
Pine Script
1
PlantUML
5
PowerShell
7
Prism
2
Python
11
Razor
3
Redmine
30
remark.js
2
rocketchat
4
Ruby
3
SignalR
1
Socket.IO
1
SonarQube
5
Sphinx
10
SQL Server
5
SQLite
1
t
1
TestLink
2
Tomcat
2
TortoiseGit
10
TortoiseSVN
2
Trading View
1
Travis CI
1
Ubuntu
13
Visual Studio
39
Visual Studio Code
9
Vue.js
8
Windows
56
Windows 10
4
Windows ADK
1
Windows API
2
Windows Embedded
4
wkhtmltopdf
2
Word
3
WPF
12
WSL
1
Xamarin
1
xUnit
5
アプリケーション
1
デザインパターン
1
テスト
3
バッチファイル
2
ぴよ
3
プログラミング
3
ライセンス
1
ラベル
3
ラベル1
2
英語
2
雑記
1
書籍
1
数学
1
正規表現
1
Blog Archive
►
2022
(1)
►
2月
(1)
►
2021
(24)
►
5月
(7)
►
4月
(8)
►
3月
(2)
►
2月
(2)
►
1月
(5)
▼
2020
(60)
▼
12月
(1)
Interop.WordDocuments.Open が null になる
►
11月
(3)
[C#] 2つのリストを結合して1つの新しいリストにする
[C#] 配列やリストが昇順 or 降順になっているかどうかを調べる
gitbook のプラグインのバージョンを指定する
►
10月
(3)
gitlab-ci で git の submodule をアップデートしたい場合
[ASP.NET Core] Form value count limit 1024 exceede...
外部 DLL を NuGet パッケージに含める方法
►
9月
(3)
/platform:anycpu32bitpreferred は、/t:exe、/t:winexe、...
GitLab のログをローテーションに設定する
[ASP.NET Core] 前のページ(遷移元)の URL を取得する
►
8月
(3)
wkhtmltopdf で PDF に変換した際に canvas 内の日本語だけが文字化けする
[C#] 文字の Unicode を取得
wkhtmltopdf で canvas に何も描画されない
►
7月
(7)
[C#] コンパイラが必要とするメンバー 'Microsoft.CSharp.RuntimeBind...
[ASP.NET Core] Razor 構文が有効にならない?
GCP で Docker を使う
[C#] Stream に対して ReadAllLines を行いたい
[JavaScript] Minify 時に `Implicit property name mus...
[C#] コンストラクタで base と this を両方使いたい
[C#] xUnit で MemberData を使ったテストがテストエクスプローラーで1つのテスト...
►
6月
(7)
[C#] ClassData でテストデータを作成する際に、テストクラス内のリソースにアクセスしたい
[C#] nameof 演算子の代わりにフルネームを返すメソッドを作る
[ASP.NET Core] ModelState のチェックを無効化
[C#] Null 許容型かどうかを判別する
[C#] 非同期メソッドのモック
[C#] リストをデシリアライズしたときに項目が追加登録されてしまう
[C#] DateTime 型を含むデータのシリアライズ
►
5月
(2)
Moq で System.NotSupportedException : Unsupported e...
IIS + ARR + URL Rewrite で ASP.NET Core アプリケーションにアク...
►
4月
(6)
[C#] 文字列内の文字が全て同じかどうかをチェックする
OpenSSL で SAN 付きの自己署名証明書を作成する
OpenSSL で作成したサーバー証明書を IIS にインポートする
submit ボタンにアイコンを表示する
[C#] バイト配列のシリアライズ
[ASP.NET Core] TempData を使っている場合のテストコードの書き方
►
3月
(6)
dotnet コマンドでビルドする際にプライベートな NuGet サーバーを参照する
Windows10 で gitlab-runner をインストールする時に Access is de...
GitLab のプライベートリポジトリを SSH Key なしで Clone する
System.Net.Sockets.SocketException: 'アクセス許可で禁じられた方...
[Python] matplotlib で plot する際に "Tcl_AsyncDelete: ...
[Python] 非同期処理を完了を待たずに実行する(fire and forget)
►
2月
(7)
[Python] ISO 8601 形式の文字列を datetime に変換する
testあああああああああああああああああああああああああああああああああ
test
ほげ
タイトル
Grafana で凡例をフィールド名にする
Grafana でダッシュボードを複製(コピー)する
►
1月
(12)
[JavaScript] 数値の変わった表記
[Python] インデックス付きのループ
ASP.NET Core (.NET Core) でバックグランドタスクを起動する
►
2019
(92)
►
12月
(13)
►
11月
(9)
►
10月
(3)
►
9月
(2)
►
8月
(3)
►
7月
(5)
►
6月
(11)
►
5月
(6)
►
4月
(17)
►
3月
(9)
►
2月
(6)
►
1月
(8)
►
2018
(100)
►
12月
(1)
►
11月
(11)
►
10月
(8)
►
9月
(6)
►
8月
(10)
►
7月
(10)
►
6月
(8)
►
5月
(9)
►
4月
(8)
►
3月
(14)
►
2月
(4)
►
1月
(11)
►
2017
(117)
►
12月
(14)
►
11月
(20)
►
10月
(17)
►
9月
(19)
►
8月
(10)
►
7月
(8)
►
6月
(3)
►
5月
(6)
►
4月
(5)
►
3月
(2)
►
2月
(8)
►
1月
(5)
►
2016
(91)
►
12月
(5)
►
11月
(9)
►
10月
(11)
►
9月
(9)
►
8月
(6)
►
7月
(14)
►
6月
(14)
►
5月
(11)
►
4月
(10)
►
3月
(2)
►
2015
(23)
►
12月
(4)
►
11月
(2)
►
10月
(8)
►
9月
(8)
►
7月
(1)
►
2013
(3)
►
11月
(1)
►
9月
(1)
►
7月
(1)
►
2012
(2)
►
7月
(1)
►
6月
(1)
►
2011
(1)
►
9月
(1)
►
2009
(1)
►
7月
(1)
►
2008
(2)
►
11月
(1)
►
7月
(1)
►
2007
(3)
►
10月
(3)