メインコンテンツまでスキップ

Pythonでファイルを収集してZip化する

友澤
ディアシステム(株)開発一部第3課

こんにちは、開発 1 部第 3 課の友澤です。

今年になって、初めて Python で開発する業務に就いたので、
簡単なスクリプトツールを作成してみました。
作成したのは、「Ubuntu 環境からファイルを収集して Zip 化する」になります。

仕様:
  • Python で作成する、スクリプトツール
    FileExplorer/FileExplorer.py
  • スクリプトの実行方法
    $ python3 FileExplorer.py
  • /var/log/から syslog を収集する(ローテートされたファイルも対象とする)
    上記、ファイルパスとキーワードはコード上で定義します。
  • スクリプト実行時に、ファイル格納用ディレクトリを作成し、
    収集したファイルを格納する
  • ファイル収集後、ファイル格納用ディレクトリを Zip 圧縮でまとめる
  • Zip ファイルのフォーマット
    FileExplorer_yyyymmdd_hhmmss.zip
  • Zip 圧縮後、ファイル格納用ディレクトリを削除する
開発メモ:
  • Zip ファイルのフォーマットに使用する現在日時は、
    datetime.now()で取得し、strftime()でフォーマットを指定します。
  • ファイル格納用ディレクトリはカレントディレクトリ(./FileExplorer/)に
    「FileExploerOutput」を作成します。
    カレントディレクトリのパスは、os.getcwd()で取得し、
    os.makedirs()でディレクトリを作成します。
    ※既に存在しているディレクトリを指定してもエラー(FileExistsError)にならない様、
    引数に exist_ok=True を記載しています。
  • ファイルが格納されているディレクトリ(/var/log/)から、
    ファイル名に"syslog"が含まれるファイルを部分一致検索でマッチングさせます。
  • マッチングしたファイルは、shutil.copy()でファイル格納用ディレクトリにファイルコピーします。
  • Zip 圧縮は、zipfile.ZipFile()で行い、zipfile.ZIP_DEFLATED(通常の ZIP 圧縮)とします。
  • Zip 圧縮後、shutil.rmtree()でファイル格納用ディレクトリを削除します。
コード:

画像1

スクリプトの実行:

※WSL の Ubuntu 環境にて実行したイメージになります。

画像2

  • スクリプト実行後、Zip ファイルが格納されています。

画像3

  • Zip ファイル内に、収集したファイルが格納されています。

画像4

まとめ:

・今回はあえてシンプルに「ファイル収集して Zip 化する」スクリプトを紹介しました。
使用している API もネット上で詳しく解説しているところが沢山見つかると思います。
なにかの参考になれましたら幸いです。

動画生成AI Sora2でディアシステムのCMを作成してみた

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部 箕浦です。
今回も生成 AI シリーズです。
今回は Open AI が最近リリースした動画生成 AI Sora2 を触ってみます。

まずは簡単に「Sora2」の紹介をします。
「Sora2」は、OpenAI が 2025 年 9 月に発表した最新の動画生成 AI モデルで、テキストや画像から高品質な動画を生成できる革新的なツールです。

Sora2 の主な特徴

1. テキストからリアルな動画生成

「公園でボールを投げる少年」といったテキストプロンプトを入力することで、リアルな映像を自動生成できます。
映像スタイルは映画風、アニメ風、写実的、超現実的など多彩に対応しています。

2. 音声・効果音の同期生成

映像に合わせてセリフや効果音、環境音を同期して生成できるため、映画のような没入感のある動画が作成可能です。

3. 物理法則の再現

物体の動きや重力、光の反射など、現実世界の物理法則を再現したリアルな映像表現が可能です。
これにより、より自然で説得力のある動画が生成されます。

4. 「カメオ」機能で自分や友人を登場させる

「カメオ」機能を使用することで、ユーザー自身や友人を動画のキャラクターとして登場させることができます。
これにより、パーソナライズされたコンテンツの制作が容易になります。

さっそく試してみる

Sora2 を利用するには、現在招待コードがないと利用できません。
招待コードはネットで出回っているので、まずはそれを入手してください。

招待コードが入手できたら以下の URL に行き、右上の「Login」から「Sora」を選択します
https://openai.com/index/sora-2/

以下のような画面になるので、Sora2 で作成した動画のサンプルが見れます。 画像7

右上の「Login」からログインします。Google アカウントから入れます。

画像8

ログインすると旧 Sora の生成画面に行くので、右下の「Join New Sora」を選択する。

画像9

この画面になるので、「Enter Invite Code」を選択する。

画像2

招待コードを入力する。

画像3

ログインできたら、以下のようにプロンプト入力欄が出てきます。

画像4

ここにプロンプトを入力します。
日本語でも OK です。
+ボタンで画像を 1 枚だけ添付できます。
カメオと呼ばれるキャラクターを動画に登場させたいときは、この中から選びます。
スマホアプリ版では、自分をカメラで撮影し、カメオとして登録して使うこともできるみたいです。

画像10

設定は、現時点では縦長か横長を選択するのみです。

画像11

試しに以下のプロンプトを入れてみます

画像12

入力すると以下のボタンから動画が見れます。
生成されるまで 2 ~ 3 分ほどかかります。

画像13

生成された動画がこちら
ちなみに無料版ではウォーターマークが入ります。

現在、無料版では 10 秒ほどの動画しか作成できないようです。

もう一つ、次は以下のプロンプトを試します。

画像14

生成された動画がこちら

それに近い動画が簡単に作れるのはすごいですね。

ディアシステムの CM を作ってみる

ディアシステムの CM 作成にトライしてみましょう。
まずは、どんな CM にするか ChatGPT に案を出してもらいます。
ディアのホームページにある画像を使ってみたいので以下の画像を添付して、

画像5

この画像を使って 動画生成AI Sora2でディアシステム株式会社のCMを作りたい。
8秒に収まるようにプロンプトを考えてください
https://www.dsic.jp/

