ネコのために鐘は鳴る

寺院に住み着くパソコ〇好き

C#5でもnameofしたい

結論

前置きが長いと結論を早く知りたいマンにボコられるので、 まずはタイトルに対する結論から。

using System;
using System.Linq.Expressions;

public static class GetName
{
    public static string Of<MemberType>(Expression<Func<MemberType>> expression)
    {
        return (expression.Body as MemberExpression).Member.Name;
    }
}

これでC#6未満でもnameofとほぼ同等のことができます。

public class Sample
{
    public string Hoge { get; set; }

    public void Sample()
    {
        // 今回のやり方
        var name1 = GetName.Of(() => Hoge);
        // C#6以降
        var name2 = nameof(Hoge);
    }
}

もっとくわしく

背景

C#6から導入された演算子nameofC#5以前のバージョンでも使いたい。 そもそも何故そんなことがしたいのかと言うと、 オトナの事情により人権を与えられず2019年現在にVisual Studio 2013 (C#5) を使って開発させられているC#erが世の中には存在するからです。

私です。

PropertyChangedイベントなどを実装すると、必ずと言ってもいいほどプロパティの名前を取得したいものです。 そんな時にリテラルでプロパティ名をベタ書きするとVisual Studioの参照が効かないため、あらゆるリファクタリング機能の恩恵を受けられません。

Visual Studioの機能がない状態でC#を書くなど、ナイフ1本でバイオハザード4をクリア [注1] するぐらいマゾヒストもいいところです。

そこで、なんとかしてリテラル文字列を使わず、参照した状態で要素名を取得したいのです。

実装と注意点

やっている内容は、Expressionをラムダ式の形で対象の要素を受け取ると、そのBodyからその要素自身の定義名を取得できることを利用しています。 書き方の簡便さは対象の要素を直接書くだけの本家nameofには負けますが、それなりに短く見た目も使い方もnameofに近くまぁまぁ妥協点ではあると思います。

ちなみにクラス名をNameではなくGetNameにしているのは、Nameはよく使用される使用頻度の高いプロパティ名なので衝突を避ける意味でそうしています。

このGetName.Of()と本家nameofの違いですが、この実装ではプロパティ、フィールド、イベントについては名前が取得できますが、 クラス名、メソッドについては取得できません。本家nameofは全て取れます。何か良い方法があれば教えてください。

それから、nameofは静的解決で定数リテラル扱いであるのに対して、今回のGetName.Ofは動的解決です。 これが何を意味するのかと言うと、例えばnameofによって得られた文字は属性の引数として使えますが、GetName.Ofコンパイルエラーになります。 (属性の引数は静的に決定している必要があるため)

// これはOK
[DisplayName(nameof(Hoge))]
public int SomeProperty { get; set; }

// これはコンパイルエラー
[DisplayName(GetName.Of(() => Hoge))]
public int SomeProperty { get; set; }

あと気になるのは、実行速度でしょうか。テストしました。

public class Sample
{
    public string Hoge { get; set; }

    public void CalcTime()
    {
        var length = 5000000;

        var sw = new Stopwatch();
        sw.Start();
        for(int i = 0; i < length; i++) {
            var name = nameof(Hoge);
        }
        sw.Stop();
        var time1 = sw.ElapsedMilliseconds;
        sw.Restart();
        for(int i = 0; i < length; i++) {
            var name = GetName.Of(() => Hoge);
        }
        sw.Stop();
        var time2 = sw.ElapsedMilliseconds;
        Console.WriteLine($"time1: {time1}ms, time2: {time2}ms");
    }
}

私のPC(Core i5-4300U @ 1.9GH)での計測結果はこちらです

time1: 17ms, time2: 7494ms

nameofに比べて2, 3桁遅いことが分かります。が500万ループで7500msなので1回約1.5us。

この時間を気にかける前にもっとすべき最適化は他にあるでしょう。これを使うことでVisual Studioによって得られる恩恵を考えると十分実用範囲内です。

