web-dev-qa-db-ja.com

プログラムでフォントをインストールする方法(C#)

プログラムでWindows 7/8 PCにフォントを永続的に追加する方法はありますか? AddFontResource DLL-Importに関するいくつかの投稿を読みましたが、動作しないようです。

その上、 MSDN Documentation は、フォントがレジストリに追加されない限り、コンピュータの再起動後にフォントが削除されることを示しています。

フォントを永続的にインストールするにはどうすればよいですか?フォントをレジストリに追加するにはどうすればよいですか?常に同じ名前/エントリですか?

ユーザーがフォントを選択するとすぐにフォントが表示されるため、実行時にフォントを動的に追加する必要があります。

備考:レジストリエントリを追加する方法を知っています。私の質問は、Windows XP、Vista、7および8と異なるフォントタイプの互換性についてです。多分私のためにフォントをインストールする他のexeを起動する方法があるでしょう。

18
El Mac

先ほど述べたように、他の実行可能ファイルを起動してTrueTypeフォントをインストールすることができます。あなたの具体的な使用例はわかりませんが、私が知っている方法を詳しく説明します。おそらく1つは役立つでしょう。

Windowsにはfontview.exeと呼ばれる組み込みユーティリティがあり、デフォルトのファイルの関連付けを想定して、有効なTrueTypeフォントでProcess.Start("Path\to\file.ttf")を呼び出すだけで呼び出すことができます。 。これは、Windowsエクスプローラから手動で起動するのと同じです。ここでの利点は、それは本当に取るに足らないことですが、それでもインストールするフォントごとにユーザーの操作が必要です。私が知る限り、このプロセスの「インストール」部分を引数として呼び出す方法はありませんが、たとえあったとしても、権限を昇格させてUACと戦わなければなりません。

より興味深いオプションは、古いバージョンのWindowsに含まれていた非推奨のfontinst.exeを置き換えるユーティリティ FontReg です。 FontRegを使用すると、/ copyスイッチを使用して実行可能ファイルを呼び出すことにより、フォントのディレクトリ全体をプログラムでインストールできます。

    var info = new ProcessStartInfo()
        {
            FileName = "Path\to\FontReg.exe",
            Arguments = "/copy",
            UseShellExecute = false,
            WindowStyle = ProcessWindowStyle.Hidden

        };

   Process.Start(info);

フォントは、FontReg.exeが配置されている場所のルートにある必要があることに注意してください。また、管理者権限が必要です。フォントのインストールを完全に透過的にする必要がある場合は、昇格したアクセス許可でアプリケーションを起動し、UACを事前に承認することをお勧めします。これにより、子プロセスを生成するときにユーザーの承認は不要になります Permissions stuff

9
B L

私は過去数日間同じ問題を抱えていて、私が見つけたそれぞれの解決策は異なる問題を引き起こしていました。

私は何とか作業コードを同僚と思いついたので、みんなで共有したいと思った。コードは、次のPastebinリンクにあります。

C#でのプログラムによるフォントのインストール

[〜#〜] edit [〜#〜]今後このコードを取得できなくなった場合は、直接回答にコピーしました。

[DllImport("gdi32", EntryPoint = "AddFontResource")]
public static extern int AddFontResourceA(string lpFileName);
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern int AddFontResource(string lpszFilename);
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern int CreateScalableFontResource(uint fdwHidden, string
    lpszFontRes, string lpszFontFile, string lpszCurrentPath);

/// <summary>
/// Installs font on the user's system and adds it to the registry so it's available on the next session
/// Your font must be included in your project with its build path set to 'Content' and its Copy property
/// set to 'Copy Always'
/// </summary>
/// <param name="contentFontName">Your font to be passed as a resource (i.e. "myfont.tff")</param>
private static void RegisterFont(string contentFontName)
{
    // Creates the full path where your font will be installed
    var fontDestination = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), contentFontName);

    if (!File.Exists(fontDestination))
    {
        // Copies font to destination
        System.IO.File.Copy(Path.Combine(System.IO.Directory.GetCurrentDirectory(), contentFontName), fontDestination);

        // Retrieves font name
        // Makes sure you reference System.Drawing
        PrivateFontCollection fontCol = new PrivateFontCollection();
        fontCol.AddFontFile(fontDestination);
        var actualFontName = fontCol.Families[0].Name;

        //Add font
        AddFontResource(fontDestination);
        //Add registry entry   
        Registry.SetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",actualFontName, contentFontName, RegistryValueKind.String);
    }
}
6
kskyriacou

AddFontResource() のドキュメントによると=

この関数は、現在のセッションにのみフォントをインストールします。システムが再起動すると、フォントは存在しなくなります。システムを再起動した後でもフォントがインストールされるようにするには、フォントがレジストリにリストされている必要があります。

だから私が見つけた最良のオプションは、フォントをWindowsのフォントディレクトリにコピーすることです

File.Copy("MyNewFont.ttf",
    Path.Combine(Environment.GetFolderPath(SpecialFolder.Windows),
        "Fonts", "MyNewFont.ttf"));

そして、それぞれのエントリをレジスターに追加します。

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts");
                    key.SetValue("My Font Description", "fontname.tff");
                    key.Close();
2
Zain Ali
internal static void InstalarFuente(string NombreFnt,string RutaFnt)
{
    string CMD = string.Format("copy /Y \"{0}\" \"%WINDIR%\\Fonts\" ", RutaFnt);
    EjecutarCMD(CMD);

    System.IO.FileInfo FInfo = new System.IO.FileInfo(RutaFnt);
    CMD = string.Format("reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\" /v \"{0}\" /t REG_SZ /d {1} /f", NombreFnt, FInfo.Name);
    EjecutarCMD(CMD);
}

public static void EjecutarCMD(string Comando)
{
    System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo("cmd.exe");
    Info.Arguments = string.Format("/c {0}", Comando);
    Info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    System.Diagnostics.Process.Start(Info);
}

.....

1
JxDarkAngel

このソリューションはクリーンで、動作します再起動なし(!)ですが、[フォントをインストールしています...]ダイアログボックスが表示されます(それ自体が消えます)。

まず、プロジェクトにsystem32\Shell32.dllへの参照を追加します。
次に、次の3行のコードだけを使用してフォントをインストールします。

Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder fontFolder = Shell.NameSpace(0x14);
fontFolder.CopyHere(@"path_to\the_font.ttf");

3行のコード:)

0
Erik Bongers

Visual Studio 2017をお持ちの場合は、新しいVisual Studioインストーラー-セットアッププロジェクトを作成できます。インストーラーを編集してダイアログボックスを削除し、[完了]ダイアログのみを残して、正常に実行されたことをユーザーに示すことができます。

ターゲットマシンのファイルシステム(Visual Studioプロジェクト内)から、Fontsという特別なディレクトリを追加します。次に、必要なすべてのフォントをFontsディレクトリに追加します。追加した各フォントのプロパティを見ると、Visual Studioは各フォントを登録する必要があると既に想定していることがわかります。

プロジェクトをコンパイルすると、デプロイ可能なsetup.exeを含むMSIが得られます。もちろん、管理者として実行する必要がありますが、それ以外に、この小さなプログラムは高速かつ効率的に動作します。これがWindowsにフォントをインストールする最も簡単な方法であることがわかりました。

0
JasonH