Windows 10 のライフサイクル
Windows 10 の Fall Creators Update がリリースされました。 過去の更新プログラムのサポート終了を調べましたのでメモします。
- Windows ライフサイクルのファクト シート
更新プログラムと Service Pack
デスクトップ オペレーティング システム | 提供日 | サポート終了 |
---|---|---|
Windows Vista SP1 | 2008年2月4日 | 2011年7月12日 |
Windows Vista SP2 | 2009年5月26日 | 2017年4月11日 |
Windows 7 SP1 | 2011年2月22日 | 2020年1月14日 |
Windows 8.1 | 2013年10月18日 | N/A |
Windows 10 Version 1507 (初期バージョン) | 2015年7月29日 | 2017年5月9日 |
Windows 10 Version 1511 (November Update) | 2015年11月10日 | 2017年10月10日 |
Windows 10 Version 1607 (Anniversary Update) | 2016年8月2日 | 2018年3月(仮) |
Windows 10 Version 1703 (Creators Update) | 2017年4月5日 | 2018年9月(仮) |
Windows 10 Version 1709 (Fall Creators Update) | 2017年10月17日 | 2019年3月(仮) |
Windows 10 サポートのロードマップ
Anniversary Update は最近出たような気がしていましたが、来年3月にはサポート終了します。
.NET Framework と WPF についてバージョン毎の機能
.NET Framework と WPF について主にバージョン毎の機能についてまとめた資料をメモします。
.NET
WPF
タイトル | URL |
---|---|
WPF バージョン履歴 (WPF: Versions, History and Major Enhancements) | https://www.codeproject.com/Articles/1035800/WPF-Versions-History-and-Major-Enhancements |
WPF Version 4.5 の新機能 | WPF Version 4.5 の新機能 |
プログラミング.NET Framework 第4版 (Microsoft Press)
- 作者: Jeffrey Richter,藤原雄介
- 出版社/メーカー: 日経BP社
- 発売日: 2013/10/10
- メディア: 単行本
- この商品を含むブログ (9件) を見る
NuGet クイックスタート | nupkg をつくる
NuGet の公式ドキュメント からたどれる場所に nupkg を作るための Quickstart がおいてありまして参考になりました。
TL;DR
- nugetコマンドがある
- nuget spec hoge.csproj にて .nuspec のひな形がつくれる
- nuget pack hoge.csproj にてパッケージ(.nupack)がつくれる
- nuget push hoge.1.0.0.0.nupkg にて パッケージを公開できる
Quickstart の場所
まずは、 Quickstartへの行き方です。
nuget.org の Documentation をクリックします。
Create a Package をクリックします。
ここです。(最初は Create a Package だけだったのかもしれませんね。 Publish まで含まれています)
では、Quickstart に沿って、簡単にメモしながら実行していきたいと思います。
事前準備 必要なインストール
nuget.exe をダウンロードしてパスの通っている箇所におきました。
現時点(2017/3/15)では v3.5.0 が推奨の最新版 (Recommended latest)です。
クラスライブラリ プロジェクトの作成
- クラスライブラリのプロジェクトを作成してください
AppLogger というクラスライブラリをつくりました。
.nuspec パッケージマニフェストファイルを作成する
NuGetパッケージは、内容と依存関係を記述するためのマニフェストファイル(.nuspec)が必要です。 nugetコマンドラインでファイルをつくれます。カスタマイズしてください。
手順に沿って、nuspecファイルのひな形を作成します。
AppLogger.nuspec ファイルが生成されました。
エディタで開いてみます。(使ったエディタは VSCodeです。)
- 下記のような感じで nuspec ファイルを編集します。
<?xml version="1.0"?> <package> <metadata> <id>MyCompanyName.MyProductName.MyPackageName</id> <version>$version$</version> <title>$title$</title> <authors>kraigb</authors> <owners>kraigb</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>Awesome application logging utility</description> <releaseNotes>First release</releaseNotes> <copyright>Copyright 2017</copyright> <tags>application app logger logging logs</tags> </metadata> </package>
パッケージをつくる
nuget pack AppLogger.csproj
のコマンドを実行してください。
- AppLogger.1.0.0.0.nupkg がつくられます。
- 注意: デフォルト値から更新していない場合、警告が表示されることに注意してください。
nuget pack コマンドの実行にて、無事、nupkg ができました。
パッケージの公開
nuget.org の場合
nuget.org にパッケージを公開する場合の手順です。
以上が、Quickstart の手順となります。
おまけ
ここからは、次のステップに向けていくつか調べた内容を記載していきます。
ローカル環境でパッケージを利用する場合
マシンのローカルにおいて利用(インストール)することもできます。
C:\data\NuGetPackeges
を作成し、そこに パッケージを追加する方法です。
以下のバッチファイルを用意しました。ビルド後に実行することで パッケージを追加します。
nuget pack foo.csproj -Prop Configuration=Release set PkgDir=C:\data\NuGetPackages if EXIST %PkgDir% ( for %%N in ( *.nupkg ) do ( %NUGET% add %%N -source %PkgDir% ) )
Visual Studio のソリューションのパッケージ管理のパッケージソースを追加することで NuGet経由で参照することができます。
ありそうな質問
クイックガイドを行った時点でありそうな質問をまとめます。
Debug ビルドの成果物がPack対象になっているみたい。Releaseにできない?
nuget pack foo.csproj は、 bin/Debug 配下の DLL を Pack します。
bin/Release をPackしたい場合は、下記オプション指定でOKです。
> nuget pack Foo.csproj -Prop Configuration=Release`
まとめ
- nuget spec hoge.csproj にて .nuspec のひな形がつくれる
- nuget pack hoge.csproj にてパッケージ(.nupack)がつくれる
- nuget push hoge.1.0.0.0.nupkg にて パッケージを公開できる
参考
nginx を Windows サービスとしてインストールする
はじめに
常時動作しているWindowsマシンがあり、 nginx と Webアプリケーション(nodejsまたはGoやPythonで記述)の組み合わせて提供することができそうで環境構築をしたのでメモします。
nginx は Windows の場合コマンドラインアプリケーションとして動作させることができます。しかしサービス化は、将来の予定にはあるようですが、現時点ではまだ提供されていません。
winswを使って実現しているblogがいくつかありましたので、最新のバージョンの手順です。
- nginx 1.11.10 (現時点のmainlineバージョン)
- winsw 2.0.2.0 (現時点の最新)
nginx のインストールと動作確認
まずは、単体アプリケーションとして起動を確認します。
- 公式サイトから zip をダウンロードして、C:\nginx に展開します
- コマンドプロンプトを開きます。
- start nginx にて起動します
- Windows セキュリティの重要な警告 ダイアログが表示されますので「アクセスを許可する(A)」を選択します
- http://localhost をブラウザで開いてWelcome to nginx! ページが表示されることを確認します
正しくインストールされていることを確認できました。
Windowsサービス化
次に、Windowsサービス化をします。
サービス化には、任意のプロセスをサービス化することができる winsw を利用します。
WinSW をダウンロードします
- WinSW 2.x系は、.NET Framework 2系(~3.5) と、 .NET Framework 4系が提供されています
- 現時点では、 V2.0.2 が 最新です
ダウンロードした WinSW.exe を nginxsvc.exe にリネームします。(この名前は好きな名前で良いです)
<service> <id>nginx</id> <name>nginx</name> <description>nginx</description> <executable>c:\nginx\nginx.exe</executable> <logpath>c:\nginx\</logpath> <logmode>roll</logmode> <depend></depend> <startargument>-p c:\nginx</startargument> <stopargument>-p c:\nginx -s stop</stopargument> </service>
管理者のコマンドプロンプトを開きます
C:\nginx\nginxsvc.exe install
を実行します
起動
- nginx がサービスとして登録されていますので右クリックして起動します
エラー
あれ、エラーになりました。
nginxsvc.err.log
にエラーが出力されていますので、中身を確認します。
nginx: [alert] could not open error log file: CreateFile() " c:\nginx/logs/error.log" failed (123: The filename, directory name, or volume label syntax is incorrect) 2017/03/06 09:35:40 [emerg] 10528#10192: CreateFile() " c:\nginx/conf/nginx.conf" failed (123: The filename, directory name, or volume label syntax is incorrect)
ファイル、ディレクトリ名が不正のようです。
起動オプションの修正
nginxsvc.xml の定義にて、nginx を起動時の引数として -p オプションで指定しているのですが、このあたりが影響してそうです。 削除して試してみます。
C:\nginx\nginxsvc.exe uninstall
にて、一度アンインストールします。
<service> <id>nginx</id> <name>nginx</name> <description>nginx (powered by WinSW)</description> <executable>c:\nginx\nginx.exe</executable> <logpath>c:\nginx\</logpath> <logmode>roll</logmode> <depend></depend> <startarguments></startarguments> <stoparguments>-s stop</stoparguments> </service>
xmlファイル修正 【2017/3/6 15時追記】
- startarguments 、 stoparguments (複数形にする)必要があります
- これにしておかないと Windowsサービスが停止できない状況が発生します
実行
C:/nginx/nginxsvc.exe install
を再度実行します。
うまく起動しました。 ブラウザで http://localhost を開いてみます。
logs\access.log にもアクセス記録が追記されていますので、 conf フォルダや logs フォルダにもアクセスできています。
参考
- https://vexxhost.com/resources/tutorials/nginx-windows-how-to-install/
- startarguments stoparguments の誤りが含まれていますので注意
nginx
winsw
Windows インストーラー: Versionに設定できる数字の範囲
WIndowsインストーラーのバージョン
プログラムのアンインストールまたは変更で、インストールしたプログラムのバージョンを表示することができます。 下記は、 1.0.0.0 と設定しているプログラムの例です。
WiXでは、下記 Product Element の Version で定義します。
<Product Id="{AAEE70F7-54D1-46C4-B351-A7FFADD67405}" Name="Acme FunctionSample" Language="1033" Version="1.0.0.0" Manufacturer="Acme Ltd." UpgradeCode="d3ade0eb-6e9a-4cb5-bd00-4282ef774434">
インストーラーのバージョン番号の範囲
Version="1.400.0.0"
ここで、1.400.0.0 を設定してみました。
しかし、Candle でエラー error CNDL0242 になります。
error CNDL0242: Invalid product version ‘1.400.0.0’. Product version must have a major version less than 256, a minor version less than 256, and a build version less than 65536.
- メジャー番号と、マイナーバージョンは、 256 より小さい数字
- またビルド番号は、 65536 より小さい数字
でないとダメとのことです。
調べたところ、これは、Windowsインストーラーの仕様のようです。
ProductVersion property (Windows)
しかし、アセンブリバージョンでは、 65536まで設定できるので、同じ番号をつけたかったのですが、しかたないですね(´・ω・`)
WPFアプリケーションをEXEひとつにまとめる
はじめに
WPFアプリケーションをインストーラーなどで配置する場合、Prismなどライブラリを使うとDLLを複数配置する必要があります。 WiXを用いる場合は、heat でまとめて wxsソースを自動生成して…といったアプローチが常套手段となりますが、EXEにDLLをマージすることで、EXEひとつを配布する方法を調べました。
ILMergeを使うとDLLをマージできるのですが、XAMLのリソースに対応していないためWPFでは使えないようです。
そこで、さらに調べたところ、下記ブログに記載されている方法がズバリな方法だったので、ご紹介します。 http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application
参照しているDLLをリソースファイルとして埋め込むことで、まとめるというアプローチです。
手順
csproj に追記
csprojをエディタで開きます。 最後の方に追加できるような形でコメントが記載されています。
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> --> </Project>
このコメントの後に下記を追記します。
<Target Name="AfterResolveReferences"> <ItemGroup> <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'"> <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName> </EmbeddedResource> </ItemGroup> </Target>
ビルド結果の確認
一度ビルドしてみましょう。 ビルドされた実行ファイルを 逆コンパイラのILSpy でみると、リソースファイルとして埋め込まれていることがわかります。
DLLの読み込み処理の追加
実行時にDLLを読み込むための処理を追加します。 まず Program.cs を追加します。 下記処理を実装します。
public class Program { /// <summary> /// Main /// </summary> [STAThread] public static void Main() { AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly; App.Main(); } private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); AssemblyName assemblyName = new AssemblyName(args.Name); string path = assemblyName.Name + ".dll"; if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false) { path = String.Format(@"{0}\{1}", assemblyName.CultureInfo, path); } using (Stream stream = executingAssembly.GetManifestResourceStream(path)) { if (stream == null) return null; byte[] assemblyRawBytes = new byte[stream.Length]; stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length); return Assembly.Load(assemblyRawBytes); } } }
次に、アプリケーションのスタートアップオブジェクトを .Program に設定してください。
これでDLLを埋め込んだ状態で起動したりデバッグ実行したりすることができます。
参考
- 作者: Adam Nathan
- 出版社/メーカー: Sams
- 発売日: 2010/06/04
- メディア: ペーパーバック
- 購入: 3人 クリック: 13回
- この商品を含むブログ (4件) を見る
例外処理は重いのでEnum.TryParseを用いたほうが良い
定義した Enum のメンバーに例えば入力した文字列が合致した場合に変換するといったケースはよくあります。
そういった場合に使えるメソッドが標準で用意されています。
文字列表現を Enum に変換するメソッド
-
- Parse は戻り値として変換結果を返します。変換出来ない場合は、例外を返すメソッドです。
-
- TryParse は変換出来ない場合は、戻り値として bool を返します。
使用例
ここでは Enum として元素記号(H, He, Li, Be...と元素番号順)を定義します。
- 入力
- 出力
- 存在した場合はそのメンバーと存在しない場合は 0 を返す、という仕様とします。
ChemicalElementsクラスは下記となります。
static class ChemicalElements { /// <summary> /// 元素記号 /// </summary> public enum SymbolsOfElements { H = 1, He, Li, Be, B, C, N, O, F, Ne, Na, Mg, Al, Si, P, S, Cl, Ar, K, Ca, Sc, Ti, V, Cr, Mn, Fe, Co, Ni, Cu, Zn, Ga, Ge, As, Se, Br, Kr, Rb, Sr, Y, Zr, Nb, Mo, Tc, Ru, Rh, Pd, Ag, Cd, In, Sn, Sb, Te, I, Xe, Cs, Ba, La, Ce, Pr, Nd, Pm, Sm, Eu, Gd, Tb, Dy, Ho, Er, Tm, Yb, Lu, Hf, Ta, W, Re, Os, Ir, Pt, Au, Hg, Tl, Pb, Bi, Po, At, Rn, Fr, Ra, Ac, Th, Pa, U, Np, Pu, Am, Cm, Bk, Cf, Es, Fm, Md, No, Lr, Rf, Db, Sg, Bh, Hs, Mt, Ds, Rg, Cn, Nh, Fl, Mc, Lv, Ts, Og, }; /// <summary> /// Enum.Parse による実装 /// </summary> /// <param name="name"></param> /// <returns></returns> static public SymbolsOfElements GetSymbolParse(string name) { SymbolsOfElements symbol; try { symbol = (SymbolsOfElements)Enum.Parse(typeof(SymbolsOfElements), name); } catch { symbol = 0; } return symbol; } /// <summary> /// Enum.TryParse による実装 /// </summary> /// <param name="name"></param> /// <returns></returns> static public SymbolsOfElements GetSymbolTryParse(string name) { SymbolsOfElements symbol; Enum.TryParse(name, out symbol); return symbol; } }
上記クラスを利用するクラスは下記のような形です。
class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); // A から Z までの文字列配列を作成する var alphabets = Enumerable.Range(0, 26).Select( n => ((char)('A' + n)).ToString() ); // TryParse による処理 Console.WriteLine("処理開始 [TryParse実装] ..."); sw.Start(); for (int i = 0; i < 100; i++) { foreach (var alphabet in alphabets) { var symbol = ChemicalElements.GetSymbolTryParse(alphabet); } } sw.Stop(); Console.WriteLine($"処理時間: {sw.Elapsed}\n"); // Parse による処理 Console.WriteLine("処理開始 [Parse実装] ..."); sw.Restart(); for (int i = 0; i < 100; i++) { foreach (var alphabet in alphabets) { var symbol = ChemicalElements.GetSymbolParse(alphabet); } } sw.Stop(); Console.WriteLine($"処理時間: {sw.Elapsed}\n"); Console.Read(); } }
実行結果
処理開始 [TryParse実装] ... 処理時間: 00:00:00.0036813 処理開始 [Parse実装] ... 処理時間: 00:00:05.8251481
いずれも同じ結果となる処理が、TryParseの場合は、4ms 未満に対し、Parseの場合は、5.8秒となりました。 1500倍くらい差がありますね。
例外処理は重いので Enum.TryParse を用いましょう。