2014-02-24 36 views
8

有沒有辦法以編程方式將字體永久添加到Windows 7/8 PC? 我已閱讀關於AddFontResource DLL導入的幾篇文章,但它似乎不工作。如何以編程方式安裝字體(C#)

除此之外,MSDN Documentation表示在重新啓動計算機後字體將被刪除,除非字體被添加到註冊表中。

如何永久安裝字體?我怎樣才能將字體添加到註冊表?它是否始終是相同的名稱/條目?

我必須在運行時動態地添加字體,因爲一旦用戶選擇字體就會得到字體。

備註:我知道如何添加註冊表項。我的問題是關於Windows XP,Vista,7和8與不同字體類型之間的兼容性問題。也許有一種方法可以啓動另一個爲我安裝字體的exe文件。

+1

可能的重複:http://stackoverflow.com/questions/14796162/how-to-install-a-windows-font-using-c-sharp – Marcus

+0

正如我指出的,我讀了幾篇文章,但他們沒有回答我的問題。我希望永久性地安裝字體,並且我還詢問了有關注冊表的一些信息。 –

回答

5

如上所述,您可以啓動其他可執行文件來爲您安裝TrueType字體。我不知道你的具體使用情況,但我會按照我所知道的方法運行,也許一個對你有用。

Windows有一個內置的工具稱爲fontview.exe,您可以通過調用Process.Start("Path\to\file.ttf")任何有效的TrueType字體...假設默認文件關聯簡單地調用。這類似於從Windows資源管理器手動啓動它。這樣做的好處是非常簡單,但它仍然需要每種字體的用戶交互來安裝。據我所知,沒有辦法調用這個過程的「安裝」部分作爲參數,但即使有,你仍然需要提升權限並與UAC對抗。

更有趣的選項是一個名爲FontReg的實用程序,它替代舊版本Windows上包含的棄用fontinst.exe。 FontReg使您可以通過與/複製開關調用可執行編程安裝字體的整個目錄:

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

     }; 

    Process.Start(info); 

注意字體必須是在哪裏FontReg.exe是根位於。您還必須擁有管理員權限。如果你需要你的字體安裝完全透明,我會建議啓動你的應用程序與提升的權限和批准的UAC預先,這樣當你產卵你的子進程你不需要用戶批准Permissions stuff

+0

是的,我已經用提升的權限啓動,所以應該沒有問題。我會告訴你自己寫下的兩種方法。非常感謝! –

+0

好的,我決定用FontReg.exe來做。它看起來是安裝字體的最佳方式。感謝您的支持! –

+1

@ElMac沒問題。我相信該源代碼與其他可分發資源捆綁在一起,因此,如果您非常喜歡,您可以查看並瞭解它是如何完成的。我只剔除了邏輯,但它看起來是在相同的邏輯路徑上:複製然後註冊。 –

2

根據文檔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(); 
+0

ex = {「訪問路徑'C:\ Windows \ Fonts \ fontname.otf'被拒絕。」}。測試在Windows 10 –

+1

編輯,對不起,以爲我是作爲管理員運行。如果管理員看起來沒有問題,但字體實際上沒有安裝 –

+0

你知道嗎? – ivias

0
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); 
} 

... ..

+0

註銷時要考慮到字體 – JxDarkAngel

+0

http:// stackoverflow。com/a/26284643/4126472 – JxDarkAngel

+0

看起來非常危險 - 如果字體文件已經存在但包含不同的字體會怎麼樣? – NetMage

3

過去幾天我一直有同樣的問題我發現每個解決方案都會產生不同的問題。

我設法與我的同事想出了一個工作代碼,我想我會分享給大家。該代碼可以在下面的鏈接引擎收錄中找到:

Installing a font programatically in C#

+0

適合我!謝謝 – MiBol

1

該解決方案是乾淨的,工作無需重新啓動但它確實表明了「安裝字體...」對話框(其中委託消失(!)本身)。

首先,在您的項目中添加對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

'path_to'是什麼意思? –

0

如果您的Visual Studio 2017年,您可以創建一個新的Visual Studio安裝程序 - 安裝項目。您可以編輯安裝程序以刪除對話框,只保留「完成」對話框以向用戶顯示它運行良好。

從目標機上的文件系統(在Visual Studio項目中),添加稱爲字體的特殊目錄。然後將所需的所有字體添加到字體目錄中。如果您查看添加的每種字體的屬性,則會看到Visual Studio已假定您想要註冊每種字體。

編譯該項目,並且您擁有一個帶有可部署的setup.exe的MSI。當然,你需要以管理員身份運行它,但除此之外,這個小程序可以快速高效地運行。我發現這是在Windows上安裝字體最簡單的方法。

+0

我是作爲一個獨立的項目爲現有客戶做到的 - 我們需要一種快速獲取字體的方法。對於新客戶,我將這種技術添加到其安裝程序項目中(我已經爲該應用程序準備了一個VS Setup項目),所以效果很好。兩次。 –