と聞いてみます。
以下のように回答もらえました。

画像6

これをベースに以下のように変更して Sora2 のプロンプトに入れてみます。

(マルチカット、動きのあるように)
未来都市の朝焼けの中、背中にリュックを背負った少年が輝く都市を見つめている。
空には光が広がり、ガラスのようなひびが世界の変革を象徴している。
少年が空に向かって手を伸ばす。
ナレーション(優しく力強い声):「思い、Webテクノロジー 情報システムを変革し、未来の景色を変える。ディアシステム株式会社」
シーンがフェードアウトし、**「ディアシステム株式会社」**の文字が表示される。

映像全体は約8秒、静かなピアノと希望に満ちたサウンドトラックで締めくくる。
映像の雰囲気:温かく透明感のある光、未来と希望を感じさせるトーン。

完成した動画がこちらです。

別で実写版を作成してみました

いかがでしょうか

まとめ

Sora2 は短時間で高品質な映像と音声を同時に生成でき、物理表現やキャラクター活用(カメオ)など実用性の高い機能を備えています。
今回は基本的な操作を確認しつつ、企業イメージを 8 秒に凝縮する形で CM 試作まで行えました。
無料版では制約(尺・透かし・解像度など)はあるものの、コンセプト検証やイメージ共有には十分活用可能です。
試行回数を重ね、どの程度プロンプトで演出意図を再現できるか検証していきたいと思います。

ASP.NETについて

坂口
ディアシステム(株)開発二部第2課

開発二部 坂口です。
ASP.NET を知ったきっかけは上司の方がサーバーについての説明をしていただいたときです。その際に最近では ASP.NET をよく使われているとおっしゃっていたので今回調べてみることにしました。

ASP.NET とは、マイクロソフトが開発した Web アプリケーション開発フレームワークの ことです。言語は主に C#、VB.NET などが使用されています。
ASP.NET を使用すると、「会員登録・ログイン機能のある Web サイト」「DB と連携した業務システム」「EC サイト」など動的な Web アプリケーションを作成することが出来ます。
ASP.NET を使ったアプリ開発で必要なツールは、Vusial Studio です。

実際に少し触ってみようと思います。
プロジェクト構成は以下のようになっております。

画像1

Web アプリでは、DB も必要となってきます。
ASP.NET MVC では、スキャホールディングというプロジェクトに必要なコードやビューの骨組みを自動生成する機能が搭載されているため、すぐに CRUD を実装することが出来ます。
手順も最も簡単です。
Models フォルダ作成し「追加」>「新しい項目」でクラスを作成します。
以下のように、作成したい DB 項目を記述していきます。

画像2

次に「Contollre」フォルダを作成し右クリックで「追加」>「新規スキャフォールディングアイテム」を選択する。

画像3

画像4

モデルクラスには、モデルフォルダ配下のクラスの名前を選択し、DbContext クラスには、【プロジェクト名】.Models.【プロジェクト名】Context を記入します。
追加ボタンを押すと、Create・Delete などのクラスと HTML が自動で作成できました。

今回、以前から気になっていたものを調査できて良かったです。実際に業務では触る機会がなかったので、もし機会があれば触ってみたいと思いました。

コンソールアプリからステップアップ!テンプレートから学ぶ .NET Worker Service

鶴田
ディアシステム(株)開発一部第2課

こんにちは。ディアシステム開発1部開発2課の鶴田です。

はじめに

みなさんは、昔から動いているコンソールアプリを「そろそろサービス化したいな」と思ったことはありませんか? 私自身そんな場面に出会い、調べてみると 「Worker Service」 という仕組みが .NET では一般的だと知りました。

せっかくなので勉強してみたところ、「これならコンソールアプリの延長線上で、ちゃんとした常駐サービスが作れるじゃないか!」と感じました。

この記事では、その時の学びをまとめつつ、最小限のサンプルコード(HelloWorld!)をもとに紹介していきます。 読んでいただいた方にとってコンソールアプリからのステップアップのきっかけになればうれしいです。

コンソールアプリと Worker Service の違い

実務で「ずっと動かしておきたい処理」をコンソールアプリで作ると、ちょっと不便が出てきます。

  • 自分で「終了条件」や「再起動」の仕組みを用意しないといけない
  • Windows ならサービスとして登録するのが面倒
  • Linux なら systemd などと組み合わせる必要がある

そこで登場するのが Worker Service です。 Worker Service は、コンソールアプリと似た書き心地なのに「常駐サービスとして動かす」ことに特化しています。しかもライフサイクル管理(開始・停止)、ログ出力、DI(依存性注入)まで標準で備わっているので、実務で安心して使えます。

コンソールアプリと Worker Service を比較し表にしました。

項目コンソールアプリWorker Service
終了管理自前で実装が必要OSからの停止通知を受け取れる
適した用途ツール、簡単なバッチ処理ファイル監視や定期処理などの常駐処理

お手軽なコンソールアプリと、実務面で強化された Worker Service といった感じですね。

Worker Service の最小サンプル

「Worker Serviceってどうやって書くの?」と気になりますよね。今回は標準的なテンプレートを作成、内容を細かく確認し、 HelloWorld してみましょう(笑)

まずはテンプレートを作成します。作成するには、.NET SDK が必要ですのであらかじめインストールしておいてください。

コマンドプロンプトで

dotnet new worker -n sampleworker

と入力します。なんやかんやと出てきていろいろ作ってくれます。 このdotnetコマンドは .NET SDK に含まれる機能で、テンプレートを作成してくれるコマンドです。今回は worker サービスと呼ばれる「常駐サービスの基本形」をつくってもらいました。

作成されたフォルダを VSCode で開いて細部を確認してみましょう!2つのcsファイルが作成されているはずです。

Program.cs

using sampleworker;

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();

var host = builder.Build();
host.Run();

Worker.cs

public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;

public Worker(ILogger<Worker> logger)
{
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
}
await Task.Delay(1000, stoppingToken);
}
}
}

