C# 文字化け問題解決

C#でGitのDiffコマンドを起動して受け取った結果を処理しとうと思い、ずっと後回しにしてた文字化け問題がやっと解決しました。

C#ではProcessクラスで外部コマンドを実行し、標準出力から結果を受け取ります。ここで受け取るときに文字化けを起こしていました。文字列を受け取った後に、文字列をエンコードしても、微妙に文字化けがのこってしまいうまくいきませんでした。

原因

Processクラスで結果を受け取るには、StandartOutputプロパティを参照しますが、StandartOutputはReadStreamオブジェクトであり、Net Fremeworkでは既定のエンコードであるShift-JISとなります。一方Git Diffの出力はUTF-8なので、Shift-JISでUTF-8を読みに行くので文字化けとなってしまいました。

解決法

ProcessオブジェクトにはStartInfoクラスがあります。ここにエンコードを指定するプロパティがあり、UTF-8に設定します。

 Process.StartInfo.StandardOutputEncoding = Encoding.UTF8;

コードサンプル

Process process = new Process(); 
// コマンド名 
process.StartInfo.FileName = command; 
// 引数 
process.StartInfo.Arguments = argument; 
// StandardOutputで結果を受け取るために必要な設定 
process.StartInfo.UseShellExecute = false; 
process.StartInfo.RedirectStandardOutput = true; 
// StandardOutputのエンコード設定 
process.StartInfo.StandardOutputEncoding = Encoding.UTF8; 
// 実行 
process.Start(); 
//プログラムが実行完了するまで待つ 
process.WaitForExit(); 
//結果格納 
var str = process.StandardOutput.ReadToEnd(); 
//プロセス終了 
process.Close();

参照

ProcessStartInfo.StandardOutputEncoding プロパティ

エクスプローラーから直接カレントフォルダ指定でVSCodeを開く

Windowsでちょっとしたプログラミングをするときに、Visual Studio Codeを使うのですが、エクスプローラーで開いているフォルダを指定して Visual Studio Code を開く方法です。

やり方1 コマンドプロンプトを開く

やり方は次の通り

  1. エクスプローラーでフォルダを開く
  2. アドレスバーに[ cmd ]と入力する
  3. コマンドプロンプトに[ code . ]と入力する

ちなみに .(ドット)は現在のフォルダの意味です。

開き方1

やり方2 直接表示

次はエクスプローラから直接VSCodeを開くコードです。[ cmd ] の後ろに[ /k ]か[ /c ]のオプションをつけるとコマンドを指定することができます。

オプションの [ /k ]はVSCodeを閉じたあともコマンドプロンプトが開いたままに、[ /c ]は VSCode閉じるときにコマンドプロンプトもいっしょに閉じます。

開き方2

Ryzen自作PC Windows11インストールで苦労した話

だいぶ久しぶりに自作パソコンを制作しました。意外と苦労した点を書きます。

主な部品は次の通り

  • CPU ・・・AMD Ryzen 7 5800X
  • マザーボード ・・・ASRock アスロック B550 Steel Legend
  • GPU・・・ASUS TUF-GTX1660S-6G-GAMING
  • ファン・・・虎徹 MarkII Rev.B SCKTT-2100
  • メモリ・・・32GB
  • SSD・・・500GB
  • ハードディスク・・・8TB

ちなみに今回選んだCPUはGPUもファンもついてないので、別途購入する必要があります。

メモリサイズを間違えた

メモリの種類がDDR4ということはわかってましたが、大きさまで気にしておらず間違えてノートPC用を買ってしまいました。組み立てる段階で間違えに気づき、慌ててAmazonで注文しました。

間違えたやつは260pin

260pin

正解は288pin

288pin

画面に全く映らない

組み立てが終わり、電源を立ち上げたら、画面が真っ黒のままで何も映りませんでした。マザーボードのコードには0dと表示。ホームページで調べてもあまりはっきりしたことが書いてなくてわかりませんでした。いろいろ試した結果。メモリがちゃんとささってないことが原因でした。

Windows11がインストールできない

Windows11をインストール開始すると、シリアル番号を入力した後にハードウェアが対応していないという警告がでてインストールできませんでした。UEFIのセキュアブートを有効にすることで解決しました。

そのままではセキュアブートを変更することができませんでした。起動タブでCSMを無効にし再起動してようやくセキュアブートを有効にすることができました。

  1. CSMをOFFする
  2. 再起動
  3. セキュアブートを有効
CSM無効
セキュアブート有効

WordPressブログのインポートで苦労した話

経緯

今日ブログのレイアウトを大幅に変更した。変更するに当たりいきなりネット上で変更するのは怖かったので一旦ローカル環境にうつしてからアップロードする作戦にしたら、Wordpressのインポートでいきなり苦労したので内容を報告します。

以前ローカルに”local”で環境を作り、All-in-One WP Migrationを使用して、バックアップしPHPのバージョンアップしたことがあった。その時はインポート容量に制限があることがわからなかったが、今回改めてやってみると300MBの制限があった。

容量の上げ方はこのサイトに書いてあった。

how-to-increase-maximum-upload-file-size-in-wordpress/

