- 投稿日:2020-03-25T22:00:56+09:00
.Net Core 3.1のコンソールアプリを、単一実行可能ファイルかつRuntimeのインストールなしでUbuntu 18.04で実行する
Publish Single Fileとself-containedを試してみたので、やったことの備忘です。
下記の記事を参考にしながら進めました。
.NET Core CLI を使用して .NET Core アプリを発行する
.NET Core 3.0のPublish Single File概要前提
やりたいこと
- .Net Core 3.1のコンソールアプリをUbuntu 18.04で実行したい
- Ubuntu 18.04に.Net Core 3.1のRuntimeをインストールしたくない
- 管理が面倒なので、単一実行可能ファイルにしたい
環境
開発環境
- Windows 10
- Visual Studio 2019実行環境
- Ubuntu 18.04実装方法
1. コンソールアプリを作る
Visual Studioのテンプレートからコンソールアプリを選び、ソリューションを作成します。
動くことが確認できればいいので、1秒ごとに「Hello World!」と出力するようにProgram.cs
を修正しました。Program.csusing System; using System.Threading; namespace SingleFileConsole { class Program { static void Main(string[] args) { while (true) { Console.WriteLine("Hello World!"); Thread.Sleep(1000); } } } }2. アプリケーションを発行する
- 開発者用コマンドプロンプトを起動する
ツール(T)
>コマンドライン(L)
>開発者用コマンドプロンプト(C)
dotnet publish -c Release -r linux-x64 /p:PublishSingleFile=true
を実行する- 実行ファイルが発行されていることを確認する(画像参照)
3. アプリケーションを実行する
- Windows 10で開発したアプリケーションを、Ubuntu 18.04にコピー
- ターミナルを立ち上げて、アプリケーションを配置したディレクトリまで移動
chmod +x SingleFileConsole
でアプリケーションを実行可能形式にする./SingleFileConsole
でアプリケーションを実行する
- 投稿日:2020-03-25T20:28:17+09:00
[PlayFab] データをクラウドセーブしたい時のAPIの選び方
前置き
- クラウドにファイルをセーブする機能を実装するために関連するPlayFabの仕様を調べました
- 2019/Dec時点の仕様です。調べてから時間が空いてますが書く時間が取れたので記事にしたということで。
- 実装自体は大きくつまづく箇所もなく、リリース済みアプリ内で利用中です。
2系統のAPI
クラウドセーブを実装する場合に使うことになるPlayFab提供APIは、大きく分けると2つの系統があります。クラシックとエンティティEntityです。
クラシックAPIの特徴
- 「ユーザー1人あたり」がサイズ制限になっていることが多い
- ファイルを扱う場合はstringに変換する必要がある
- 2018年以前はこの系統のAPIのみが提供されていたので系統名がなかった。Entityが登場したのでクラシックと呼ばれることに。本命登場で幼なじみと呼ばれるようになった感ある。
Entity APIの特徴
- 2018年に導入されたAPI
- JSONファイルやオブジェクトを直接扱える
- 「アプリ全体が利用している量」がサイズ制限になっていることが多い
- PlayFabは、同じことができる場合こちらを使うことを推奨している
2つのAPIをTier毎に比較
ESSENTIAL Tier PRO/Indie Tier クラシック API 10000Byte/ユーザー※ (運営に相談/ユーザー) Entity API 1GB/プロジェクト 50TB/プロジェクト
- プロジェクトに必要なスペック&財布に応じて選ぶといいと思います
- ※だいたい10000byteでなく、本当にきっちり10000byteです1byteでも超えていると、超えているのではじきましたというメールまで届きます。ちょっとくらい超えても大丈夫かなと淡く期待していましたがそんなことなかったです。
Tier
PlayFabの料金プランはTierで分かれている
ESSENTIAL 無料 Indie/PRO 有料 月99$/299$ ENTERPRIZE 有料、法人向け ※IndieはMAU10万超えでPROに自動移行、受けられるサービスは同じ
詳しい記事 => PlayFab 各プランのAPI制限値とか比較してみたどちらを選んだか
- 自分は、Essential Tierで利用中で、ユーザー数がどこまで増えるのか予測が難しかったので、10000byteと極小容量ですがユーザー数が増えても同容量使えるクラシックAPIを選びました。実際にどんなコードを組んでいるのかも時間がある時に記事にします。
- 投稿日:2020-03-25T19:44:20+09:00
null安全とLINQ
前書
流石にLINQまでフロー解析はしてくれないらしい
直面した場面
public static int? ToIntOrNull(int num) { return num % 2 == 0 ? (int?)null : num; } // public static IEnumerable<int> TestFunc1() { //kは非nullが確定しているが警告が出る //CS8629 Null 許容値型は Null になる場合があります。 return Enumerable.Range(0, 10) .Select((i) => ToIntOrNull(i)) .Where((j) => j != null) .Select((k) => (int)k); } public static IEnumerable<int> TestFunc2() { //!演算子をつければ警告は出ない return Enumerable.Range(0, 10) .Select((i) => ToIntOrNull(i)) .Where((j) => j != null) .Select((k) => (int)k!); }追記
コメントを頂いたのでそのまま転記
OfType()を使えばすっきり綺麗に書けるそうですpublic static IEnumerable<int> TestFunc3() { return Enumerable.Range(0, 10) .Select((i) => ToIntOrNull(i)) .OfType<int>(); // 1,3,5,7,9 }
- 投稿日:2020-03-25T12:50:54+09:00
dotnet coreにおけるhttp proxy設定に関する注意点
はじめに
dotnet coreの2.1と3.0以降で、System.Net.Http.HttpClientのデフォルトhttpプロキシに関する挙動が異なるところがあったので記述する。
dotnet core 3.0以降
正式な仕様としては https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.defaultproxy?view=netcore-3.1 に記載がある。訳すと、
- 明示的な指定がない場合、全てのプラットフォームで環境変数の値をまず確認する
- http_proxy,https_proxy,all_proxy,no_proxyの三つ(大小文字問わず)
- ない場合は、OSごとに処理が異なる
- linuxはプロキシなしとして扱う
- winはOS設定(winhttpとwininetの設定)を使用する
- winhttpとwininetの両方で設定があった場合、wininetの方の設定が優先される
- macはOS設定を使用する
dotnet core 2.1
HttpClient.DefaultProxyは2.1に存在しないため他にないか探したが、ドキュメントには存在しなかった。
自分で調べた結果、まとめると、
- linuxの場合は環境変数のみ
- winの場合は環境変数は無視され、OS設定(winhttp,wininet)を使用する
- macの場合はシステム設定は無視され、環境変数のみ使われる
という具合のようだ。
主な差異
- winの場合、netcoreapp3.0の時は環境変数を優先して使用するが、netcoreapp2.1では考慮もされない
- linuxの場合は挙動は同じ
- macの場合は、netcoreapp2.1ではOS設定が無視される
まとめ
プロキシ設定というのは見過ごされやすい盲点になるので、挙動の違いは把握しておきたい。
特にmacは持ってないのでソースベースの解析になるが、間違っていたら指摘希望。
- 投稿日:2020-03-25T01:01:39+09:00
今更ながらWPFに置き換えてみる(8)
画面の右上、右下にWindowを飛ばすボタンをテスト。
アイコン化→通常Windowへ復帰した場合、画面の上限、右端、下限に接している場合現状のtop,leftを固定せずに拡大方向を切り替えてどのように見えるかを確認してみた。
Windowの位置、サイズについては直接this.left、this.topをセットするというのが一番単純な方法ですが、それだと最低でも2ステップの実行となってしまいトランジション中にがたつきが目立つので、Win32のSetWindowPosでまとめてセットするように変更。
Windowの位置変更は非常に速いが、サイズの変更は予想通り処理が重い。
位置変更トランジションは中間に100ステップ入れていますがほとんど瞬間移動しているように見えます。
サイズの変更は30ステップ程度でタイミング的に釣り合うイメージでした。新たに出てきた問題点
・Windowの位置変更にDragMoveを利用しているが、ドラッグ中のスクリーン枠へのスナップがForms+VBの時のように簡単にいかない(気がする)
- 投稿日:2020-03-25T00:43:54+09:00
VB6→C#化における、ラッピング戦略
コンバートしたソースを最大限利用する方法
プロジェクトの参照で、C# WinFormsプロジェクトの基本的な参照のみを残し、削除する
これにより、コンバート時に変換された、VB6互換部品のコードが全てエラーになる。
(詳細は、後日追記する)SharpDevelopで新たに追加された、MyApplicationなどのStatic対応も全て使わないことにする。
参考にすることはある可能性はあるので、ファイル全体をコメントアウトしておく。Using句のネームスペース設定中、Microsoft.VisualBasic 名前空間、Microsoft.VisualBasic.Compatibility.VB6 名前空間は参照を削除したことによって赤いアンダーラインが表示されるが、残しておく。この名前空間を利用し、エラーになっている部分を拾うことになる。
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic?view=netframework-4.8
一部、LenBやErr()など、上記の名前空間に属する関数などが省略された形で記述されているが、
一括変換又は、下記で記述するマイグレーションサポート用のクラスへ実装することにする。詳細は後述する。
簡単に説明すると、この関数らを含むフォームを継承したクラスを作り、全てのフォームはそれらを継承するようにする。
Class MigSupForm : Form
{
LenB(){};
Err();
}
Class FrmXXX : MigSupForm
{}
GridAxMSFlexGrid
MSWinsockLib
axWinsck
ADODBこれらのOCX部品に関しても、Microsoft.VisualBasic 名前空間、Microsoft.VisualBasic.Compatibility.VB6 名前空間へ属する
関数として作ることにより、変換ソースを極力修正しないようにする。名前空間を利用する目的としては、一行一行の手間を省くためである。これは、実際やっていただければ納得するはず。
ここまでは無難な作業である。なんでやるかは、
VB6関連ソースを一括に管理するため、
移行の土台に素早く乗らせるため、
リファクタリングを活用することで、もっと効率的な作業を進めるため。
。。。型の曖昧さの問題は、演算子周りで起きており、キャストを施すのは、最終的に道ではあるが、全てを手作業するのは大変である。
この解決策として、演算子のオーバーロードを施す事はどうだろうか。
全ての形ではない問題が起きている型のみを作成することにする。ジェネリックも応用できそう
https://ufcpp.net/study/csharp/sp2_generics.htmlBOXING、UNBOXINGも応用できそう。
オブジェクト型には全てが入る。
using System;class Test
{
static void Main() {
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}頻発する、Form を Objectへ代入、ShortにIntを代入 は
VBSObject クラス、VBSShortクラスを作り、演算子を定義すればそうだろうか。全体的にStaticとなっているので、最初は、SharpDevelop作成サポートクラスに似せた
静的サポートクラスを作成する。ここにMain関数も入れておく。フォームのクラス名でそのまま利用などは、SharpDelelop作成クラスでの定義を利用するように変換されているので、
それに似せるような形をとる。win32 C# 関数
ちょっと変換が変なので、見直しが必要。
https://www.atmarkit.co.jp/ait/articles/0305/09/news004.htmlここで結構調べられる
https://www.pinvoke.net/index.aspx配列 コントロール C#
http://tki.main.jp/hata/indexer.htmlこのコンセプトのファイルは、DLLのプロジェクトにして、共通としてインポートするといいでしょう。
全体を早く見渡し、少しでも早く軌道に乗せたい。