では1つずつ解説です。

Program.csの解説

Program.cs、最初の1行目より!

var builder = Host.CreateApplicationBuilder(args);

これ、.NET 6 以降の定番の書き方らしいです。えらく短いです。

Host.CreateApplicationBuilder ですが、.NET 6 以降で導入されたそうです。 実行環境を構成するためビルダーと呼ばれるインスタンスオブジェクトを作成します。

このビルダーを使うと

  • サービスの登録
  • アプリの設定ファイル
  • ログ出力機能の構成

など、たいていの Worker で必要な設定をまとめて行ってくれるそうです。便利です!

あともう一つ。args ですが、これは昔の書き方にすると・・・

public int main(string[] args)
{
}

と記述されていた時の args です。いわゆるコマンドライン引数ですね。 このコマンドラインは設定や構成(例:DB接続情報、RestAPI接続情報など)に使うことが一般的なようです。

つぎです。

builder.Services.AddHostedService<Worker>();

CreateApplicationBuilderコマンドで作成された builder には、依存性注入(DI)用の領域があります。これがDIコンテナーサービスです。この Services プロパティを通じて、アプリケーション全体で利用できるサービス(クラスやインターフェース)を追加・設定できます。

当テンプレートでは Worker クラスをバックグラウンドサービスとして登録しているのが分かります。 ちなみにですが、AddHostedService メソッド以外にも様々なメソッドが用意されており、用途によって使い分けることができます。

メソッド名用途
AddSingleton<TService, TImplementation>() アプリケーション全体で1つだけインスタンスを生成し、使い回します。
AddScoped<TService, TImplementation>() スコープ(通常は1リクエスト)ごとにインスタンスを生成します。
AddTransient<TService, TImplementation>() サービスが要求されるたびに新しいインスタンスを生成します。
AddDbContext<TContext>() Entity Framework Core のDbContextを登録します。
AddLogging() ロギング機能を追加します。
AddHttpClient() HTTP通信用の HttpClient をDIコンテナに登録します。

つぎです。

var host = builder.Build();

builder へ設定した、アプリケーション全体で利用できるサービス(クラスやインターフェース)をもとに、ホストオブジェクトを生成する処理です。Build() メソッドを呼び出すと、サービスに登録した仕組みが初期化され、利用可能になります。

つぎです。

host.Run();

host.Run() を呼び出すことで、アプリケーションが起動します。 起動後は登録済みのサービスは変更できなくなります。

ここまでが Program.cs の説明です。

次から Worker.cs の説明です。同様に1行ずつ確認していきます。

Worker.csの解説

public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;

public Worker(ILogger<Worker> logger)
{
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
}
await Task.Delay(1000, stoppingToken);
}
}
}

では最初の1行めからです。

public class Worker : BackgroundService

BackgroundService を継承しています。 BackgroundService とはどのようなクラスでしょうか

Microsoft Learn BackgroundService クラス

Learn を確認すると、最初に実行されるのは ExecuteAsync( CancellationToken ) のようですが・・・CancellationTokenとはなんだ??(ΦωΦ)

Microsoft Learn CancellationToken 構造体

この解説によると、操作を取り消す通知を配信してくれるそうです。

取り消しが要求されたかどうかは、プロパティ IsCancellationRequested を確認するとよい、と。この機能を使って、

  • 取り消しが要求されるまで、一定時間ごとに処理を繰り返す。例: while (!stoppingToken.IsCancellationRequested)

機能を実現できるというわけですね。BackgroundServiceについては後で詳細に確認します。

つぎです。

    public Worker(ILogger<Worker> logger)
{
_logger = logger;
}

Workerクラスのコンストラクタです。引数として ILogger<Worker> を指定しています。しかし、Program.cs にて ILogger<Worker> は一切指定していません。ILogger<Worker> とは何者なのでしょうか。ソースを確認してみましょう。VSCode上で選択し、F12でソースを確認できます。

interface ILogger<out TCategoryName> の解説

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.Extensions.Logging
{
/// <summary>
/// A generic interface for logging where the category name is derived from the specified
/// <typeparamref name="TCategoryName"/> type name.
/// Generally used to enable activation of a named <see cref="ILogger"/> from dependency injection.
/// </summary>
/// <typeparam name="TCategoryName">The type whose name is used for the logger category name.</typeparam>
public interface ILogger<out TCategoryName> : ILogger
{

}
}

コメントをAIに翻訳してもらいましょう

【AIによる翻訳ここから】

指定された 型名からカテゴリ名が導出される、ロギング用のジェネリックインターフェース。 通常、依存性注入から名前付き を有効化するために使用される。 ロガーのカテゴリ名として使用される型。

【AIによる翻訳ここまで】

名前空間と合わせて考えると、 Microsoft が用意した標準的なロギング用のインターフェースのようです。