方法は以下の2つ

① Edit .htaccess file

php_value upload_max_filesize 128M
php_value post_max_size 128M
php_value memory_limit 256M
php_value max_execution_time 300
php_value max_input_time 300

② Edit wp-config.php file

@ini_set( 'upload_max_filesize' , '128M' );
@ini_set( 'post_max_size', '128M');
@ini_set( 'memory_limit', '256M' );
@ini_set( 'max_execution_time', '300' );
@ini_set( 'max_input_time', '300' );

local だとどちらの方法もダメだった。①の場合、エラーでサイトが開かなくなる。②の場合、変化なし。
直接php.iniを書き換えてもダメ。

結局localでやるのは諦めた。localはWordpressの環境を作るのが簡単なので気に入ってたのに。

対応策

MAMPでWordpressの環境を作った。MAMPの場合、アップロードの初期値は8MB。①の方法で変更できた。

.htaccess

# BEGIN WordPress
# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /wp/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wp/index.php [L]
</IfModule>

# END WordPress

# ここから下を追加
php_value upload_max_filesize 1000M
php_value post_max_size 1000M
php_value memory_limit 1000M
php_value max_execution_time 300
php_value max_input_time 300

②の方法は変化なかった。

参考

WordPressのバックアップの仕方とローカルサイトでの試し方などは、このサイトが非常に良かったので紹介しておく。


WordPressのPHPを安全にバージョンアップする方法
WordPressのバックアップをかんたん確実に取る方法【初心者向け】
WordPressをローカル環境(パソコン)にインストールする方法

サーボドライバ外部速度設定器で苦労した

今の仕事で、サーボドライバに外部速度設定器(ボリューム)を2つ取り付けて制御しましたが、意外と苦労したので報告します。

速度設定方法

ボリュームによる速度司令は、電圧を-10V〜+10Vの範囲で設定し速度を統制します。この装置は正転時にボリューム1を使用し、逆転時にボリューム2を使用するように切替えて制御しています。

電圧が0Vより大きいときは正転し、0Vより小さいときは逆転します。厳密に言うとLG端子(グランド)より、VC端子(電圧入力)の電圧が大きいか小さいかで回転方向が変わります。

下記の図のようにLG端子よりVC端子が大きければ正転方向に回転します。

VC > LG → 正転

また、下記図のようにLG端子よりVC端子が小さければ正転方向に回転します。

VC < LG → 正転

さて今回使用するドライバは、サーボドライバ内にボリューム駆動用の電源が搭載しているタイプでした。そこで同じような考えで回路を組んだら、逆転方向が動作しませんでした。

動作しない理由

内部電源で逆転方向に動作しない。

この回路ではVCとLGが同電位になってしまいます。LGを+12Vに接続するわけにもいきません。(ショートしてしまうので)

解決策

ボリュームにドライバ内部電源の0〜12Vをかけて、ボリュームと指令信号1/2をを切り替えるようにしました。

解決策

心機一転

更新がかなり久しぶりになりました。約二年ぶりです。この間に単身赴任になったり、長期で出張に行ったりといろいろありました。単身赴任はまだ継続中ですが。

タイトルをTry Everythingに変更しました。自分が興味あることや仕事に関係することについて出来ることをどんどんやっていこうという想いです。

単身赴任中ということもあり、DIYや電子工作など部材が必要なことはあまりやらなくなりました。最近の興味はもっぱら資格取得です。

私は電気に関する仕事をしているので、とりあえず電気工事士二種をとりました。電験三種も受けましたが、基準点が下がれば受かるかもしれません。

この先は英語や中国語の勉強をしていくつもりです。

pythonでMP3タイトルを一括変更する

森沢洋介著「瞬間英作文」。素晴らしいですね。英語で会話するときに言いたいことがあるけれど、文章にできずに簡単にしか言えませんでしたが。この本をきっかけに打開できてきたような気がします。付録CDをiPhoneに入れて、ミュージックアプリで通勤途中に聞いています。日本語を聞いて、英語の文章を作って、英語の音声と比べてみる。というのを繰り返して、長い文書も段々と自然と作れるようになってきました。この学習も次の段階で、話すための瞬間英作文シャッフルトレーニングを買ってやろうとしています。

前置きは長くなりましたが、今回は瞬間英作文シャッフルトレーニングのCDをMP3にしてiPhoneへ転送したところで、意外な苦労をしたので書きます。

問題1 アルバムのタイトルがまとまらない

何故かアルバム名がたくさんできてしまいました。アルバム名を揃えたり短くしたりいろいろやってみましたがうまくいきませんでした。結果的に、いったんmp3ファイルを1つだけ転送してから、残りのファイルを転送するとうまくいきました。下記のブログにずばり答えが書いてあったので助かりました。
iPadのMusicアプリ上でアルバムがまとまらない

またMacでMP3のアルバム名やタイトルなどをGUIで設定したい場合はID3 Editorが利用できます。アルバム名やジャンルなど共通の項目は複数のファイルをまとめて編集することができます。

問題2 曲名が長すぎてはみ出してしまう