まとめ

オトナを説得して人権を得て、nameofを使用した方がより幸せになるでしょう。

参考文献

注1 超余裕!瀕死のレオンがナイフ1本でバイオ4攻略1-1【ゆっくり】

(C#) Enumの要素に表示名をつける

やりたいこと

Enumのフィールド名と表示名を分離したい。

最終的な目標として、Sushi.Takoというenumを表示する文字として"タコ"を割り当てたい。かつ汎用性のある構造にしたい。多言語によるローカライズにも対応したい。今回はそういうお話です。


2019/2/2 追記

ローカライズについて → ちゃんと多言語化できるよう追加記事書きました


が、悲しいかなそんなものはデフォルトで用意されていない。

ないものは書く。

以下のようなEnumがあるとします。

public enum Sushi
{
    Tako, Ika, Ebi
}

イカのようなEnumですね。

これをデータとして保持している分には何も問題ないのですが、このデータを画面に表示したい時に普通にToStinrg()すると"Tako","Ika"のように要素名が直に表示されています。困ります。

C#ではクラス名やフィールド名などに使える文字は、一部の予約語や記号を除いてなんでも使えます。すごい。

public enum Sushi
{
   タコ, イカ, エビ
}

非常にやっつけ仕事感満載の上記のenumですが、普通にコンパイルできる上にToString()したらちゃんと日本語で"タコ"になります。 やったね。

やってねえよこのタコ野郎

茶番はこの程度にして本題に入りましょう。

本題

属性を使えばこの問題を解決できます。EnumDisplayNameという属性を作ります。

属性定義

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : Attribute
{
    /// <summary>表示名</summary>
    public string Name { get; set; }

    /// <summary>enum表示名属性</summary>
    /// <param name="name">表示名</param>
    public EnumDisplayNameAttribute(string name)
    {
        Name = name;
    }
}

enum

public enum Sushi
{
   [EnumDisplayName("タコ")]
   Tako,
   [EnumDisplayName("イカ")]
   Ika,
   [EnumDisplayName("エビ")]
   Ebi
}

属性を使ったことでenumのフィールドそのものにメタ情報として表示名を付与することができました。Sushi.Tako"タコ"が別々の場所に定義されていて後から対応づける、といったやり方より、見た目的にもスッキリ1つのenumの定義の中に収まっていていい感じです。

あとはこの属性を取り出す処理を書けばいいだけです。 使用側の見た目的にもいいので拡張メソッドとして実装してみることにしましょう。

拡張メソッド定義

public static class EnumExtension
{
    public static string GetEnumDisplayName<T>(this T enumValue)
    {
        var field = typeof(T).GetField(enumValue.ToString());
        var attrType = typeof(EnumDisplayNameAttribute);
        var attribute = Attribute.GetCustomAttribute(field, attrType);
        return (attribute as EnumDisplayNameAttribute)?.Name;
    }
}

表示名使用側

// Sushi型のenum値
var sushi = Sushi.Tako;

// enum値から表示名を取り出す
var displayName = sushi.GetEnumDisplayName();

日本語のリテラルでハードコーディングではなく、多言語化などでリソースから表示名を設定したい場合なども、 フィールドの属性の部分をリソース値にするだけでいいので汎用性も多言語化もバッチリですね。 (追記)全然バッチリじゃなかったので追加記事書きました。

余談

System.ComponentModel名前空間DisplayNameAttributeという表示名属性がデフォルトで用意されています。 が、プロパティやクラスにはつけることができるのですが、今回の目的のenumのフィールドにこれをつけることができません。なのでわざわざ自作のEnumDisplayName属性を作ったのですね。

他言語へのローカライズ (追記)

他言語のローカライズ、リソースに普通に書けばいけると思い本記事を書きましたが、 検証した結果できませんでした。以下のようにコンパイルエラーになります。

f:id:ikorin2:20190202021634p:plain

よく考えればその通りです。リソース値は定数リテラルではないので属性引数として渡せません。 このままではあまり嬉しくないので対策を考えます。。。

ちゃんとローカライズできるよう追加記事書きました

ikorin2.hatenablog.jp

DependencyPropertyとBindingについて

DependencyPropertyとは何か

WPFにおけるBindingの根幹をなす依存関係プロパティ(DependencyProperty)について書いておこうと思います。

まず、DependencyPropertyとは何かというと、一言で言うとBindingができるプロパティのことです。 より正確に言うと、Bindingのtargetとなることができるプロパティです。

まずはその定義から見ていきましょう。

public class SampleClass : DependencyObject
{
    public static readonly DependencyProperty MyNameProperty =
        DependencyProperty.Register("MyName",
                                    typeof(string),
                                    typeof(SampleClass),
                                  new PropertyMetadata(null));
}

説明の為にSampleClassというクラスを定義しました。DependencyObjectを継承しています。 そして、一見何やら奇怪なstaticフィールドMyNamePropertyが定義されていますが、これがDependencyPropertyです。

そして、そのDependencyPropertyに値を与えているRegisterメソッドの4つの引数についてです。

1つ目は、プロパティ名。依存関係プロパティは〇〇Propertyというフィールド名にするのが慣習であるため、〇〇の部分がこれに当たります。

2つ目はプロパティの型。

3つ目はこの依存関係プロパティを持つクラス。

4つ目はこの依存関係プロパティのメタデータであり、その引数(上記の場合null)はプロパティの初期値です。

Propertyというからには、何らかの値を保持したり取り出したり出来るわけです。

var sample = new SampleClass();
// MyNamePropertyに "ねこ" とセットする
sample.SetValue(SampleClass.MyNameProperty, "ねこ");

// MyNamePropertyから値を取り出す
var n = (string)sample.GetValue(SampleClass.MyNameProperty);

このようにして値をセットしたり取り出したり出来るのですが、これでは使いにくすぎます。 そこで、普通のプロパティと同じように使えるように、ラッパープロパティを定義してあげます。

public class SampleClass : DependencyObject
{
    // 依存関係プロパティのラッパープロパティ
    public string MyName
    {
        get { return (string)GetValue(MyNameProperty); }
        set { SetValue(MyNameProperty, value); }
    }

    public static readonly DependencyProperty MyNameProperty =
        DependencyProperty.Register("MyName",
                                    typeof(string),
                                    typeof(SampleClass),
                                  new PropertyMetadata(null));
}

MyNameという普通のプロパティを新たに定義し、先ほどの依存関係プロパティをラップしていることがわかります。

ちなみに、この依存関係プロパティとラッパープロパティの記述は、Visual Studioの場合propdpと打ち、Tabキー2回押してスニペットを使用すれば簡単に書くことができます。楽チンは人生の花。

これで、普通のプロパティと同様の使い方ができます。

var sample = new SampleClass();
// MyNamePropertyに "ねこ" とセットする
sample.MyName = "ねこ";

// MyNamePropertyから値を取り出す
var name = sample.MyName;

ここまでしてようやく見慣れた普通のプロパティですね。

さて、本題はここからです。

BindingとDependencyProperty

まず始めに、認識を正しくしておきましょう。Bindingとはプロパティとプロパティを同期させるものではありません。 プロパティと依存関係プロパティを同期させるものです。

xamlでBindingを書くと、いまいち曖昧な理解でも書けてしまうのでC#でBindingを書くとしましょう。

クラス定義側

public class SampleClass : DependencyObject
{
    public string MyName
    {
        get { return (string)GetValue(MyNameProperty); }
        set { SetValue(MyNameProperty, value); }
    }

    public static readonly DependencyProperty MyNameProperty =
        DependencyProperty.Register("MyName",
                                    typeof(string),
                                    typeof(SampleClass),
                                  new PropertyMetadata(null));

    public override string ToString()
    {
        return MyName;
    }
}

public class SourceObject
{
    public string Name { get; set; }
}

Bindingの実行

// BindingのTargetになる依存関係オブジェクト
var sample = new SampleClass();
var bind = new Binding();
// BindingのSourceとなるプロパティを持つオブジェクト
bind.Source = new SourceObject() 
{ 
    Name = "ねこちゃん" 
};
// Bindingの実行
bind.Path = new PropertyPath("Name");
BindingOperations.SetBinding(sample,
                             SampleClass.MyNameProperty,
                             bind);

上記のソースコードを見てもらえれば分かるように、BindingにはSourceとTargetがあり、Sourceになれるのはプロパティ、Targetになれるのは依存関係プロパティです。

(本筋の話とは逸れますが、SampleClassがToString()をoverrideしてMyNameを返しているのは意味があってやっています。後で説明します)

これを、xamlで書くとどうなるのでしょうか?

ただのDependencyObjectをUIElementで構成されるViewのLogicalTreeの中に書くことはできないので、今回はLabelのコンテンツとして配置することにしましょう。 (LabelのContentはobject型なのでなんでも入れられる)

ちなみに、先ほどSampleClassのToString()をoverrideしていた理由はこのためで、Labelの中身というのは実はToString()された文字列が表示される仕組みになっていて、 この場合MyNameが画面に表示されるという仕掛けです。

<Label>
    <Label.Resources>
        <local:SourceObject x:Key="SourceObj" Name="こねこ"/>
    </Label.Resources>
    <local:SampleClass MyName="{Binding Name, Source={StaticResource SourceObj}}"/>
</Label>

本筋の話とはやや逸れますが、今回のSampleClassはFrameworkElementですらないDependencyObjectなので、FrameworkElementが持つDataContextの恩恵を受けられません。 したがって、Resourcesの中にSourceObjectを持ち、StaticResourceとしてBindingのSourceに指定しています。

一見すると、MyNameプロパティとNameプロパティをBindingしているように見えますが違います。 Bindingはプロパティと依存関係プロパティの間しか繋げません。

これは、xamlが解釈される時に、自動的にその背後にある依存関係プロパティがTargetになるよう解釈されているだけです。

実際、依存関係プロパティのラッパープロパティでない普通のプロパティに対しxamlでBinding構文を書くと、Visual Studioに怒られます。

もちろん、Bindingではなく、ただ値を与えるだけならば、普通のプロパティでもxaml上で書けます。

public class Hoge
{
    // 普通のプロパティ
    public string Name { get; set; }
}
<!-- エラーは出ない -->
<Hoge Name="ねこ"/>

DependencyProperty同士のBinding

さて、今、チェックボックスが2つあり、そのチェックを同期させたいということを考えてみましょう。 つまり、片方をチェックすると、もう片方も自動でチェックがつくということです。

これはxaml上で次のようにBindingを書けば特に何かC#でコードを書くことなく実現できます。

<CheckBox x:Name="source"/>
<CheckBox IsChecked="{Binding IsChecked, ElementName=source, Mode=TwoWay}"/>

前提として、CheckBoxIsCheckedプロパティ等、主要なコントロールのプロパティはほぼ全て依存関係プロパティとして実装されています。 つまり、CheckBoxIsCheckedプロパティはCheckBox.IsCheckedPropertyという依存関係プロパティのラッパープロパティであるということです。

上記のxamlは一見、依存関係プロパティ同士のBindingに見えますが、何度も言うようにBindingはプロパティと依存関係プロパティを繋ぎます。

すなわち、BindingのTargetはCheckBox.IsCheckedProperty依存関係プロパティですが、SourceはラッパープロパティであるIsCheckedプロパティなわけです。

勿論、IsCheckedプロパティの実態はCheckBox.IsCheckedProperty依存関係プロパティなので、当然事実上2つのチェックボックスの依存関係プロパティが連動するわけですね。

さいごに

Bindingには方向(Mode)と更新タイミング(UpdateSourceTrigger)とかがあって、もう少し奥が深いのですがその辺はまた別の記事で書こうかなと思います。

書いたらこの辺にリンクを貼っておこうと思います。。。

MVVMで始めるWPF生活

はじめに

皆さんはラーメンは何で食べますか?

いえ、そうではなく、WPFとはいったい何でしょうか?

正式にはWindows Presentation Foundationといい、Windows Formに代わる新しいWindowsにおけるGUIアプリケーションのプラットフォームであり、登場は2006年。描画は内部でDirectXにより行われ、WinAPIのラッパーであるWindows Formとは根本から異なるシステムで……

などとそんなことが知りたいのならwikipediaでも読んでください。

もはや10年以上前に登場した技術であるにもかかわらず、本記事執筆時点(2018年)において、c#GUIアプリとなった時に未だWindows Formに捕らわれているのをよく見かけます。


もちろん、既存の資産の運用、新しい技術の導入にかかるリスク、コストはあるのでしょう(私はプログラマとして食べているわけではないので詳しくは知らない)。
ですがWPFはいいぞと布教したいためにこの記事を書きます。(このweb時代にデスクトップアプリケーション自体オワコンでしょとか言わない)


WPFについて何となく知っているものの、抵抗を感じている人、未だWindows Formに捕らわれている人に読んでもらえたらと思います。

(そんな人がこの記事読むのかはさておき、一応WPF及びC#を全く知らない人の為に説明すると、WPFとは簡単に言うとWindowsで動くGUIソフトを作るための開発環境および基盤技術です。)

WPFとMVVM

WPFはMVVMデザインパターンで実装することが強く望まれます。これこそが、Windows Formとの大きな違いであり、Form捕らわれマンにとっての最初の壁です。
勿論、MVVMに則らずにformのように実装することも可能ですが、それはラーメンをフォークで食べるようなものです。邪道です。

MVVMデザインパターン

MVVMパターンとは何なのでしょうか?概略を理解していただくために、具体的なソースコードを出さずに概念的に説明したいと思います。


f:id:ikorin2:20181109005135p:plain


全体の構成は、View・ViewModel・Modelと呼ばれる要素から成ります。

ViewはTextBoxやButtonなどのUIに関する要素です。
Modelは各種データや計算処理などのロジック等を担当するオブジェクトです。
そして、ViewModelはViewModel自身あるいはModelが持つデータとViewをBindingによって繋ぐオブジェクトです。

このBindingという関係は、あるプロパティと別のプロパティの値を同期させるものだと思ってください。(片方が変更されると、もう片方もその値に変更される)


この時重要なことは、ViewとViewModelは図のように、Command及びBindingによってのみ繋がる関係であるということです。言い換えれば、両者は密結合であってはならないということです。

構図としては、ViewModelはViewに使われる側の立場なのですが、大原則として、ViewModelはViewが誰なのかを知ってはいけないのです。
(つまり、ViewModelがWindowやTextBoxなどのUI要素のインスタンスを保持して直接操作するなどは言語道断、フォークでラーメンを食べています。)


簡単な例を挙げましょう。

Windowに数値を入力するTextBoxを2つ置き、ボタンが押されたらその和を計算して表示するだけの足し算計算機を考えます。
この計算機をMVVMに則して実装した場合の動きを順に追っていきましょう。

f:id:ikorin2:20181109013249p:plain

  1. まず入力された2つの値はBindingによって、ViewModel (以下VM) に渡ります。
  2. 次に、計算ボタンが押されるとCommandによってViewからVMに「計算を実行しろ」という命令が出ます。
  3. 最後に、計算結果をVMのAnswerプロパティに格納すると、BindingされているViewの表示が自動で変更される。

というプロセスによって処理が実行されます。


おそらくここで、聡明な皆さんの120%の方が、「いやModelないじゃん」と思うことでしょう。その通りです。
この計算機の機能が薄っぺらすぎるためModelを作るまでもないのですが、Modelを使って正式な(?)MVVMにすると以下のようになります。


f:id:ikorin2:20181109015240p:plain


先ほどと変わった場所は、ModelとしてCalculatorというオブジェクトが追加され、VMはCalculator.AddValueというメソッドを呼ぶことで計算結果を得ています。

つまり、VMはModelを使って計算処理や何らかのロジックを呼ぶだけで、VM自身は具体的な処理はModelに任せているということです。

VMとModelの関係は、ViewとVMの関係ほど疎結合とはいかないものの、ModelはあくまでVMに使われる側の立場であることに変わりはなく、ModelはVMを知ってはいけません

さいごに

簡単な例を用いてMVVMの概念を解説しましたが理解していただけましたでしょうか?

MVVMデザインパターン自体はWPF固有のものというわけではなく、他言語による開発などでも普通に用いられる有名なデザインパターンです。(Vue.js等)

ですが、Bindingという特殊な構造が標準で実装できるようなプラットフォームやライブラリ等がなければ実現しにくいパターンであるため、MVC等に比べてやや特殊なのかもしれないと個人的には思います。


最後になりますが、私はラーメンは口で食べます。人間なので。

ターミナルで擬似動画再生

お久しぶりです.更新頻度が半端なく低く,もはや誰のためのブログなのかわからないですね.でも更新します.

楽しいので

 
さて本日のテーマはターミナルで動画を再生したい的な何かです.

ハッキリ言ってn番煎じです.世の中にはそういうものがすでに存在します.


(A゚∇゚) <新規性はあるんですか?
(^・ω・)~ <既存のツールとの差異はあるんでしょうか??
 

結論:コマンド1つでごちうさオープニング「Daydream cafe」が再生できます!

 

はい,一文の得にもなりませんね.最高


閑話休題

今回作ったものです.

f:id:ikorin2:20180611183856g:plain
github.com

使い方はREADME.mdに書いてある通りなんですけれどターミナルで

ddcafe

 
と打つだけです.あぁ^~心がぴょんぴょんするんじゃぁ^~

今回はpythonで書いたのでPyPIでパッケージ化してpipで簡単にインストールできるようにしてみました.

pip install ddcafe

python3の標準ライブラリしか使っていないはずなので,外部ライブラリに依存はしてないはずです.windowsでも多分動くはず……


技術的な内容は解説しません,面倒なので(エ
githubソースコード読んだらわかるはず(はず).そのうち書くかもしれません


あと,一応同じフォーマットのjsonで動画(というかテキストデータ)を用意して引数で渡せばごちうさ以外も再生できます.json生成する方のプログラムは公開していませんが.


今回これを作った理由は,twitterのフォロワーさんが作っていた

al

とターミナルで打つと,きんいろモザイクのアリスが歌うパロディのジョークプログラムを見て触発されたからです.せっかくなので.
github.com





P.S.
PyPIのこと「ぱいぱい」って読んでるのぼくだけじゃないはず

VOICEROID +EX をwindows10にうまくインストールできない

先日VOICEROID +EXを購入したんですが、どうにもインストールが上手くいかなくてつまったのでメモ書き程度に。どこかで同じような症状になっている人の目に留まれば幸いです。

 

 購入したのはダウンロード版ではなくパッケージ版なので、とりあえずディスクを光学ドライブに入れてランチャーソフトを起動します。f:id:ikorin2:20180415030456p:plain

後は一番上の大きいインストールボタンを押して、指示に従ってインストールすれば終わり……終わり……

 

終わらん

 

「ライセンス認証ドライバをインストールしています」と出てきたウィンドウのプログレスバーが0%から永遠に動かない。仕方がないのでインストーラーをキャンセルして終了しようとしてもこれまた永遠に終了しない。

 

仕方がないのでタスクマネージャーからプロセスをキルして無理やり閉じました。どうなってるんだ……

[2020/10/11 追記]

色々な方から、インストール時にブルースクリーンになってしまうとの情報も頂いていますが、本記事の手順で回避できるようです。お試しください。

 

軽くググったら、どうやらwindows10で使うにはアップデートしないといけないみたい。

writer.hateblo.jp

 

このサイトに書いてあるのは、今までVOICEROID +EXを使えてたのにwindows10にしたら使えなくなった、みたいな状況ですが、初めからwin10にインストールしようとしたときにも同じことが起こるのでは?と思ったので試してみたらうまくいきました。

 

[2020/07/26 追記]

あーもう!!なんか頻繁にリンク先変わるのなんで??ホームページの改修でもしたの?なんかいろいろ変わってたので以降の記事を書き直しました。(一応書き換え前の状態も記事の最後に残しておきます)

 

https://supportportal.thalesgroup.com/csm?id=kb_search&query=Sentinel%20HASP%2FLDK%20Windows%20GUI%20Run-time%20Installer&spa=1

 

上記のリンクから Sentinel HASP/LDK Windows GUI Run-time Installer をダウンロードします。もしかしたらバージョンとかが新しくなっているかもしれませんが、一番新しそうなのをダウンロードしてください。

 

f:id:ikorin2:20200726030932p:plain

 

一応、今このページを見た状態ではこんな感じなので、一番上のインストーラーをダウンロードしてください。今後また見た目が変わってるかもしれません。(3回ぐらいページ変わってたので本当に信用できなくなってきた)

 

おそらく、ダウンロードをクリックすると嫌になるぐらい長い英語のライセンス条文が出てくると思いますが、一番下までスクロールして「I accept」をクリックしてください。ダウンロード出来たら中身の zip を解凍して HASPUserSetup.exe を実行してください。

 

後はもう一回VOICEROID +EXのランチャーソフトからインストールを実行すればちゃんと「ライセンス認証ドライバをインストールしています」を通り抜けられます。

 

インストールするのに事前にドライバ(?)のアップデートが必要とか初見殺しもいい所だし、公式ももっとわかりやすくどこかに書いててほしいという感じ。きりたんがかわいいので許す。

 

 

以下、変更前の記事。一応残しておく

 

https://safenet.gemalto.com/sentineldownloads/?s=&c=End+User&p=Sentinel+LDK&o=Windows&t=Runtime+%26+Device+Driver&l=all

[2020/06/13 追記]

上記リンク先がいつの間にか変わってて別のページに変わってました。代わりに下のリンクを使ってください。

https://www.sentinelcloud.com/sentineldownloads/

 

書いてある通り、このリンクからSafeNet社のリンクにアクセスして

Sentinel HASP LDK - Windows GUI Run-time Installer

をクリック。いろいろと英語で書いてあるページの一番下まで行って

I accept』 

をクリックしてインストーラーをダウンロード。

zipを解凍してHASPUserSetup.exeを実行すればOK。

 

後はもう一回VOICEROID +EXのランチャーソフトからインストールを実行すればちゃんと「ライセンス認証ドライバをインストールしています」を通り抜けられます。

 

インストールするのに事前にドライバ(?)のアップデートが必要とか初見殺しもいい所だし、公式ももっとわかりやすくどこかに書いててほしいという感じ。きりたんがかわいいので許す。

 

ブログ始めました

初めまして、いこりと申します。

以前からブログというものを書いてみたいなと思っていたのですが、どうにも最初の一歩を踏み出せないままズルズルと時間が経っていました。

関西のとある大学で大学生をやっています。趣味は工作やプログラミング、その他いろいろです(説明略)

 

今回は初投稿なので、これといった話題もないので、ただの自己紹介と言ったところでしょうか……………

 

全然自己紹介になってない

 

まあいろんな人のブログ見ても初投稿ってだいたいこんなものでしょうという自己暗示をかけつつ、今後も緩い感じでブログ書いていきたいです。

 

twitterもやっておりますので何かの気の迷いでそちらも見たい方がおられましたら、ブログ見ました、とでも声でもかけて頂ければ私も喜びます。

Twitter: @ikorin24

 

それでは今後も記事を書くことを願ってこの辺で筆を置かせていただきます。