続けてみていきましょう。ほかにも不思議な箇所があります。インターフェース ILogger を インターフェース ILogger<out TCategoryName> で再定義していますね・・・(´・ω・`)ナンデヤロ? 目的を確認してみましょう。

  • 依存性注入(DI)で ILogger<Worker> のように型を指定するだけで、そのクラス専用のロガーが自動で注入される
  • クラスごとに自動でカテゴリ名(通常はクラス名)が割り当てられ、ログ出力時に「どのクラスから出たログか」が明確になる
  • ログのフィルタリングや出力先の切り替えなどを、カテゴリ単位で柔軟に制御できる

なるほど・・・カスタマイズ済みのロガーを自動で注入できるようになり、ログの出力元が分かるようになり、さらにログの使い分けもできる、と。かなり柔軟でええ感じにできそうです。これでテックブログ1本かけそう!

横道に逸れそうなので深堀りはしないでおきます。

つぎぃ!

abstract class BackgroundService の解説

protected override async Task ExecuteAsync(CancellationToken stoppingToken)

override しているのは・・・そーいえば BackgroundService を継承していましたね。継承元の BackgroundService は、 Worker Service の基本動作を「共通化」するクラスです。BackgroundService を確認してみましょう。

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Base class for implementing a long running <see cref="IHostedService"/>.
/// </summary>
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task? _executeTask;
private CancellationTokenSource? _stoppingCts;

/// <summary>
/// Gets the Task that executes the background operation.
/// </summary>
/// <remarks>
/// Will return <see langword="null"/> if the background operation hasn't started.
/// </remarks>
public virtual Task? ExecuteTask => _executeTask;

/// <summary>
/// This method is called when the <see cref="IHostedService"/> starts. The implementation should return a task that represents
/// the lifetime of the long running operation(s) being performed.
/// </summary>
/// <param name="stoppingToken">Triggered when <see cref="IHostedService.StopAsync(CancellationToken)"/> is called.</param>
/// <returns>A <see cref="Task"/> that represents the long running operations.</returns>
/// <remarks>See <see href="https://learn.microsoft.com/dotnet/core/extensions/workers">Worker Services in .NET</see> for implementation guidelines.</remarks>
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

/// <summary>
/// Triggered when the application host is ready to start the service.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Start operation.</returns>
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Create linked token to allow cancelling executing task from provided token
_stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

// Store the task we're executing
_executeTask = ExecuteAsync(_stoppingCts.Token);

// If the task is completed then return it, this will bubble cancellation and failure to the caller
if (_executeTask.IsCompleted)
{
return _executeTask;
}

// Otherwise it's running
return Task.CompletedTask;
}

/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Stop operation.</returns>
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executeTask == null)
{
return;
}

try
{
// Signal cancellation to the executing method
_stoppingCts!.Cancel();
}
finally
{
#if NET8_0_OR_GREATER
await _executeTask.WaitAsync(cancellationToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
#else
// Wait until the task completes or the stop token triggers
var tcs = new TaskCompletionSource<object>();
using CancellationTokenRegistration registration = cancellationToken.Register(s => ((TaskCompletionSource<object>)s!).SetCanceled(), tcs);
// Do not await the _executeTask because cancelling it will throw an OperationCanceledException which we are explicitly ignoring
await Task.WhenAny(_executeTask, tcs.Task).ConfigureAwait(false);
#endif
}

}

/// <inheritdoc />
public virtual void Dispose()
{
_stoppingCts?.Cancel();
}
}
}

BackgroundService クラスは、インターフェースである IHostedService と IDispose を実装しています。インターフェースそれぞれの役割は以下の通りです。

インターフェース名役割
IHostedServiceアプリが起動するときと終了するときに呼ばれる処理を定義するためのインターフェース
IDisposeガベージコレクションでは解放できないリソースを解放するための仕組みを提供するインターフェース

まずは IHostedService を少し深堀してみましょう。

interface IHostedService の解説

IHostedService には、2つ のメソッドしかありません。

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Defines methods for objects that are managed by the host.
/// 訳:ホストによって管理されるオブジェクトのためのメソッドを定義する
/// </summary>
public interface IHostedService
{
/// <summary>
/// Triggered when the application host is ready to start the service.
/// 訳:アプリケーションホストがサービスを開始する準備が整ったときに発動される
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted. 訳:開始処理が中止されたことを表す</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Start operation. 約:非同期の開始処理を表す</returns>
Task StartAsync(CancellationToken cancellationToken);

/// <summary>
/// Triggered when the application host is performing a graceful shutdown. 訳:アプリケーションホストが正常にシャットダウン処理を実行しているときに呼ばれる
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful. 訳:シャットダウン処理がこれ以上正常に行われるべきでないことを表す</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Stop operation. 訳:非同期の停止処理を表す</returns>
Task StopAsync(CancellationToken cancellationToken);
}
}

IHostedService にて実装を強要しているのは2つのメソッドです。

Task StartAsync(CancellationToken cancellationToken);

コメントの訳:アプリケーションホストがサービスを開始する準備が整ったときに発動される

  • アプリケーション起動時に呼ばれる
  • サービスの開始処理を書く場所(例: タイマー開始、バックグラウンドスレッドの起動、接続確立など)
  • cancellationToken が渡されるので、起動処理中にキャンセル(例: 起動失敗、強制終了)が可能

Task StopAsync(CancellationToken cancellationToken);

コメントの訳:アプリケーションホストが正常にシャットダウン処理を実行しているときに呼ばれる

  • アプリケーション終了時に呼ばれる
  • サービスの停止処理を書く場所(例: バックグラウンド処理をキャンセル、接続のクローズ、ログ出力)
  • cancellationToken が渡されるので、終了処理が可能(例: シャットダウンが一定時間で強制終了されるときに使う)

併せて考えると、 BackgroundService クラスは、IHostedService インターフェースを通じて上記2つの基礎的かつ具体的な実装を提供している、ということになります。

結果的にみると、BackgroundService クラスを継承することで、バックグラウンドで動作する標準的な機能を簡単に作成できるように設計、効率的に実装できます。

次です。

interface IDisposable の解説

//
// 概要:
// Provides a mechanism for releasing unmanaged resources. 訳:アンマネージリソースを解放する仕組みを提供する
public interface IDisposable
{
//
// 概要:
// Performs application-defined tasks associated with freeing, releasing, or resetting
// unmanaged resources. 訳:アンマネージリソースの解放・破棄・リセットに関連する、アプリケーション定義の処理を実行する
void Dispose();
}

C# には ガベージコレクション(GC) という仕組みがあり、使わなくなったオブジェクトが占有していた メモリ を自動で解放してくれます。 しかし、すべてのリソースが自動で解放されるわけではありません。たとえばファイルハンドルやデータベース接続、COMコンポーネントなどは、開発者自身が明示的に解放処理を記述する必要があります。

そこで登場するのが IDisposable インターフェース です。これを実装することで、リソース解放処理を Dispose メソッド にまとめ、標準的な方法で呼び出せるようになります。 また、using ステートメントを利用すれば、スコープを抜けたタイミングで自動的に Dispose が実行されるため、後片付け漏れを防ぐことができます。

BackgroundService クラスの確認は以上です。Worker.csにもどります。

Hello World をかくところ!

    while (!stoppingToken.IsCancellationRequested)
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);

Console.WriteLine("Hello, World!");

}
await Task.Delay(1000, stoppingToken);
}

ExecuteAsync メソッドの引数、stoppingToken.IsCancellationRequested != 真 の間、処理を続けます。

この while 句の中に定義したい実装を記述します。 " Hello World! " するならここです(笑)

今回は .NET Worker Service で常駐サービスを作るために SDKが作成するテンプレートを勉強しました。継承している抽象クラスやインターフェースのソースを確認し、目的を調べることができました。

これで Worker Service で書けそうです。実際に書いてみて沢山の失敗を経験することにします(笑)

画像生成AI Nano Banana に触れてみた

箕浦
箕浦
ディアシステム(株)開発二部

こんにちは。開発 2 部 箕浦です。
今回は噂の画像生成AI Nano Banana(ナノバナナ)を触ってみましたので、紹介したいと思います。
まずは Nano Banana について少し紹介してから実際に生成した画像を紹介します。

Nano Banana(ナノバナナ)について

Nano Bananaとは、Googleが開発した最新のAI画像生成・編集モデル「Gemini 2.5 Flash Image」の愛称です。
2025年8月にリリースされ、AI画像生成の分野で大きな注目を集めています。

Nano Bananaの特徴

1. キャラクター一貫性の革新

従来のAI画像生成では、同じキャラクターでも角度や服装を変えると別人になってしまうという問題がありました。
しかしNano Bananaは:

  • 同一人物の特徴を維持したまま編集が可能
  • ポーズや向き、服装を変更しても人物の一貫性を保持
  • 複数の画像生成でもキャラクターの統一性を維持

2. 高度な画像編集機能

  • 画像合成:複数の画像を自然に結合
  • 背景変更:元の人物を保ったまま環境を変更
  • 衣装変更:人物の特徴を維持したまま服装を変更
  • ポーズ変更:同じキャラクターで様々なポーズを生成

3. 業界トップの性能

LMArena(AIモデル評価サイト)では:

  • Text-to-Imageで1位を獲得
  • Image Editでスコア1,339を記録(2位を大きく引き離す)
  • 高精度と高速処理を両立

主な活用例

ビジネス活用

  • ノベルティグッズのデザイン提案
  • 商品紹介画像の作成
  • 広告素材の制作
  • プレゼンテーション用画像

クリエイティブ用途

  • キャラクター設定資料の作成
  • 漫画・イラストの参考資料
  • ストーリーボードの制作
  • 動画制作の素材作り

日常利用

  • SNS用アイキャッチ画像
  • プロフィール写真のバリエーション
  • 家族写真の演出
  • 記念写真の作成

利用方法

無料で使える環境

  1. Google Geminihttps://gemini.google.com/)

    • 無料プランで利用可能
    • 1日あたり一定枚数まで生成可能
  2. Google AI Studiohttps://aistudio.google.com/)

    • 開発者向け環境
    • より詳細な設定が可能

ためしてみた

今回は、Google AI Studioから試したいと思います。

画像1

Google AI Studioにアクセスすると上記の画面になりますので、「Try Nano Banana」を押下します。

今回はフリー素材の画像を使っていろいろ遊んでみたいと思います。

まずは以下のビジネス用画像を添付し、プロンプトに

この画像の人全員にビールジョッキを持たせてください

と入力してみます。

画像2

すると

画像3

ちゃんと持たせてくれました!

今度は

背景を居酒屋にしてください

画像4

ちょっと合成写真感はありますが、まあいいでしょう

さらに

画像のすべての人物をパーカーに着替えさせてください

画像5

パーカー感がリアルで感動です!

続けてディアのロゴを入れてみましょう

全員のパーカーにこのロゴをいれてください

画像6

しばらくすると・・・

画像7

ちゃんと指示どうりやってくれました。
商品のPRが画像にも使えそうですね。

次に別のパターンを試してみます。

フリー素材の画像を使って以下を入れてみます。

1枚目の右の人を2枚目の人に変えて

画像8

指示どうり金髪の女性に差し替えてポーズまで合わせてくれています

画像9

今回はほんの一部ですが、皆さんもぜひ試してみてください。

最後に、現在は自己判断での利用となっており、以下の点に注意が必要です:

  • 第三者の著作権を侵害しない
  • 肖像権の尊重
  • 利用規約の確認

ローコード開発って何ぞや?

前田
ディアシステム(株)開発一部第2課

こんにちは。開発一部 第 2 課の前田です。

ローコード開発という言葉、耳にする事があると思います。
そのローコード開発について、ざっくり紹介したいと思います。

常駐しているお客様先での、私が携わっている ETL(*)のシステムもローコードの開発ツールを採用しています。
 *ETL とはデータを 抽出(Extract) 変換(Transform) 格納(Load) する一連のプロセスの事です。

ローコードツールの特徴として

  • コードを書く量を最小限に抑え、GUI 等を使ってアプリを構築する手法
  • テンプレートや部品化された機能を使って、ドラッグ&ドロップ操作で UI やロジックを構築
  • データベースや API 連携が GUI で設定できて、コード記述が最小限で済み、SaaS や API 連携にも対応していて、外部サービスとの統合がスムーズである

(イメージ)

画像1

又、コンポーネント単位でデバッグが出来る事で、途中結果の確認が容易にできます。
プログラムバグが出たとしても、原因調査がしやすく特定するまでの時間が速いです。

 (イメージ)

画像2

ローコード開発のメリットとデメリット

[メリット]

  • 学習コストが少ない
        何らかのプログラム言語を習得する必要がない(但し IT リテラシーは必要)
  • 開発コストが少ない
        コーディング量が少ないため、短期間でリリースができる
        外注せずに、社内で開発ができる
        標準化されているので、後から修正がしやすく、他人が作ったソースの解析もあまり悩まなくで済むのが良いところです

[デメリット]

  • ツールのライセンスや保守料等の費用が発生する
  • ツールの制約によって、独自仕様の実装が難しい場合があります
  • 複雑な分岐やロジックになると、結局ソースが見にくくなったり、
       「あれ、こんな事はできないのね?」みたいに、プログラマ経験があると混乱する場面もたまにあります。
  • IT 部門以外の方が開発すると、ポリシーが徹底されないリスクがあります

最後に

最近では AI による開発支援機能が追加されたりと、ツール自体が進化してます。
開発コストも小さいのでアジャイル開発、小規模プロジェクトには向いていると感じます。
メーカー企業では、このようなローコードで作れるアプリを導入して IT 部門だけでは無く、業務部門の中で開発する流れが進んでいるようです。

Wi-Fiが遅い、繋がらない!その原因と解決策をチェックしよう

福田
ディアシステム(株)開発一部第5課

「あれ、またWi-Fiが遅い…」

そう感じたこと、ありませんか?

私たちの生活に欠かせないWi-Fiは、今や単なるネット接続ツールではなく、仕事や勉強、動画視聴、そしてSNSまで、私たちの毎日に寄り添う重要なライフラインです。

もしWi-Fiの調子が悪くて困っているなら、今回紹介するWi-Fi環境のチェックポイントを試してみてください。

まずはこの2つのポイントをチェックしてみてください。 今回は、日本の主流である光回線に絞って解説します。

  1. ONU(光回線終端装置)をチェック! 光回線をご利用の場合、インターネットの入り口となるのがONUです。 これは、光ファイバーの信号をデジタルデータに変換する役割を担っています。

通信会社からレンタルされていることが多いので、まずはランプが正常に点灯しているかを確認しましょう。 もし赤く点滅していたり、消えていたりする場合は、通信自体に問題がある可能性があります。

  1. Wi-Fiルーターの電波強度をチェック! Wi-Fiの電波は、壁や家具、他の電化製品などによって弱くなってしまいます。

「電波が届きにくいな…」と感じたら、電波の強度を測定してみましょう。

Wi-Fiの電波強度は、通信速度や安定性に直結する重要な要素です。

今回は、パソコンを使ってWi-Fiの電波強度を調べる、方法をご紹介します!

Windowsパソコンで電波強度を測る! 特別なアプリをインストールする必要はありません。 Windowsのコマンドプロンプトを使えば、すぐにWi-Fiの電波強度をチェックできます。

(1). コマンドプロンプトを起動する スタートメニューから「cmd」と入力して、コマンドプロンプトを起動します。

(2). コマンドを入力する コマンドプロンプトの画面で、次のコマンドを入力してEnterキーを押してください。

netsh wlan show interfaces

コマンド実行すると、このような情報を表示します。

システムに 1 インターフェイスがあります:

名前 : Wi-Fi
説明 : Intel(R) Wi-Fi 6E AX211 160MHz
GUID : ********-****-****-****-************
物理アドレス : **:**:**:**:**:**
インターフェイス 入力 : プライマリ
状態 : 接続されました
SSID : ***
AP BSSID : **:**:**:**:**:**
バンド : 2.4 GHz
チャネル : 6
接続された Akm 暗号 : [ akm = **-**-**:**, cipher = **-**-**:** ]
ネットワークの種類 : インフラストラクチャ
無線の種類 : 802.11n
認証 : WPA2-パーソナル
暗号 : CCMP
接続モード : プロファイル
受信速度 (Mbps) : 144.4
送信速度 (Mbps) : 144.4
シグナル : 97%
プロファイル : ***
構成された QoS MSC の : 0
構成された QoS マップ : 0
ポリシーで許可されている QoS マップ : 0

この表示は、Wi-Fiルーターからの距離は、見通し直線で1メートルで実行しました。

Wi-Fiに関する情報が表示されます。注目するのは「シグナル」という項目です。 ここに表示されている%表記の数値が、現在の電波強度を表しています。 100%に近いほど、電波の状態は良好です。 50%あたりになると、通信速度に影響が出始める可能性があります。

今回は、いくつかの場所で実際に計測した結果をもとに、Wi-Fi電波の強度を見ていきましょう。

測定1:ルーターから1mの場所 まず、Wi-Fiルーターから見通しがよい1メートルほどの場所で計測しました。

	シグナル: 97%

ほぼ満点ですね!ルーターの真横や、ごく近い場所では、これくらい高い数値になるはずです。

測定2:ルーターから3mの場所 次に、ルーターから見通しがよい3メートルの場所で試しました。

	シグナル: 99%

なんと、1メートル地点よりも数値が上がりました!これは、電波の反射や周囲の環境によって、電波が強められる現象が起きることがあります。 Wi-Fi電波は、壁や家具に反射しながら届くため、必ずしもルーターから近ければ近いほど良い、というわけではないのが面白いところです。

測定3:ルーターと機器の場所を入れ替えて3mの場所 さらに、同じ3メートルの場所でも、ルーターとパソコンの位置関係を少し変えてみました。

	シグナル: 92%

数値が少し下がりましたね。 このように、電波の強度はわずかな位置の違いでも変動します。 これは、電波が跳ね返ったり、他の電波と干渉したりする影響が考えられます。

測定4:曲がり角の先、約5mの場所 次に、ルーターからL字に曲がった先にある、見通しのきかない約5メートルの場所で計測しました。

	シグナル: 92%

先ほどの3メートルの結果とほとんど変わりません。 これは、Wi-Fiの電波が回り込んだり、壁で反射したりして届いていることを示しています。

測定5:さらに場所を入れ替えて5mの場所 同じL字の場所でも、ルーターとパソコンの位置を入れ替えてみたところ…

	シグナル: 93%

こちらもほとんど変化がありません。 この結果から、この場所の電波強度は、距離や反射、回り込みの影響でこのくらいの値になると推測できます。

測定6:扉を閉めた先、約5mの場所 次は、見通しの良い5メートル地点で、間に扉を閉めた状態で計測しました。

	シグナル: 87%

数値が下がりました。 扉という障害物を通過することで、電波が減衰していることがわかります。

測定7:階段を半分登った場所 さらに、ルーターはそのままで、階段を半分ほど登った場所で計測しました。

	シグナル: 57%

一気に数値が下がりました!床や壁、さらには高さの変化など、複数の要因が絡み合って電波が大幅に弱くなっています。

測定8:2階の部屋 最後に、2階まで登ったところで計測しました。

	シグナル: 43%

かなり数値が下がりました。これくらいの電波強度になると、動画の読み込みが遅くなったり、途切れたりする可能性があります。

今回の計測結果を見て、「ウチも電波が弱い場所があるかも…」と感じた方もいるのではないでしょうか。

計測結果から見ると、「シグナルが50%に近い場所(今回の例では階段の途中)」にWi-Fiの中継器を置くことで、家全体のWi-Fi環境をグッと改善できる可能性が見えてきました。

さらに快適なWi-Fi環境を目指すなら、次の点も試してみてください。

  • 時間帯を変えて再計測しましょう。

Wi-Fiの電波は、近所の電波と干渉することがあります。 夜間や週末など、使う人が増える時間帯に電波強度がどう変わるか見てみるのもおすすめです。

  • Wi-Fiルーターの置き場所を変えてみましょう。

わずかな向きや位置の違いで、電波の届き方は大きく変わります。 壁から少し離したり、家具の配置を変えたりするだけで、意外な改善が見られるかもしれません。

  • 高性能なルーターへの買い替えも検討

どうしても電波が弱い場所があるなら、指向性のある高性能なWi-Fiルーターに替えるのも一つの手です。
特定の方向に電波を強く飛ばせるので、より安定した接続が期待できます。

Wi-Fiの電波は目に見えないので、どこに問題があるか分かりにくいです。
今回ご紹介したような方法で「見える化」することで、解決への糸口が見つかります。

c# 別クラスのPrivateメソッドを呼び出す方法

建部
ディアシステム(株)開発一部第2課

こんにちは。開発一部の建部です。

この記事は、公開されていないクラスのPrivateメソッドを呼び出す例をいくつか例示します。

例では実行ファイルでの実装となっていますが、MS-Testなどのテストフレームにも適用でき、
戻り値取得もできるので Privateなメソッドのユニットテストにも応用できます。

なお、Privateメソッドをユニットテストする意義については、別議論とします。
(VS2022では右クリック→単体テスト作成でも拒否されますし、、、)

やっている事は、

  • ReflectionによるPrivateメソッド名の文字特定 →エディタのメソッド名補完機能でも候補に出てこないメソッドが指定できます。
  • InvokeによるPrivateメソッドの実行および、その引数指定方法

の2点です。

ファイル構成は

ファイル名説明メモ
Program.cs実行ファイルのエントリポイント
TestClass01.cs対象クラスのメソッド呼び出し処理※ここで色々やってます
TargetClass01.cs呼び出されるメソッド群

です。

Program.cs

using System;

namespace PrivateMethodTest
{
/// <summary>
/// 実行ファイルのエントリ
/// </summary>
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, PrivateMethodTest");
//
TestClass01 testc = new TestClass01();
}
}
}

TestClass01.cs

using System.Reflection;

namespace PrivateMethodTest
{
/// <summary>
/// 対象クラスのメソッド呼び出しクラス
/// </summary>
public class TestClass01
{
/// <summary>
/// コンストラクタ
/// </summary>
public TestClass01()
{
Console.WriteLine("Hello, TestClass01");
//
bool result = TestMethod01();
}

/// <summary>
/// 対象クラスのメソッド呼び出し処理
/// </summary>
/// <returns></returns>
public bool TestMethod01()
{
Console.WriteLine("TestClass01-TestMethod01");
TargetClass01 targetc01 = new TargetClass01();

// Publicなメソッドの呼び出し
int? result = targetc01.PublicMethod01();

// Privateなメソッドの呼び出し
MethodInfo? minfo = targetc01.GetType().GetMethod("PrivateMethod01", BindingFlags.Instance | BindingFlags.NonPublic);
if (minfo != null)
{
Console.WriteLine("PrivateMethod01={0}", (int?)minfo.Invoke(targetc01, null));
}

// Privateな引数付きメソッドの呼び出し
minfo = targetc01.GetType().GetMethod("PrivateMethod02", BindingFlags.Instance | BindingFlags.NonPublic);
if (minfo != null)
{
Console.WriteLine("PrivateMethod02={0}", (int?)minfo.Invoke(targetc01, new object[]{ 2, 3 }));
}

// 事前にPublicなクラスメンバに値をセットしてPrivateなメソッドの呼び出し
targetc01.Property01 = 5;
targetc01.Property02 = 3;

minfo = targetc01.GetType().GetMethod("PrivateMethod03", BindingFlags.Instance | BindingFlags.NonPublic);
if (minfo != null)
{
Console.WriteLine("PrivateMethod03={0}", (int?)minfo.Invoke(targetc01, null));
}

return true;
}
}
}

TargetClass01.cs

namespace PrivateMethodTest
{
/// <summary>
/// 呼び出された衣装クラス
/// </summary>
public class TargetClass01
{
public int Property01 = 0;
public int Property02 = 0;

/// <summary>
/// コンストラクタ
/// </summary>
public TargetClass01()
{
Console.WriteLine("Hello, TargetClass01");
}

/// <summary>
/// 呼び出される処理01
/// </summary>
/// <returns></returns>
public int PublicMethod01()
{
Console.WriteLine("TargetClass01-PublicMethod01");
return -1;
}

/// <summary>
/// 呼び出される処理02
/// </summary>
/// <returns></returns>
private int PrivateMethod01()
{
Console.WriteLine("TargetClass01-PrivateMethod01");

return 0;
}

/// <summary>
/// 呼び出される処理03
/// </summary>
/// <returns></returns>
private int PrivateMethod02(int arg01, int arg02)
{
Console.WriteLine("TargetClass01-PrivateMethod02");

return arg01 - arg02;
}

/// <summary>
/// 呼び出される処理04
/// </summary>
/// <returns></returns>
private int PrivateMethod03()
{
Console.WriteLine("TargetClass01-PrivateMethod03");
return Property01 + Property02;
}
}
}

例は.net9.0のVSCodeでの実行を確認しております。

ビジネスマネージャー合格体験記

中野
ディアシステム(株)開発二部第2課

はじめに

会社から管理職向けに推奨されている資格「ビジネスマネージャー検定」に挑戦し、その過程をまとめます。
コロナの影響で、自宅で受験できるIBT(Internet Based Testing)形式が導入されたため、今回はその形で受験しました。

試験の概要

  • 資格の対象者
    主に企業の管理職やマネジメント層を対象とした資格ですが、一般職の方でも受験可能です。

  • 資格概要
    ビジネスマネージャー検定は、組織運営や人材育成、業務管理など、マネジメントに必要な知識を体系的に学ぶことができる資格です。

  • 試験内容
    選択式の問題で構成されており、マネジメントに関する幅広い分野から出題されます。
    試験時間:90分
    出題数:40問
    合格ライン:70点以上

試験の特徴

試験の内容的には難しくはなく、一般的な知識で回答できる問題と、知っていなければ回答できない問題があります。
出題方法としては、他の試験より難しいと感じました。
その理由として、選択問題の形式が「正解の組み合わせを選ぶ」というもので、選択肢が6~12個程度用意されており
運での正答率が下がるため、問いに対する正しい理解がないとほぼ正解できない点です。

試験勉強

基本的には、公式のテキストと過去問集の2冊をベースに勉強しました。 公式テキスト
テキスト全体を読み切って理解するには時間がかかるため
先に過去問を解いて、わからないワード・問題があればテキストやネットを理解するといった方法を取りました。

不正解の問題番号を控えておき、間違えた問題集を2周ほど繰り返すことで覚えていきます。

試験本番対策

  • 40問90分ということで1問2分ちょっとのペースで解いていく必要があるため、少しでも悩むと思った場合一次回答を行いすぐ次の問題へ
  • 「損益計算表」のテーマでは、計算が必要になるため基本的には即一次回答し時間があれば考える
  • IBT形式の場合は、事前にシステムチェックや条件・禁止事項を確認する

IBTについて

  • 良いところ

    • 自宅で受験できるため、移動の手間が省ける
    • 自分のペースで受験できる(時間帯の選択が可能・周りの音などに左右されず集中できる)
  • 悪いところ

    • ネット環境やPCの不具合があると受験に支障が出る
    • トイレによる途中退出・回線の不調による回線切断は不合格となる
    • IBT形式の受験条件を整えるのに苦労する(机上にPC以外何も置かないなど)

最後に

最初は「マネージメントについての資格なんて…」と思っていましたが、
資格勉強を通じて、自分が持っていない考え方や知識を得られて、自分の成長につながりました。
個人的には、管理職はもちろんのこと、一般職の方が勉強するだけでも良い資格試験だと感じました。

また、資格試験・勉強も一度受けてみると、自分の中でハードルがグッと下がり、
他の技術系資格も挑戦してみようと思っています。

SQLを作成する時は、パースを意識しよう

西村
ディアシステム(株)開発一部第4課

こんにちは開発一部第4課の西村です。

システムの運用保守で性能問題が発生した際、SQLを見直すことになることは、よくあります。
性能問題が発生してからチューニングを実施すると、どうしても運用に影響がでてしまうので、設計段階から意識して改善していくことが望ましいです。
SQLのチューニングにはいろいろな方法がありますが、本記事では「パース」に注目して書いていこうと思います。
「パース」に注目することで、パフォーマンスだけではなく、セキュリティ面での強化も期待できます。

はじめに

パースとは、SQL文を解析することです。
解析結果は共有プールにキャッシュされ、解析結果を使用することにより、すぐにSQL文を実行することができます。
これを、ソフトパースと呼びます。
キャッシュされた解析結果が存在しない場合、SQLの検証、実行計画の作成を行った後、SQLを実行します。
これを、ハードパースと呼びます。
パフォーマンスの高いシステム設計をするためには、できるだけハードパースを回避する必要があります。
では、パース時間を減らすための方法を3点紹介します。

SQL構文を統一する。

同じ内容のSQLでも、大文字小文字の違いや空白の個数、改行位置、別名の違いで、別のSQL文と解釈します。
ハードパースを回避するため、SQL構文は統一しましょう。

(大文字と小文字の違い)

画像1

(改行位置の違い)

画像2

バインド変数を使用する。

SQLが解析される際、リテラル値を使用していると、IDの数だけ解析されます。
バインド変数を使うことで、同じ構文のSQL文は再利用され、ハードパースの頻度を下げることができます。 例

① リテラル値使用

② バインド変数使用

画像3

結合する表の数を制限する。

実行計画が作成される際、アクセス順番の検討が行われます。
nテーブルを結合する場合、単純に考えるとn!通りの順序があります。
パース時間を軽減するために、表の結合数を考慮しましょう。
また、テーブル設計で多くの表を結合する必要がないように意識しましょう。

画像4

(結合4表)

おわりに

「パース」を意識したSQL設計は、パフォーマンスの最適化だけではなく、保守性にも繋がります。
繰り返し実行される処理を中心に、ボトルネックを可視化しながら改善をしていきましょう。

未経験から始める
システムエンジニア

一生モノのITスキルを身につけよう

あなたの経験とスキルを
ディアシステムで発揮してください!