これは曲名をすべて半角に変更して対応しました。ID3 Editorで曲名は一つずつ編集するしか無いのでコマンドラインですることを考えました。ID3 Editorでもコマンドラインのツールが有るようですが、やり方があまり詳しく乗っていないので、今回はpythonでライブラリを読み込んでやることにしました。まず作成したコードは

mutagenというライブラリを使用しています。ライブラリのインストールは

pip install mutagen

全角半角の変換はjaconvライブラリを使用しています。これもライブラリのインストールが必要です。

pip install jaconv

.replace(‘Part’,”)でPartという文字を消していますが、これは、CD2のタイトルがPart1と2に分かれていて、これがあるとiPhoneのミュージックアプリで見たときはみ出してしまうので削除しました。編集した結果下記のように見やすくなりました。

ASIO C++ UDPクライアントをモジュール化

前回まで三菱MCプロトコルのライブラリをつくるため通信テストをしてきましたが、プロクラムの中にASIOの記述をずらずらと書いていたのでクラスにまとめてモジュール化しようと考えています。

クラスにするだけでも、結構苦労しました。特にsocketをローカル変数宣言して、コンストラクタで設定するところです。構造体のデータを転送してみましたが、エラーが発生してうまく行かなかったので、まずはnetcatで立ち上げたローカルサーバへの送信プログラムを作ってみました。プログラムはgistへアップしましたので参照してください。
UDPClient

早速説明していきます。UDPClientクラスの変数はendpointとsocketを宣言します。コンストラクタではio_contextとIPアドレスとポート番号を受けて、socketとendpointを初期化しています。

class UDPClient
{
private:
	asio::ip::udp::endpoint endpoint;
	asio::ip::udp::socket socket;

public:
	UDPClient(
		asio::io_context& io_contex, 
		const std::string host, 
		const short port)
		: socket(io_contex)
	{
		asio::ip::udp::endpoint endpoint_(asio::ip::address::from_string(host), port);
		endpoint = endpoint_;
	}

UDP送信は構造体で送信することを考えて、テンプレートで作成しました。(まだ実際に構造体での転送は試していません。)

template <typename T>
void Send(T msg,int size)
{
	socket.send_to(asio::buffer(&msg, size, endpoint);
}

mainの中は次のとおりです。io_contexとIPアドレスとポート番号を指定してクラスを宣言し、キーボードで入力した文字をUDPサーバへ送信するだけのプログラムです。

asio::io_context io_context;
const std::string host = "127.0.0.1"; 
const short port = (short)60000;

UDPClient udp(io_context,host,port);
udp.Open();    
for(;;)
{
    std::string inmsg;
    getline(std::cin, inmsg);        
    if(inmsg=="q") break;
    inmsg+="\r\n\r\n";
    udp.Send(inmsg,inmsg.size());
}
udp.Close();

私のMacbook環境ではnetcatが使えるのでnetcatが使えるので、netcatをUDPサーバ、ポート番号60000で立ち上げて、文字が表示することを確認しました。

$ netcat -l -u -p 60000

メインのプログラムでinmsg+=”\r\n\r\n”;としているのは、netcatでうまく開業されなかったからです。他に1文字か2文字だと一段多く改行したり、十何文字か多く打つと文字が変になったりするのですが、とりあえずモジュール化して通信できるました。

次は受信についてやり、構造体のデータを送ります。

三菱PLC通信 構造体でトライ -コマンド受信

前回に続き、今回は構造体でコマンドを設定しての受信について説明します。
まずは受信の構造体からです。

//受信コマンドヘッダ
struct QNa3E_Frame_Receive{
    std::uint16_t subheader;
    std::uint8_t network_number;
    std::uint8_t pc_number;
    std::uint16_t request_IO_number;
    std::uint8_t request_station_number;
    std::uint16_t response_data_length;
    std::uint16_t terminal_code;
}rsv;

これも、リファレンスマニュアルのQnA互換3Eフレームのバイナリコードで更新する場合を見ながら作成しました。UDP受信については前々回の三菱PLCとイーサネット通信をご参照ください。

// UDP受信
std::array<unsigned char, 128> recv_buf;
asio::ip::udp::endpoint sender_endpoint;
size_t recv_buf_len = socket.receive_from(
    asio::buffer(recv_buf), sender_endpoint);

今回はこの受信バッファを構造体に入れます。

// 受信データを受信ヘッダへコピー
int rsv_size = sizeof(QNa3E_Frame_Receive);
memcpy(&rsv, &recv_buf,rsv_size);

構造体のサイズ分memcpyでコピーしています。

// 受信したデータを書き出し
for(size_t i=rsv_size; i<recv_buf_len; i+=2)
    std::cout  << (recv_buf[i + 1] << 8) + recv_buf[i] << std::endl;

受信したデータを標準出力で出力します。受信バッファrecv_bufには1バイトずつデータが入っているので、1ワードずつ出力するには、forループで2つずつ進めて上位バイトを8bitシフトさせて下位バイトを足して、ワードデータにして表示しました。出力は下記のようになります。

1
10
100

構造体で作成することができました。次回からはMX Componentの関数にあるような感じでクラスを作っていきます。